diff --git a/boot/bootdata/hivesft.inf b/boot/bootdata/hivesft.inf index 36cb025fb4e..0058d8bb280 100644 --- a/boot/bootdata/hivesft.inf +++ b/boot/bootdata/hivesft.inf @@ -512,7 +512,7 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapper",,0x00000012 HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\HotFix",,0x00000012 HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\IME Compatibility",,0x00000012 -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\IMM","LoadIMM",0x00010003,1 +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\IMM","LoadIMM",0x00010003,0 HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\IMM","LoadCTFIME",0x00010003,0 ; DOS Device ports diff --git a/dll/directx/wine/CMakeLists.txt b/dll/directx/wine/CMakeLists.txt index a6fcff25cc7..05ff58197af 100644 --- a/dll/directx/wine/CMakeLists.txt +++ b/dll/directx/wine/CMakeLists.txt @@ -8,6 +8,10 @@ endif() add_subdirectory(amstream) add_subdirectory(d3d8) add_subdirectory(d3d9) +add_subdirectory(d3d10) +add_subdirectory(d3d10_1) +add_subdirectory(d3d10core) +add_subdirectory(d3d11) add_subdirectory(d3dcompiler_43) add_subdirectory(d3drm) add_subdirectory(d3dx9_24) @@ -41,6 +45,7 @@ add_subdirectory(dplayx) add_subdirectory(dpnhpast) add_subdirectory(dsound) add_subdirectory(dxdiagn) +add_subdirectory(dxgi) add_subdirectory(msdmo) add_subdirectory(qcap) add_subdirectory(qedit) diff --git a/dll/directx/wine/d3d10/CMakeLists.txt b/dll/directx/wine/d3d10/CMakeLists.txt new file mode 100644 index 00000000000..0431e25336c --- /dev/null +++ b/dll/directx/wine/d3d10/CMakeLists.txt @@ -0,0 +1,34 @@ + +add_definitions( + -D__WINESRC__ + -DUSE_WIN32_OPENGL) + +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/psdk) + +spec2def(d3d10.dll d3d10.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + d3d10_main.c + effect.c + shader.c + stateblock.c + utils.c + d3d10_private.h) + +add_library(d3d10 SHARED + ${SOURCE} + version.rc + ${CMAKE_CURRENT_BINARY_DIR}/d3d10_stubs.c + ${CMAKE_CURRENT_BINARY_DIR}/d3d10.def) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(d3d10 PRIVATE -Wno-incompatible-pointer-types -Wno-unused-but-set-variable -Wno-switch -Wno-error) # Our favourite compiler :) +endif() + +set_module_type(d3d10 win32dll) +target_link_libraries(d3d10 wine dxguid uuid) +add_importlibs(d3d10 d3d11 d3dwine msvcrt d3dcompiler_43 d3d10core dxgi kernel32 ntdll) +add_pch(d3d10 d3d10_private.h SOURCE) +add_dependencies(d3d10 wineheaders d3d_idl_headers) +add_cd_file(TARGET d3d10 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3d10/Makefile.in b/dll/directx/wine/d3d10/Makefile.in new file mode 100644 index 00000000000..0e4cd6ac161 --- /dev/null +++ b/dll/directx/wine/d3d10/Makefile.in @@ -0,0 +1,12 @@ +MODULE = d3d10.dll +IMPORTLIB = d3d10 +IMPORTS = dxguid uuid d3d10core d3dcompiler dxgi + +C_SRCS = \ + d3d10_main.c \ + effect.c \ + shader.c \ + stateblock.c \ + utils.c + +RC_SRCS = version.rc diff --git a/dll/directx/wine/d3d10/d3d10.spec b/dll/directx/wine/d3d10/d3d10.spec new file mode 100644 index 00000000000..62dd94d18b4 --- /dev/null +++ b/dll/directx/wine/d3d10/d3d10.spec @@ -0,0 +1,30 @@ +# 1 stub RevertToOldImplementation +@ stdcall D3D10CompileEffectFromMemory(ptr long ptr ptr ptr long long ptr ptr) +@ stdcall D3D10CompileShader(ptr long str ptr ptr str str long ptr ptr) +@ stdcall D3D10CreateBlob(long ptr) d3dcompiler_43.D3DCreateBlob +@ stdcall D3D10CreateDevice(ptr long ptr long long ptr) +@ stdcall D3D10CreateDeviceAndSwapChain(ptr long ptr long long ptr ptr ptr) +@ stdcall D3D10CreateEffectFromMemory(ptr long long ptr ptr ptr) +@ stdcall D3D10CreateEffectPoolFromMemory(ptr long long ptr ptr) +@ stdcall D3D10CreateStateBlock(ptr ptr ptr) +@ stub D3D10DisassembleEffect +@ stdcall D3D10DisassembleShader(ptr long long ptr ptr) +@ stdcall D3D10GetGeometryShaderProfile(ptr) +@ stdcall D3D10GetInputAndOutputSignatureBlob(ptr long ptr) d3dcompiler_43.D3DGetInputAndOutputSignatureBlob +@ stdcall D3D10GetInputSignatureBlob(ptr long ptr) d3dcompiler_43.D3DGetInputSignatureBlob +@ stdcall D3D10GetOutputSignatureBlob(ptr long ptr) d3dcompiler_43.D3DGetOutputSignatureBlob +@ stdcall D3D10GetPixelShaderProfile(ptr) +@ stdcall D3D10GetShaderDebugInfo(ptr long ptr) d3dcompiler_43.D3DGetDebugInfo +@ stub D3D10GetVersion +@ stdcall D3D10GetVertexShaderProfile(ptr) +@ stub D3D10PreprocessShader +@ stdcall D3D10ReflectShader(ptr long ptr) +@ stub D3D10RegisterLayers +@ stdcall D3D10StateBlockMaskDifference(ptr ptr ptr) +@ stdcall D3D10StateBlockMaskDisableAll(ptr) +@ stdcall D3D10StateBlockMaskDisableCapture(ptr long long long) +@ stdcall D3D10StateBlockMaskEnableAll(ptr) +@ stdcall D3D10StateBlockMaskEnableCapture(ptr long long long) +@ stdcall D3D10StateBlockMaskGetSetting(ptr long long) +@ stdcall D3D10StateBlockMaskIntersect(ptr ptr ptr) +@ stdcall D3D10StateBlockMaskUnion(ptr ptr ptr) diff --git a/dll/directx/wine/d3d10/d3d10_main.c b/dll/directx/wine/d3d10/d3d10_main.c new file mode 100644 index 00000000000..e3d1c57e448 --- /dev/null +++ b/dll/directx/wine/d3d10/d3d10_main.c @@ -0,0 +1,321 @@ +/* + * Direct3D 10 + * + * Copyright 2007 Andras Kovacs + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d10_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10); + +static HRESULT d3d10_create_device(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, UINT sdk_version, ID3D10Device **device) +{ + IDXGIFactory *factory; + HRESULT hr; + + TRACE("adapter %p, driver_type %s, swrast %p, flags %#x, sdk_version %#x, device %p.\n", + adapter, debug_d3d10_driver_type(driver_type), swrast, flags, sdk_version, device); + + if (sdk_version != D3D10_SDK_VERSION) + { + WARN("Invalid SDK version %#x.\n", sdk_version); + return E_INVALIDARG; + } + + if (adapter) + { + IDXGIAdapter_AddRef(adapter); + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); + if (FAILED(hr)) + { + WARN("Failed to get dxgi factory, returning %#x.\n", hr); + return hr; + } + } + else + { + hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory); + if (FAILED(hr)) + { + WARN("Failed to create dxgi factory, returning %#x.\n", hr); + return hr; + } + + switch (driver_type) + { + case D3D10_DRIVER_TYPE_WARP: + FIXME("WARP driver not implemented, falling back to hardware.\n"); + case D3D10_DRIVER_TYPE_HARDWARE: + { + hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter); + if (FAILED(hr)) + { + WARN("No adapters found, returning %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + case D3D10_DRIVER_TYPE_NULL: + FIXME("NULL device not implemented, falling back to refrast.\n"); + /* fall through, for now */ + case D3D10_DRIVER_TYPE_REFERENCE: + { + HMODULE refrast = LoadLibraryA("d3d10ref.dll"); + if (!refrast) + { + WARN("Failed to load refrast, returning E_FAIL.\n"); + IDXGIFactory_Release(factory); + return E_FAIL; + } + hr = IDXGIFactory_CreateSoftwareAdapter(factory, refrast, &adapter); + FreeLibrary(refrast); + if (FAILED(hr)) + { + WARN("Failed to create a software adapter, returning %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + case D3D10_DRIVER_TYPE_SOFTWARE: + { + if (!swrast) + { + WARN("Software device requested, but NULL swrast passed, returning E_FAIL.\n"); + IDXGIFactory_Release(factory); + return E_FAIL; + } + hr = IDXGIFactory_CreateSoftwareAdapter(factory, swrast, &adapter); + if (FAILED(hr)) + { + WARN("Failed to create a software adapter, returning %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + default: + FIXME("Unhandled driver type %#x.\n", driver_type); + IDXGIFactory_Release(factory); + return E_FAIL; + } + } + + hr = D3D10CoreCreateDevice(factory, adapter, flags, D3D_FEATURE_LEVEL_10_0, device); + IDXGIAdapter_Release(adapter); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create a device, returning %#x.\n", hr); + return hr; + } + + TRACE("Created ID3D10Device %p.\n", *device); + + return hr; +} + +HRESULT WINAPI D3D10CreateDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, UINT sdk_version, ID3D10Device **device) +{ + return d3d10_create_device(adapter, driver_type, swrast, flags, sdk_version, device); +} + +HRESULT WINAPI D3D10CreateDeviceAndSwapChain(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, UINT sdk_version, DXGI_SWAP_CHAIN_DESC *swapchain_desc, + IDXGISwapChain **swapchain, ID3D10Device **device) +{ + IDXGIDevice *dxgi_device; + IDXGIFactory *factory; + HRESULT hr; + + TRACE("adapter %p, driver_type %s, swrast %p, flags %#x, sdk_version %d, " + "swapchain_desc %p, swapchain %p, device %p\n", + adapter, debug_d3d10_driver_type(driver_type), swrast, flags, sdk_version, + swapchain_desc, swapchain, device); + + /* Avoid forwarding to D3D10CreateDevice(), since it breaks applications + * hooking these entry-points. */ + if (FAILED(hr = d3d10_create_device(adapter, driver_type, swrast, flags, sdk_version, device))) + { + WARN("Failed to create a device, returning %#x\n", hr); + *device = NULL; + return hr; + } + + TRACE("Created ID3D10Device %p\n", *device); + + hr = ID3D10Device_QueryInterface(*device, &IID_IDXGIDevice, (void **)&dxgi_device); + if (FAILED(hr)) + { + ERR("Failed to get a dxgi device from the d3d10 device, returning %#x\n", hr); + ID3D10Device_Release(*device); + *device = NULL; + return hr; + } + + hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter); + IDXGIDevice_Release(dxgi_device); + if (FAILED(hr)) + { + ERR("Failed to get the device adapter, returning %#x\n", hr); + ID3D10Device_Release(*device); + *device = NULL; + return hr; + } + + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); + IDXGIAdapter_Release(adapter); + if (FAILED(hr)) + { + ERR("Failed to get the adapter factory, returning %#x\n", hr); + ID3D10Device_Release(*device); + *device = NULL; + return hr; + } + + hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)*device, swapchain_desc, swapchain); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + ID3D10Device_Release(*device); + *device = NULL; + + WARN("Failed to create a swapchain, returning %#x\n", hr); + return hr; + } + + TRACE("Created IDXGISwapChain %p\n", *swapchain); + + return S_OK; +} + +static int d3d10_effect_type_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct d3d10_effect_type *t = WINE_RB_ENTRY_VALUE(entry, const struct d3d10_effect_type, entry); + const DWORD *id = key; + + return *id - t->id; +} + +HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT flags, + ID3D10Device *device, ID3D10EffectPool *effect_pool, ID3D10Effect **effect) +{ + struct d3d10_effect *object; + HRESULT hr; + + FIXME("data %p, data_size %lu, flags %#x, device %p, effect_pool %p, effect %p stub!\n", + data, data_size, flags, device, effect_pool, effect); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate D3D10 effect object memory\n"); + return E_OUTOFMEMORY; + } + + wine_rb_init(&object->types, d3d10_effect_type_compare); + object->ID3D10Effect_iface.lpVtbl = &d3d10_effect_vtbl; + object->refcount = 1; + ID3D10Device_AddRef(device); + object->device = device; + + hr = d3d10_effect_parse(object, data, data_size); + if (FAILED(hr)) + { + ERR("Failed to parse effect\n"); + IUnknown_Release(&object->ID3D10Effect_iface); + return hr; + } + + *effect = &object->ID3D10Effect_iface; + + TRACE("Created ID3D10Effect %p\n", object); + + return S_OK; +} + +HRESULT WINAPI D3D10CompileEffectFromMemory(void *data, SIZE_T data_size, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, UINT hlsl_flags, UINT fx_flags, + ID3D10Blob **effect, ID3D10Blob **errors) +{ + TRACE("data %p, data_size %lu, filename %s, defines %p, include %p, " + "hlsl_flags %#x, fx_flags %#x, effect %p, errors %p.\n", + data, data_size, wine_dbgstr_a(filename), defines, include, + hlsl_flags, fx_flags, effect, errors); + + return D3DCompile(data, data_size, filename, defines, include, + NULL, "fx_4_0", hlsl_flags, fx_flags, effect, errors); +} + +HRESULT WINAPI D3D10CreateEffectPoolFromMemory(void *data, SIZE_T data_size, UINT fx_flags, + ID3D10Device *device, ID3D10EffectPool **effect_pool) +{ + FIXME("data %p, data_size %lu, fx_flags %#x, device %p, effect_pool %p stub.\n", + data, data_size, fx_flags, device, effect_pool); + + return E_NOTIMPL; +} + +const char * WINAPI D3D10GetVertexShaderProfile(ID3D10Device *device) +{ + FIXME("device %p stub!\n", device); + + return "vs_4_0"; +} + +const char * WINAPI D3D10GetGeometryShaderProfile(ID3D10Device *device) +{ + FIXME("device %p stub!\n", device); + + return "gs_4_0"; +} + +const char * WINAPI D3D10GetPixelShaderProfile(ID3D10Device *device) +{ + FIXME("device %p stub!\n", device); + + return "ps_4_0"; +} + +HRESULT WINAPI D3D10ReflectShader(const void *data, SIZE_T data_size, ID3D10ShaderReflection **reflector) +{ + struct d3d10_shader_reflection *object; + + FIXME("data %p, data_size %lu, reflector %p stub!\n", data, data_size, reflector); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate D3D10 shader reflection object memory\n"); + return E_OUTOFMEMORY; + } + + object->ID3D10ShaderReflection_iface.lpVtbl = &d3d10_shader_reflection_vtbl; + object->refcount = 1; + + *reflector = &object->ID3D10ShaderReflection_iface; + + TRACE("Created ID3D10ShaderReflection %p\n", object); + + return S_OK; +} diff --git a/dll/directx/wine/d3d10/d3d10_private.h b/dll/directx/wine/d3d10/d3d10_private.h new file mode 100644 index 00000000000..e785b8b8698 --- /dev/null +++ b/dll/directx/wine/d3d10/d3d10_private.h @@ -0,0 +1,302 @@ +/* + * Copyright 2008-2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_D3D10_PRIVATE_H +#define __WINE_D3D10_PRIVATE_H + +#include "wine/debug.h" +#include "wine/rbtree.h" +#include "wine/heap.h" + +#define COBJMACROS +#include "winbase.h" +#include "winuser.h" +#include "objbase.h" + +#include "d3d10.h" +#include "d3dcompiler.h" + +/* + * This doesn't belong here, but for some functions it is possible to return that value, + * see http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx + * The original definition is in D3DX10core.h. + */ +#define D3DERR_INVALIDCALL 0x8876086c + +/* TRACE helper functions */ +const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type) DECLSPEC_HIDDEN; +const char *debug_d3d10_shader_variable_class(D3D10_SHADER_VARIABLE_CLASS c) DECLSPEC_HIDDEN; +const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t) DECLSPEC_HIDDEN; +const char *debug_d3d10_device_state_types(D3D10_DEVICE_STATE_TYPES t) DECLSPEC_HIDDEN; + +enum d3d10_effect_object_type +{ + D3D10_EOT_RASTERIZER_STATE = 0x0, + D3D10_EOT_DEPTH_STENCIL_STATE = 0x1, + D3D10_EOT_BLEND_STATE = 0x2, + D3D10_EOT_VERTEXSHADER = 0x6, + D3D10_EOT_PIXELSHADER = 0x7, + D3D10_EOT_GEOMETRYSHADER = 0x8, + D3D10_EOT_STENCIL_REF = 0x9, + D3D10_EOT_BLEND_FACTOR = 0xa, + D3D10_EOT_SAMPLE_MASK = 0xb, +}; + +enum d3d10_effect_object_operation +{ + D3D10_EOO_VALUE = 1, + D3D10_EOO_PARSED_OBJECT = 2, + D3D10_EOO_PARSED_OBJECT_INDEX = 3, + D3D10_EOO_ANONYMOUS_SHADER = 7, +}; + +struct d3d10_effect_object +{ + struct d3d10_effect_pass *pass; + enum d3d10_effect_object_type type; + union + { + ID3D10RasterizerState *rs; + ID3D10DepthStencilState *ds; + ID3D10BlendState *bs; + ID3D10VertexShader *vs; + ID3D10PixelShader *ps; + ID3D10GeometryShader *gs; + } object; +}; + +struct d3d10_effect_shader_signature +{ + char *signature; + UINT signature_size; + UINT element_count; + D3D10_SIGNATURE_PARAMETER_DESC *elements; +}; + +struct d3d10_effect_shader_variable +{ + struct d3d10_effect_shader_signature input_signature; + struct d3d10_effect_shader_signature output_signature; + union + { + ID3D10VertexShader *vs; + ID3D10PixelShader *ps; + ID3D10GeometryShader *gs; + } shader; +}; + +struct d3d10_effect_state_object_variable +{ + union + { + D3D10_RASTERIZER_DESC rasterizer; + D3D10_DEPTH_STENCIL_DESC depth_stencil; + D3D10_BLEND_DESC blend; + D3D10_SAMPLER_DESC sampler; + } desc; + union + { + ID3D10RasterizerState *rasterizer; + ID3D10DepthStencilState *depth_stencil; + ID3D10BlendState *blend; + ID3D10SamplerState *sampler; + } object; +}; + +/* ID3D10EffectType */ +struct d3d10_effect_type +{ + ID3D10EffectType ID3D10EffectType_iface; + + char *name; + D3D10_SHADER_VARIABLE_TYPE basetype; + D3D10_SHADER_VARIABLE_CLASS type_class; + + DWORD id; + struct wine_rb_entry entry; + struct d3d10_effect *effect; + + DWORD element_count; + DWORD size_unpacked; + DWORD stride; + DWORD size_packed; + DWORD member_count; + DWORD column_count; + DWORD row_count; + struct d3d10_effect_type *elementtype; + struct d3d10_effect_type_member *members; +}; + +struct d3d10_effect_type_member +{ + char *name; + char *semantic; + DWORD buffer_offset; + struct d3d10_effect_type *type; +}; + +/* ID3D10EffectVariable */ +struct d3d10_effect_variable +{ + ID3D10EffectVariable ID3D10EffectVariable_iface; + + struct d3d10_effect_variable *buffer; + struct d3d10_effect_type *type; + + char *name; + char *semantic; + DWORD buffer_offset; + DWORD annotation_count; + DWORD flag; + DWORD data_size; + struct d3d10_effect *effect; + struct d3d10_effect_variable *elements; + struct d3d10_effect_variable *members; + struct d3d10_effect_variable *annotations; + + union + { + struct d3d10_effect_state_object_variable state; + struct d3d10_effect_shader_variable shader; + } u; +}; + +/* ID3D10EffectPass */ +struct d3d10_effect_pass +{ + ID3D10EffectPass ID3D10EffectPass_iface; + + struct d3d10_effect_technique *technique; + char *name; + DWORD start; + DWORD object_count; + DWORD annotation_count; + struct d3d10_effect_object *objects; + struct d3d10_effect_variable *annotations; + + D3D10_PASS_SHADER_DESC vs; + D3D10_PASS_SHADER_DESC ps; + D3D10_PASS_SHADER_DESC gs; + UINT stencil_ref; + UINT sample_mask; + float blend_factor[4]; +}; + +/* ID3D10EffectTechnique */ +struct d3d10_effect_technique +{ + ID3D10EffectTechnique ID3D10EffectTechnique_iface; + + struct d3d10_effect *effect; + char *name; + DWORD pass_count; + DWORD annotation_count; + struct d3d10_effect_pass *passes; + struct d3d10_effect_variable *annotations; +}; + +struct d3d10_effect_anonymous_shader +{ + struct d3d10_effect_variable shader; + struct d3d10_effect_type type; +}; + +/* ID3D10Effect */ +extern const struct ID3D10EffectVtbl d3d10_effect_vtbl DECLSPEC_HIDDEN; +struct d3d10_effect +{ + ID3D10Effect ID3D10Effect_iface; + LONG refcount; + + ID3D10Device *device; + DWORD version; + DWORD local_buffer_count; + DWORD variable_count; + DWORD local_variable_count; + DWORD sharedbuffers_count; + DWORD sharedobjects_count; + DWORD technique_count; + DWORD index_offset; + DWORD texture_count; + DWORD depthstencilstate_count; + DWORD blendstate_count; + DWORD rasterizerstate_count; + DWORD samplerstate_count; + DWORD rendertargetview_count; + DWORD depthstencilview_count; + DWORD used_shader_count; + DWORD anonymous_shader_count; + + DWORD used_shader_current; + DWORD anonymous_shader_current; + + struct wine_rb_tree types; + struct d3d10_effect_variable *local_buffers; + struct d3d10_effect_variable *local_variables; + struct d3d10_effect_anonymous_shader *anonymous_shaders; + struct d3d10_effect_variable **used_shaders; + struct d3d10_effect_technique *techniques; +}; + +/* ID3D10ShaderReflection */ +extern const struct ID3D10ShaderReflectionVtbl d3d10_shader_reflection_vtbl DECLSPEC_HIDDEN; +struct d3d10_shader_reflection +{ + ID3D10ShaderReflection ID3D10ShaderReflection_iface; + LONG refcount; +}; + +HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T data_size) DECLSPEC_HIDDEN; + +/* D3D10Core */ +HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, + unsigned int flags, D3D_FEATURE_LEVEL feature_level, ID3D10Device **device); + +#define MAKE_TAG(ch0, ch1, ch2, ch3) \ + ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ + ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) +#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') +#define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N') +#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') + +HRESULT parse_dxbc(const char *data, SIZE_T data_size, + HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) DECLSPEC_HIDDEN; + +static inline void read_dword(const char **ptr, DWORD *d) +{ + memcpy(d, *ptr, sizeof(*d)); + *ptr += sizeof(*d); +} + +static inline void write_dword(char **ptr, DWORD d) +{ + memcpy(*ptr, &d, sizeof(d)); + *ptr += sizeof(d); +} + +static inline BOOL require_space(size_t offset, size_t count, size_t size, size_t data_size) +{ + return !count || (data_size - offset) / count >= size; +} + +void skip_dword_unknown(const char *location, const char **ptr, unsigned int count) DECLSPEC_HIDDEN; +void write_dword_unknown(char **ptr, DWORD d) DECLSPEC_HIDDEN; + +#endif /* __WINE_D3D10_PRIVATE_H */ diff --git a/dll/directx/wine/d3d10/effect.c b/dll/directx/wine/d3d10/effect.c new file mode 100644 index 00000000000..72c8d09efa7 --- /dev/null +++ b/dll/directx/wine/d3d10/effect.c @@ -0,0 +1,7203 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2009 Rico Schüller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d10_private.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10); + +#define D3D10_FX10_TYPE_COLUMN_SHIFT 11 +#define D3D10_FX10_TYPE_COLUMN_MASK (0x7 << D3D10_FX10_TYPE_COLUMN_SHIFT) + +#define D3D10_FX10_TYPE_ROW_SHIFT 8 +#define D3D10_FX10_TYPE_ROW_MASK (0x7 << D3D10_FX10_TYPE_ROW_SHIFT) + +#define D3D10_FX10_TYPE_BASETYPE_SHIFT 3 +#define D3D10_FX10_TYPE_BASETYPE_MASK (0x1f << D3D10_FX10_TYPE_BASETYPE_SHIFT) + +#define D3D10_FX10_TYPE_CLASS_SHIFT 0 +#define D3D10_FX10_TYPE_CLASS_MASK (0x7 << D3D10_FX10_TYPE_CLASS_SHIFT) + +#define D3D10_FX10_TYPE_MATRIX_COLUMN_MAJOR_MASK 0x4000 + +static const struct ID3D10EffectTechniqueVtbl d3d10_effect_technique_vtbl; +static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl; +static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl; +static const struct ID3D10EffectConstantBufferVtbl d3d10_effect_constant_buffer_vtbl; +static const struct ID3D10EffectScalarVariableVtbl d3d10_effect_scalar_variable_vtbl; +static const struct ID3D10EffectVectorVariableVtbl d3d10_effect_vector_variable_vtbl; +static const struct ID3D10EffectMatrixVariableVtbl d3d10_effect_matrix_variable_vtbl; +static const struct ID3D10EffectStringVariableVtbl d3d10_effect_string_variable_vtbl; +static const struct ID3D10EffectShaderResourceVariableVtbl d3d10_effect_shader_resource_variable_vtbl; +static const struct ID3D10EffectRenderTargetViewVariableVtbl d3d10_effect_render_target_view_variable_vtbl; +static const struct ID3D10EffectDepthStencilViewVariableVtbl d3d10_effect_depth_stencil_view_variable_vtbl; +static const struct ID3D10EffectShaderVariableVtbl d3d10_effect_shader_variable_vtbl; +static const struct ID3D10EffectBlendVariableVtbl d3d10_effect_blend_variable_vtbl; +static const struct ID3D10EffectDepthStencilVariableVtbl d3d10_effect_depth_stencil_variable_vtbl; +static const struct ID3D10EffectRasterizerVariableVtbl d3d10_effect_rasterizer_variable_vtbl; +static const struct ID3D10EffectSamplerVariableVtbl d3d10_effect_sampler_variable_vtbl; +static const struct ID3D10EffectTypeVtbl d3d10_effect_type_vtbl; + +/* null objects - needed for invalid calls */ +static struct d3d10_effect_technique null_technique = {{&d3d10_effect_technique_vtbl}}; +static struct d3d10_effect_pass null_pass = {{&d3d10_effect_pass_vtbl}}; +static struct d3d10_effect_type null_type = {{&d3d10_effect_type_vtbl}}; +static struct d3d10_effect_variable null_local_buffer = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_constant_buffer_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_variable = {{&d3d10_effect_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_scalar_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_scalar_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_vector_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_vector_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_matrix_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_matrix_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_string_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_string_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_shader_resource_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_resource_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_render_target_view_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_render_target_view_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_depth_stencil_view_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_depth_stencil_view_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_shader_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_blend_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_blend_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_depth_stencil_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_depth_stencil_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_rasterizer_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_rasterizer_variable_vtbl}, + &null_local_buffer, &null_type}; +static struct d3d10_effect_variable null_sampler_variable = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_sampler_variable_vtbl}, + &null_local_buffer, &null_type}; + +/* anonymous_shader_type and anonymous_shader */ +static char anonymous_name[] = "$Anonymous"; +static char anonymous_vertexshader_name[] = "vertexshader"; +static char anonymous_pixelshader_name[] = "pixelshader"; +static char anonymous_geometryshader_name[] = "geometryshader"; +static struct d3d10_effect_type anonymous_vs_type = {{&d3d10_effect_type_vtbl}, + anonymous_vertexshader_name, D3D10_SVT_VERTEXSHADER, D3D10_SVC_OBJECT}; +static struct d3d10_effect_type anonymous_ps_type = {{&d3d10_effect_type_vtbl}, + anonymous_pixelshader_name, D3D10_SVT_PIXELSHADER, D3D10_SVC_OBJECT}; +static struct d3d10_effect_type anonymous_gs_type = {{&d3d10_effect_type_vtbl}, + anonymous_geometryshader_name, D3D10_SVT_GEOMETRYSHADER, D3D10_SVC_OBJECT}; +static struct d3d10_effect_variable anonymous_vs = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_variable_vtbl}, + &null_local_buffer, &anonymous_vs_type, anonymous_name}; +static struct d3d10_effect_variable anonymous_ps = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_variable_vtbl}, + &null_local_buffer, &anonymous_ps_type, anonymous_name}; +static struct d3d10_effect_variable anonymous_gs = {{(const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_variable_vtbl}, + &null_local_buffer, &anonymous_gs_type, anonymous_name}; + +static struct d3d10_effect_type *get_fx10_type(struct d3d10_effect *effect, + const char *data, size_t data_size, DWORD offset); + +static inline struct d3d10_effect_variable *impl_from_ID3D10EffectVariable(ID3D10EffectVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + +struct d3d10_effect_state_property_info +{ + UINT id; + const char *name; + D3D_SHADER_VARIABLE_TYPE type; + UINT size; + UINT count; + D3D_SHADER_VARIABLE_TYPE container_type; + LONG offset; +}; + +static const struct d3d10_effect_state_property_info property_info[] = +{ + {0x0c, "RasterizerState.FillMode", D3D10_SVT_INT, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, FillMode) }, + {0x0d, "RasterizerState.CullMode", D3D10_SVT_INT, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, CullMode) }, + {0x0e, "RasterizerState.FrontCounterClockwise", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, FrontCounterClockwise) }, + {0x0f, "RasterizerState.DepthBias", D3D10_SVT_INT, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, DepthBias) }, + {0x10, "RasterizerState.DepthBiasClamp", D3D10_SVT_FLOAT, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, DepthBiasClamp) }, + {0x11, "RasterizerState.SlopeScaledDepthBias", D3D10_SVT_FLOAT, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, SlopeScaledDepthBias) }, + {0x12, "RasterizerState.DepthClipEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, DepthClipEnable) }, + {0x13, "RasterizerState.ScissorEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, ScissorEnable) }, + {0x14, "RasterizerState.MultisampleEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, MultisampleEnable) }, + {0x15, "RasterizerState.AntialiasedLineEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_RASTERIZER, FIELD_OFFSET(D3D10_RASTERIZER_DESC, AntialiasedLineEnable) }, + {0x16, "DepthStencilState.DepthEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, DepthEnable) }, + {0x17, "DepthStencilState.DepthWriteMask", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, DepthWriteMask) }, + {0x18, "DepthStencilState.DepthFunc", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, DepthFunc) }, + {0x19, "DepthStencilState.StencilEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, StencilEnable) }, + {0x1a, "DepthStencilState.StencilReadMask", D3D10_SVT_UINT8, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, StencilReadMask) }, + {0x1b, "DepthStencilState.StencilWriteMask", D3D10_SVT_UINT8, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, StencilWriteMask) }, + {0x1c, "DepthStencilState.FrontFaceStencilFail", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, FrontFace.StencilFailOp) }, + {0x1d, "DepthStencilState.FrontFaceStencilDepthFail", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, FrontFace.StencilDepthFailOp)}, + {0x1e, "DepthStencilState.FrontFaceStencilPass", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, FrontFace.StencilPassOp) }, + {0x1f, "DepthStencilState.FrontFaceStencilFunc", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, FrontFace.StencilFunc) }, + {0x20, "DepthStencilState.BackFaceStencilFail", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, BackFace.StencilFailOp) }, + {0x21, "DepthStencilState.BackFaceStencilDepthFail", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, BackFace.StencilDepthFailOp) }, + {0x22, "DepthStencilState.BackFaceStencilPass", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, BackFace.StencilPassOp) }, + {0x23, "DepthStencilState.BackFaceStencilFunc", D3D10_SVT_INT, 1, 1, D3D10_SVT_DEPTHSTENCIL, FIELD_OFFSET(D3D10_DEPTH_STENCIL_DESC, BackFace.StencilFunc) }, + {0x24, "BlendState.AlphaToCoverageEnable", D3D10_SVT_BOOL, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, AlphaToCoverageEnable) }, + {0x25, "BlendState.BlendEnable", D3D10_SVT_BOOL, 1, 8, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, BlendEnable) }, + {0x26, "BlendState.SrcBlend", D3D10_SVT_INT, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, SrcBlend) }, + {0x27, "BlendState.DestBlend", D3D10_SVT_INT, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, DestBlend) }, + {0x28, "BlendState.BlendOp", D3D10_SVT_INT, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, BlendOp) }, + {0x29, "BlendState.SrcBlendAlpha", D3D10_SVT_INT, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, SrcBlendAlpha) }, + {0x2a, "BlendState.DestBlendAlpha", D3D10_SVT_INT, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, DestBlendAlpha) }, + {0x2b, "BlendState.BlendOpAlpha", D3D10_SVT_INT, 1, 1, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, BlendOpAlpha) }, + {0x2c, "BlendState.RenderTargetWriteMask", D3D10_SVT_UINT8, 1, 8, D3D10_SVT_BLEND, FIELD_OFFSET(D3D10_BLEND_DESC, RenderTargetWriteMask) }, + {0x2d, "SamplerState.Filter", D3D10_SVT_INT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, Filter) }, + {0x2e, "SamplerState.AddressU", D3D10_SVT_INT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, AddressU) }, + {0x2f, "SamplerState.AddressV", D3D10_SVT_INT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, AddressV) }, + {0x30, "SamplerState.AddressW", D3D10_SVT_INT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, AddressW) }, + {0x31, "SamplerState.MipMapLODBias", D3D10_SVT_FLOAT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, MipLODBias) }, + {0x32, "SamplerState.MaxAnisotropy", D3D10_SVT_UINT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, MaxAnisotropy) }, + {0x33, "SamplerState.ComparisonFunc", D3D10_SVT_INT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, ComparisonFunc) }, + {0x34, "SamplerState.BorderColor", D3D10_SVT_FLOAT, 4, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, BorderColor) }, + {0x35, "SamplerState.MinLOD", D3D10_SVT_FLOAT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, MinLOD) }, + {0x36, "SamplerState.MaxLOD", D3D10_SVT_FLOAT, 1, 1, D3D10_SVT_SAMPLER, FIELD_OFFSET(D3D10_SAMPLER_DESC, MaxLOD) }, +}; + +static const D3D10_RASTERIZER_DESC default_rasterizer_desc = +{ + D3D10_FILL_SOLID, + D3D10_CULL_BACK, + FALSE, + 0, + 0.0f, + 0.0f, + TRUE, + FALSE, + FALSE, + FALSE, +}; + +static const D3D10_DEPTH_STENCIL_DESC default_depth_stencil_desc = +{ + TRUE, + D3D10_DEPTH_WRITE_MASK_ALL, + D3D10_COMPARISON_LESS, + FALSE, + D3D10_DEFAULT_STENCIL_READ_MASK, + D3D10_DEFAULT_STENCIL_WRITE_MASK, + {D3D10_STENCIL_OP_KEEP, D3D10_STENCIL_OP_KEEP, D3D10_STENCIL_OP_KEEP, D3D10_COMPARISON_ALWAYS}, + {D3D10_STENCIL_OP_KEEP, D3D10_STENCIL_OP_KEEP, D3D10_STENCIL_OP_KEEP, D3D10_COMPARISON_ALWAYS}, +}; + +static const D3D10_BLEND_DESC default_blend_desc = +{ + FALSE, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + D3D10_BLEND_SRC_ALPHA, + D3D10_BLEND_INV_SRC_ALPHA, + D3D10_BLEND_OP_ADD, + D3D10_BLEND_SRC_ALPHA, + D3D10_BLEND_INV_SRC_ALPHA, + D3D10_BLEND_OP_ADD, + {0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf}, +}; + +static const D3D10_SAMPLER_DESC default_sampler_desc = +{ + D3D10_FILTER_MIN_MAG_MIP_POINT, + D3D10_TEXTURE_ADDRESS_WRAP, + D3D10_TEXTURE_ADDRESS_WRAP, + D3D10_TEXTURE_ADDRESS_WRAP, + 0.0f, + 16, + D3D10_COMPARISON_NEVER, + {0.0f, 0.0f, 0.0f, 0.0f}, + 0.0f, + FLT_MAX, +}; + +struct d3d10_effect_state_storage_info +{ + D3D_SHADER_VARIABLE_TYPE id; + SIZE_T size; + const void *default_state; +}; + +static const struct d3d10_effect_state_storage_info d3d10_effect_state_storage_info[] = +{ + {D3D10_SVT_RASTERIZER, sizeof(default_rasterizer_desc), &default_rasterizer_desc }, + {D3D10_SVT_DEPTHSTENCIL, sizeof(default_depth_stencil_desc), &default_depth_stencil_desc}, + {D3D10_SVT_BLEND, sizeof(default_blend_desc), &default_blend_desc }, + {D3D10_SVT_SAMPLER, sizeof(default_sampler_desc), &default_sampler_desc }, +}; + +static BOOL fx10_get_string(const char *data, size_t data_size, DWORD offset, const char **s, size_t *l) +{ + size_t len, max_len; + + if (offset >= data_size) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return FALSE; + } + + max_len = data_size - offset; +#ifdef __REACTOS__ + if (!(len = strlen(data + offset))) +#else + if (!(len = strnlen(data + offset, max_len))) +#endif + { + *s = NULL; + *l = 0; + return TRUE; + } + + if (len == max_len) + return FALSE; + + *s = data + offset; + *l = ++len; + + return TRUE; +} + +static BOOL fx10_copy_string(const char *data, size_t data_size, DWORD offset, char **s) +{ + const char *p; + size_t len; + + if (!fx10_get_string(data, data_size, offset, &p, &len)) + return FALSE; + + if (!p) + { + *s = NULL; + return TRUE; + } + + if (!(*s = heap_alloc(len))) + { + ERR("Failed to allocate string memory.\n"); + return FALSE; + } + + memcpy(*s, p, len); + + return TRUE; +} + +static BOOL copy_name(const char *ptr, char **name) +{ + size_t name_len; + + if (!ptr) return TRUE; + + name_len = strlen(ptr) + 1; + if (name_len == 1) + { + return TRUE; + } + + if (!(*name = heap_alloc(name_len))) + { + ERR("Failed to allocate name memory.\n"); + return FALSE; + } + + memcpy(*name, ptr, name_len); + + return TRUE; +} + +static const char *shader_get_string(const char *data, size_t data_size, DWORD offset) +{ + const char *s; + size_t l; + + if (!fx10_get_string(data, data_size, offset, &s, &l)) + return NULL; + + return l ? s : ""; +} + +static HRESULT shader_parse_signature(const char *data, DWORD data_size, struct d3d10_effect_shader_signature *s) +{ + D3D10_SIGNATURE_PARAMETER_DESC *e; + const char *ptr = data; + unsigned int i; + DWORD count; + + if (!require_space(0, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid data size %#x.\n", data_size); + return E_INVALIDARG; + } + + read_dword(&ptr, &count); + TRACE("%u elements\n", count); + + skip_dword_unknown("shader signature", &ptr, 1); + + if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size)) + { + WARN("Invalid count %#x (data size %#x).\n", count, data_size); + return E_INVALIDARG; + } + + if (!(e = heap_calloc(count, sizeof(*e)))) + { + ERR("Failed to allocate signature memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < count; ++i) + { + UINT name_offset; + UINT mask; + + read_dword(&ptr, &name_offset); + if (!(e[i].SemanticName = shader_get_string(data, data_size, name_offset))) + { + WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size); + heap_free(e); + return E_INVALIDARG; + } + read_dword(&ptr, &e[i].SemanticIndex); +#ifdef __REACTOS__ + read_dword(&ptr, (DWORD *)&e[i].SystemValueType); + read_dword(&ptr, (DWORD *)&e[i].ComponentType); +#else + read_dword(&ptr, &e[i].SystemValueType); + read_dword(&ptr, &e[i].ComponentType); +#endif + read_dword(&ptr, &e[i].Register); + read_dword(&ptr, &mask); + + e[i].ReadWriteMask = mask >> 8; + e[i].Mask = mask & 0xff; + + TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, " + "type %u, register idx: %u, use_mask %#x, input_mask %#x\n", + debugstr_a(e[i].SemanticName), e[i].SemanticIndex, e[i].SystemValueType, + e[i].ComponentType, e[i].Register, e[i].Mask, e[i].ReadWriteMask); + } + + s->elements = e; + s->element_count = count; + + return S_OK; +} + +static void shader_free_signature(struct d3d10_effect_shader_signature *s) +{ + heap_free(s->signature); + heap_free(s->elements); +} + +static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +{ + struct d3d10_effect_shader_variable *s = ctx; + HRESULT hr; + + TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4)); + + TRACE("chunk size: %#x\n", data_size); + + switch(tag) + { + case TAG_ISGN: + case TAG_OSGN: + { + /* 32 (DXBC header) + 1 * 4 (chunk index) + 2 * 4 (chunk header) + data_size (chunk data) */ + UINT size = 44 + data_size; + struct d3d10_effect_shader_signature *sig; + char *ptr; + + if (tag == TAG_ISGN) sig = &s->input_signature; + else sig = &s->output_signature; + + if (!(sig->signature = heap_alloc_zero(size))) + { + ERR("Failed to allocate input signature data\n"); + return E_OUTOFMEMORY; + } + sig->signature_size = size; + + ptr = sig->signature; + + write_dword(&ptr, TAG_DXBC); + + /* signature(?) */ + write_dword_unknown(&ptr, 0); + write_dword_unknown(&ptr, 0); + write_dword_unknown(&ptr, 0); + write_dword_unknown(&ptr, 0); + + /* seems to be always 1 */ + write_dword_unknown(&ptr, 1); + + /* DXBC size */ + write_dword(&ptr, size); + + /* chunk count */ + write_dword(&ptr, 1); + + /* chunk index */ + write_dword(&ptr, (ptr - sig->signature) + 4); + + /* chunk */ + write_dword(&ptr, tag); + write_dword(&ptr, data_size); + memcpy(ptr, data, data_size); + + hr = shader_parse_signature(ptr, data_size, sig); + if (FAILED(hr)) + { + ERR("Failed to parse shader, hr %#x\n", hr); + shader_free_signature(sig); + } + + break; + } + + default: + FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag, 4)); + break; + } + + return S_OK; +} + +static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offset, struct d3d10_effect_variable *v) +{ + ID3D10Device *device = v->effect->device; + DWORD dxbc_size; + const char *ptr; + HRESULT hr; + + if (v->effect->used_shader_current >= v->effect->used_shader_count) + { + WARN("Invalid shader? Used shader current(%u) >= used shader count(%u)\n", v->effect->used_shader_current, v->effect->used_shader_count); + return E_FAIL; + } + + v->effect->used_shaders[v->effect->used_shader_current] = v; + ++v->effect->used_shader_current; + + if (offset >= data_size || !require_space(offset, 1, sizeof(dxbc_size), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + + ptr = data + offset; + read_dword(&ptr, &dxbc_size); + TRACE("dxbc size: %#x\n", dxbc_size); + + if (!require_space(ptr - data, 1, dxbc_size, data_size)) + { + WARN("Invalid dxbc size %#x (data size %#lx, offset %#x).\n", offset, (long)data_size, offset); + return E_FAIL; + } + + /* We got a shader VertexShader vs = NULL, so it is fine to skip this. */ + if (!dxbc_size) return S_OK; + + switch (v->type->basetype) + { + case D3D10_SVT_VERTEXSHADER: + hr = ID3D10Device_CreateVertexShader(device, ptr, dxbc_size, &v->u.shader.shader.vs); + if (FAILED(hr)) return hr; + break; + + case D3D10_SVT_PIXELSHADER: + hr = ID3D10Device_CreatePixelShader(device, ptr, dxbc_size, &v->u.shader.shader.ps); + if (FAILED(hr)) return hr; + break; + + case D3D10_SVT_GEOMETRYSHADER: + hr = ID3D10Device_CreateGeometryShader(device, ptr, dxbc_size, &v->u.shader.shader.gs); + if (FAILED(hr)) return hr; + break; + + default: + ERR("This should not happen!\n"); + return E_FAIL; + } + + return parse_dxbc(ptr, dxbc_size, shader_chunk_handler, &v->u.shader); +} + +static D3D10_SHADER_VARIABLE_CLASS d3d10_variable_class(DWORD c, BOOL is_column_major) +{ + switch (c) + { + case 1: return D3D10_SVC_SCALAR; + case 2: return D3D10_SVC_VECTOR; + case 3: if (is_column_major) return D3D10_SVC_MATRIX_COLUMNS; + else return D3D10_SVC_MATRIX_ROWS; + default: + FIXME("Unknown variable class %#x.\n", c); + return 0; + } +} + +static D3D10_SHADER_VARIABLE_TYPE d3d10_variable_type(DWORD t, BOOL is_object) +{ + if(is_object) + { + switch (t) + { + case 1: return D3D10_SVT_STRING; + case 2: return D3D10_SVT_BLEND; + case 3: return D3D10_SVT_DEPTHSTENCIL; + case 4: return D3D10_SVT_RASTERIZER; + case 5: return D3D10_SVT_PIXELSHADER; + case 6: return D3D10_SVT_VERTEXSHADER; + case 7: return D3D10_SVT_GEOMETRYSHADER; + + case 10: return D3D10_SVT_TEXTURE1D; + case 11: return D3D10_SVT_TEXTURE1DARRAY; + case 12: return D3D10_SVT_TEXTURE2D; + case 13: return D3D10_SVT_TEXTURE2DARRAY; + case 14: return D3D10_SVT_TEXTURE2DMS; + case 15: return D3D10_SVT_TEXTURE2DMSARRAY; + case 16: return D3D10_SVT_TEXTURE3D; + case 17: return D3D10_SVT_TEXTURECUBE; + + case 19: return D3D10_SVT_RENDERTARGETVIEW; + case 20: return D3D10_SVT_DEPTHSTENCILVIEW; + case 21: return D3D10_SVT_SAMPLER; + case 22: return D3D10_SVT_BUFFER; + default: + FIXME("Unknown variable type %#x.\n", t); + return D3D10_SVT_VOID; + } + } + else + { + switch (t) + { + case 1: return D3D10_SVT_FLOAT; + case 2: return D3D10_SVT_INT; + case 3: return D3D10_SVT_UINT; + case 4: return D3D10_SVT_BOOL; + default: + FIXME("Unknown variable type %#x.\n", t); + return D3D10_SVT_VOID; + } + } +} + +static HRESULT parse_fx10_type(const char *data, size_t data_size, DWORD offset, struct d3d10_effect_type *t) +{ + const char *ptr; + DWORD unknown0; + DWORD typeinfo; + unsigned int i; + + if (offset >= data_size || !require_space(offset, 6, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + + ptr = data + offset; + read_dword(&ptr, &offset); + TRACE("Type name at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &t->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Type name: %s.\n", debugstr_a(t->name)); + + read_dword(&ptr, &unknown0); + TRACE("Unknown 0: %u.\n", unknown0); + + read_dword(&ptr, &t->element_count); + TRACE("Element count: %u.\n", t->element_count); + + read_dword(&ptr, &t->size_unpacked); + TRACE("Unpacked size: %#x.\n", t->size_unpacked); + + read_dword(&ptr, &t->stride); + TRACE("Stride: %#x.\n", t->stride); + + read_dword(&ptr, &t->size_packed); + TRACE("Packed size %#x.\n", t->size_packed); + + switch (unknown0) + { + case 1: + if (!require_space(ptr - data, 1, sizeof(typeinfo), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + + read_dword(&ptr, &typeinfo); + t->member_count = 0; + t->column_count = (typeinfo & D3D10_FX10_TYPE_COLUMN_MASK) >> D3D10_FX10_TYPE_COLUMN_SHIFT; + t->row_count = (typeinfo & D3D10_FX10_TYPE_ROW_MASK) >> D3D10_FX10_TYPE_ROW_SHIFT; + t->basetype = d3d10_variable_type((typeinfo & D3D10_FX10_TYPE_BASETYPE_MASK) >> D3D10_FX10_TYPE_BASETYPE_SHIFT, FALSE); + t->type_class = d3d10_variable_class((typeinfo & D3D10_FX10_TYPE_CLASS_MASK) >> D3D10_FX10_TYPE_CLASS_SHIFT, typeinfo & D3D10_FX10_TYPE_MATRIX_COLUMN_MAJOR_MASK); + + TRACE("Type description: %#x.\n", typeinfo); + TRACE("\tcolumns: %u.\n", t->column_count); + TRACE("\trows: %u.\n", t->row_count); + TRACE("\tbasetype: %s.\n", debug_d3d10_shader_variable_type(t->basetype)); + TRACE("\tclass: %s.\n", debug_d3d10_shader_variable_class(t->type_class)); + TRACE("\tunknown bits: %#x.\n", typeinfo & ~(D3D10_FX10_TYPE_COLUMN_MASK | D3D10_FX10_TYPE_ROW_MASK + | D3D10_FX10_TYPE_BASETYPE_MASK | D3D10_FX10_TYPE_CLASS_MASK | D3D10_FX10_TYPE_MATRIX_COLUMN_MAJOR_MASK)); + break; + + case 2: + TRACE("Type is an object.\n"); + + if (!require_space(ptr - data, 1, sizeof(typeinfo), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + + read_dword(&ptr, &typeinfo); + t->member_count = 0; + t->column_count = 0; + t->row_count = 0; + t->basetype = d3d10_variable_type(typeinfo, TRUE); + t->type_class = D3D10_SVC_OBJECT; + + TRACE("Type description: %#x.\n", typeinfo); + TRACE("\tbasetype: %s.\n", debug_d3d10_shader_variable_type(t->basetype)); + TRACE("\tclass: %s.\n", debug_d3d10_shader_variable_class(t->type_class)); + break; + + case 3: + TRACE("Type is a structure.\n"); + + if (!require_space(ptr - data, 1, sizeof(t->member_count), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + + read_dword(&ptr, &t->member_count); + TRACE("Member count: %u.\n", t->member_count); + + t->column_count = 0; + t->row_count = 0; + t->basetype = 0; + t->type_class = D3D10_SVC_STRUCT; + + if (!(t->members = heap_calloc(t->member_count, sizeof(*t->members)))) + { + ERR("Failed to allocate members memory.\n"); + return E_OUTOFMEMORY; + } + + if (!require_space(ptr - data, t->member_count, 4 * sizeof(DWORD), data_size)) + { + WARN("Invalid member count %#x (data size %#lx, offset %#x).\n", + t->member_count, (long)data_size, offset); + return E_FAIL; + } + + for (i = 0; i < t->member_count; ++i) + { + struct d3d10_effect_type_member *typem = &t->members[i]; + + read_dword(&ptr, &offset); + TRACE("Member name at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &typem->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Member name: %s.\n", debugstr_a(typem->name)); + + read_dword(&ptr, &offset); + TRACE("Member semantic at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &typem->semantic)) + { + ERR("Failed to copy semantic.\n"); + return E_OUTOFMEMORY; + } + TRACE("Member semantic: %s.\n", debugstr_a(typem->semantic)); + + read_dword(&ptr, &typem->buffer_offset); + TRACE("Member offset in struct: %#x.\n", typem->buffer_offset); + + read_dword(&ptr, &offset); + TRACE("Member type info at offset %#x.\n", offset); + + if (!(typem->type = get_fx10_type(t->effect, data, data_size, offset))) + { + ERR("Failed to get variable type.\n"); + return E_FAIL; + } + } + break; + + default: + FIXME("Unhandled case %#x.\n", unknown0); + return E_FAIL; + } + + if (t->element_count) + { + TRACE("Elementtype for type at offset: %#x\n", t->id); + + /* allocate elementtype - we need only one, because all elements have the same type */ + if (!(t->elementtype = heap_alloc_zero(sizeof(*t->elementtype)))) + { + ERR("Failed to allocate members memory.\n"); + return E_OUTOFMEMORY; + } + + /* create a copy of the original type with some minor changes */ + t->elementtype->ID3D10EffectType_iface.lpVtbl = &d3d10_effect_type_vtbl; + t->elementtype->effect = t->effect; + + if (!copy_name(t->name, &t->elementtype->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("\tType name: %s.\n", debugstr_a(t->elementtype->name)); + + t->elementtype->element_count = 0; + TRACE("\tElement count: %u.\n", t->elementtype->element_count); + + /* + * Not sure if this calculation is 100% correct, but a test + * shows that these values work. + */ + t->elementtype->size_unpacked = t->size_packed / t->element_count; + TRACE("\tUnpacked size: %#x.\n", t->elementtype->size_unpacked); + + t->elementtype->stride = t->stride; + TRACE("\tStride: %#x.\n", t->elementtype->stride); + + t->elementtype->size_packed = t->size_packed / t->element_count; + TRACE("\tPacked size: %#x.\n", t->elementtype->size_packed); + + t->elementtype->member_count = t->member_count; + TRACE("\tMember count: %u.\n", t->elementtype->member_count); + + t->elementtype->column_count = t->column_count; + TRACE("\tColumns: %u.\n", t->elementtype->column_count); + + t->elementtype->row_count = t->row_count; + TRACE("\tRows: %u.\n", t->elementtype->row_count); + + t->elementtype->basetype = t->basetype; + TRACE("\tBasetype: %s.\n", debug_d3d10_shader_variable_type(t->elementtype->basetype)); + + t->elementtype->type_class = t->type_class; + TRACE("\tClass: %s.\n", debug_d3d10_shader_variable_class(t->elementtype->type_class)); + + t->elementtype->members = t->members; + } + + return S_OK; +} + +static struct d3d10_effect_type *get_fx10_type(struct d3d10_effect *effect, + const char *data, size_t data_size, DWORD offset) +{ + struct d3d10_effect_type *type; + struct wine_rb_entry *entry; + HRESULT hr; + + entry = wine_rb_get(&effect->types, &offset); + if (entry) + { + TRACE("Returning existing type.\n"); + return WINE_RB_ENTRY_VALUE(entry, struct d3d10_effect_type, entry); + } + + if (!(type = heap_alloc_zero(sizeof(*type)))) + { + ERR("Failed to allocate type memory.\n"); + return NULL; + } + + type->ID3D10EffectType_iface.lpVtbl = &d3d10_effect_type_vtbl; + type->id = offset; + type->effect = effect; + if (FAILED(hr = parse_fx10_type(data, data_size, offset, type))) + { + ERR("Failed to parse type info, hr %#x.\n", hr); + heap_free(type); + return NULL; + } + + if (wine_rb_put(&effect->types, &offset, &type->entry) == -1) + { + ERR("Failed to insert type entry.\n"); + heap_free(type); + return NULL; + } + + return type; +} + +static void set_variable_vtbl(struct d3d10_effect_variable *v) +{ + const ID3D10EffectVariableVtbl **vtbl = &v->ID3D10EffectVariable_iface.lpVtbl; + + switch (v->type->type_class) + { + case D3D10_SVC_SCALAR: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_scalar_variable_vtbl; + break; + + case D3D10_SVC_VECTOR: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_vector_variable_vtbl; + break; + + case D3D10_SVC_MATRIX_ROWS: + case D3D10_SVC_MATRIX_COLUMNS: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_matrix_variable_vtbl; + break; + + case D3D10_SVC_STRUCT: + *vtbl = &d3d10_effect_variable_vtbl; + break; + + case D3D10_SVC_OBJECT: + switch(v->type->basetype) + { + case D3D10_SVT_STRING: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_string_variable_vtbl; + break; + + case D3D10_SVT_TEXTURE1D: + case D3D10_SVT_TEXTURE1DARRAY: + case D3D10_SVT_TEXTURE2D: + case D3D10_SVT_TEXTURE2DARRAY: + case D3D10_SVT_TEXTURE2DMS: + case D3D10_SVT_TEXTURE2DMSARRAY: + case D3D10_SVT_TEXTURE3D: + case D3D10_SVT_TEXTURECUBE: + case D3D10_SVT_BUFFER: /* Either resource or constant buffer. */ + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_resource_variable_vtbl; + break; + + case D3D10_SVT_RENDERTARGETVIEW: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_render_target_view_variable_vtbl; + break; + + case D3D10_SVT_DEPTHSTENCILVIEW: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_depth_stencil_view_variable_vtbl; + break; + + case D3D10_SVT_DEPTHSTENCIL: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_depth_stencil_variable_vtbl; + break; + + case D3D10_SVT_VERTEXSHADER: + case D3D10_SVT_GEOMETRYSHADER: + case D3D10_SVT_PIXELSHADER: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_variable_vtbl; + break; + + case D3D10_SVT_BLEND: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_blend_variable_vtbl; + break; + + case D3D10_SVT_RASTERIZER: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_rasterizer_variable_vtbl; + break; + + case D3D10_SVT_SAMPLER: + *vtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_sampler_variable_vtbl; + break; + + default: + FIXME("Unhandled basetype %s.\n", debug_d3d10_shader_variable_type(v->type->basetype)); + *vtbl = &d3d10_effect_variable_vtbl; + break; + } + break; + + default: + FIXME("Unhandled type class %s.\n", debug_d3d10_shader_variable_class(v->type->type_class)); + *vtbl = &d3d10_effect_variable_vtbl; + break; + } +} + +static HRESULT copy_variableinfo_from_type(struct d3d10_effect_variable *v) +{ + unsigned int i; + HRESULT hr; + + if (v->type->member_count) + { + if (!(v->members = heap_calloc(v->type->member_count, sizeof(*v->members)))) + { + ERR("Failed to allocate members memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < v->type->member_count; ++i) + { + struct d3d10_effect_variable *var = &v->members[i]; + struct d3d10_effect_type_member *typem = &v->type->members[i]; + + var->buffer = v->buffer; + var->effect = v->effect; + var->type = typem->type; + set_variable_vtbl(var); + + if (!copy_name(typem->name, &var->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable name: %s.\n", debugstr_a(var->name)); + + if (!copy_name(typem->semantic, &var->semantic)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable semantic: %s.\n", debugstr_a(var->semantic)); + + var->buffer_offset = v->buffer_offset + typem->buffer_offset; + TRACE("Variable buffer offset: %u.\n", var->buffer_offset); + + hr = copy_variableinfo_from_type(var); + if (FAILED(hr)) return hr; + } + } + + if (v->type->element_count) + { + unsigned int bufferoffset = v->buffer_offset; + + if (!(v->elements = heap_calloc(v->type->element_count, sizeof(*v->elements)))) + { + ERR("Failed to allocate elements memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < v->type->element_count; ++i) + { + struct d3d10_effect_variable *var = &v->elements[i]; + + var->buffer = v->buffer; + var->effect = v->effect; + var->type = v->type->elementtype; + set_variable_vtbl(var); + + if (!copy_name(v->name, &var->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable name: %s.\n", debugstr_a(var->name)); + + if (!copy_name(v->semantic, &var->semantic)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable semantic: %s.\n", debugstr_a(var->semantic)); + + if (i != 0) + { + bufferoffset += v->type->stride; + } + var->buffer_offset = bufferoffset; + TRACE("Variable buffer offset: %u.\n", var->buffer_offset); + + hr = copy_variableinfo_from_type(var); + if (FAILED(hr)) return hr; + } + } + + return S_OK; +} + +static HRESULT parse_fx10_variable_head(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_variable *v) +{ + DWORD offset; + + read_dword(ptr, &offset); + TRACE("Variable name at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &v->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable name: %s.\n", debugstr_a(v->name)); + + read_dword(ptr, &offset); + TRACE("Variable type info at offset %#x.\n", offset); + + if (!(v->type = get_fx10_type(v->effect, data, data_size, offset))) + { + ERR("Failed to get variable type.\n"); + return E_FAIL; + } + set_variable_vtbl(v); + + return copy_variableinfo_from_type(v); +} + +static HRESULT parse_fx10_annotation(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_variable *a) +{ + HRESULT hr; + + if (FAILED(hr = parse_fx10_variable_head(data, data_size, ptr, a))) + return hr; + + skip_dword_unknown("annotation", ptr, 1); + + /* mark the variable as annotation */ + a->flag = D3D10_EFFECT_VARIABLE_ANNOTATION; + + return S_OK; +} + +static HRESULT parse_fx10_anonymous_shader(struct d3d10_effect *e, struct d3d10_effect_anonymous_shader *s, + enum d3d10_effect_object_type otype) +{ + struct d3d10_effect_variable *v = &s->shader; + struct d3d10_effect_type *t = &s->type; + const char *shader = NULL; + + switch (otype) + { + case D3D10_EOT_VERTEXSHADER: + shader = "vertexshader"; + t->basetype = D3D10_SVT_VERTEXSHADER; + break; + + case D3D10_EOT_PIXELSHADER: + shader = "pixelshader"; + t->basetype = D3D10_SVT_PIXELSHADER; + break; + + case D3D10_EOT_GEOMETRYSHADER: + shader = "geometryshader"; + t->basetype = D3D10_SVT_GEOMETRYSHADER; + break; + + default: + FIXME("Unhandled object type %#x.\n", otype); + return E_FAIL; + } + + if (!copy_name(shader, &t->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Type name: %s.\n", debugstr_a(t->name)); + + t->type_class = D3D10_SVC_OBJECT; + + t->ID3D10EffectType_iface.lpVtbl = &d3d10_effect_type_vtbl; + + v->type = t; + v->effect = e; + set_variable_vtbl(v); + + if (!copy_name("$Anonymous", &v->name)) + { + ERR("Failed to copy semantic.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable name: %s.\n", debugstr_a(v->name)); + + if (!copy_name(NULL, &v->semantic)) + { + ERR("Failed to copy semantic.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable semantic: %s.\n", debugstr_a(v->semantic)); + + return S_OK; +} + +static const struct d3d10_effect_state_property_info *get_property_info(UINT id) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(property_info); ++i) + { + if (property_info[i].id == id) + return &property_info[i]; + } + + return NULL; +} + +static const struct d3d10_effect_state_storage_info *get_storage_info(D3D_SHADER_VARIABLE_TYPE id) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(d3d10_effect_state_storage_info); ++i) + { + if (d3d10_effect_state_storage_info[i].id == id) + return &d3d10_effect_state_storage_info[i]; + } + + return NULL; +} + +static BOOL read_float_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, float *out_data, UINT idx) +{ + switch (in_type) + { + case D3D10_SVT_FLOAT: + out_data[idx] = *(float *)&value; + return TRUE; + + case D3D10_SVT_INT: + out_data[idx] = (INT)value; + return TRUE; + + default: + FIXME("Unhandled in_type %#x.\n", in_type); + return FALSE; + } +} + +static BOOL read_int32_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT *out_data, UINT idx) +{ + switch (in_type) + { + case D3D10_SVT_FLOAT: + out_data[idx] = *(float *)&value; + return TRUE; + + case D3D10_SVT_INT: + case D3D10_SVT_UINT: + case D3D10_SVT_BOOL: + out_data[idx] = value; + return TRUE; + + default: + FIXME("Unhandled in_type %#x.\n", in_type); + return FALSE; + } +} + +static BOOL read_int8_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT8 *out_data, UINT idx) +{ + switch (in_type) + { + case D3D10_SVT_INT: + case D3D10_SVT_UINT: + out_data[idx] = value; + return TRUE; + + default: + FIXME("Unhandled in_type %#x.\n", in_type); + return FALSE; + } +} + +static BOOL read_value_list(const char *data, size_t data_size, DWORD offset, + D3D_SHADER_VARIABLE_TYPE out_type, UINT out_base, UINT out_size, void *out_data) +{ + D3D_SHADER_VARIABLE_TYPE in_type; + const char *ptr; + DWORD t, value; + DWORD count, i; + + if (offset >= data_size || !require_space(offset, 1, sizeof(count), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return FALSE; + } + + ptr = data + offset; + read_dword(&ptr, &count); + if (count != out_size) + return FALSE; + + if (!require_space(ptr - data, count, 2 * sizeof(DWORD), data_size)) + { + WARN("Invalid value count %#x (offset %#x, data size %#lx).\n", count, offset, (long)data_size); + return FALSE; + } + + TRACE("%u values:\n", count); + for (i = 0; i < count; ++i) + { + UINT out_idx = out_base * out_size + i; + + read_dword(&ptr, &t); + read_dword(&ptr, &value); + + in_type = d3d10_variable_type(t, FALSE); + TRACE("\t%s: %#x.\n", debug_d3d10_shader_variable_type(in_type), value); + + switch (out_type) + { + case D3D10_SVT_FLOAT: + if (!read_float_value(value, in_type, out_data, out_idx)) + return FALSE; + break; + + case D3D10_SVT_INT: + case D3D10_SVT_UINT: + case D3D10_SVT_BOOL: + if (!read_int32_value(value, in_type, out_data, out_idx)) + return FALSE; + break; + + case D3D10_SVT_UINT8: + if (!read_int8_value(value, in_type, out_data, out_idx)) + return FALSE; + break; + + default: + FIXME("Unhandled out_type %#x.\n", out_type); + return FALSE; + } + } + + return TRUE; +} + +static BOOL parse_fx10_state_group(const char *data, size_t data_size, + const char **ptr, D3D_SHADER_VARIABLE_TYPE container_type, void *container) +{ + const struct d3d10_effect_state_property_info *property_info; + UINT value_offset; + unsigned int i; + DWORD count; + UINT idx; + UINT id; + + read_dword(ptr, &count); + TRACE("Property count: %#x.\n", count); + + for (i = 0; i < count; ++i) + { + read_dword(ptr, &id); + read_dword(ptr, &idx); + skip_dword_unknown("read property", ptr, 1); + read_dword(ptr, &value_offset); + + if (!(property_info = get_property_info(id))) + { + FIXME("Failed to find property info for property %#x.\n", id); + return FALSE; + } + + TRACE("Property %s[%#x] = value list @ offset %#x.\n", + property_info->name, idx, value_offset); + + if (property_info->container_type != container_type) + { + ERR("Invalid container type %#x for property %#x.\n", container_type, id); + return FALSE; + } + + if (idx >= property_info->count) + { + ERR("Invalid index %#x for property %#x.\n", idx, id); + return FALSE; + } + + if (!read_value_list(data, data_size, value_offset, property_info->type, idx, + property_info->size, (char *)container + property_info->offset)) + { + ERR("Failed to read values for property %#x.\n", id); + return FALSE; + } + } + + return TRUE; +} + +static HRESULT parse_fx10_object(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_object *o) +{ + ID3D10EffectVariable *variable = &null_variable.ID3D10EffectVariable_iface; + const char *data_ptr = NULL; + DWORD offset; + enum d3d10_effect_object_operation operation; + HRESULT hr; + struct d3d10_effect *effect = o->pass->technique->effect; + ID3D10Effect *e = &effect->ID3D10Effect_iface; + struct d3d10_effect_variable *v; + DWORD tmp, variable_idx = 0; + const char *name; + size_t name_len; + + if (!require_space(*ptr - data, 4, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#lx (data size %#lx).\n", (long)(*ptr - data), (long)data_size); + return E_FAIL; + } +#ifdef __REACTOS__ + read_dword(ptr, (DWORD*)&o->type); +#else + read_dword(ptr, &o->type); +#endif + TRACE("Effect object is of type %#x.\n", o->type); + + read_dword(ptr, &tmp); + TRACE("Effect object index %#x.\n", tmp); +#ifdef __REACTOS__ + read_dword(ptr, (DWORD *)&operation); +#else + read_dword(ptr, &operation); +#endif + TRACE("Effect object operation %#x.\n", operation); + + read_dword(ptr, &offset); + TRACE("Effect object idx is at offset %#x.\n", offset); + + switch(operation) + { + case D3D10_EOO_VALUE: + TRACE("Copy variable values\n"); + + switch (o->type) + { + case D3D10_EOT_VERTEXSHADER: + TRACE("Vertex shader\n"); + variable = &anonymous_vs.ID3D10EffectVariable_iface; + break; + + case D3D10_EOT_PIXELSHADER: + TRACE("Pixel shader\n"); + variable = &anonymous_ps.ID3D10EffectVariable_iface; + break; + + case D3D10_EOT_GEOMETRYSHADER: + TRACE("Geometry shader\n"); + variable = &anonymous_gs.ID3D10EffectVariable_iface; + break; + + case D3D10_EOT_STENCIL_REF: + if (!read_value_list(data, data_size, offset, D3D10_SVT_UINT, 0, 1, &o->pass->stencil_ref)) + { + ERR("Failed to read stencil ref.\n"); + return E_FAIL; + } + break; + + case D3D10_EOT_SAMPLE_MASK: + if (!read_value_list(data, data_size, offset, D3D10_SVT_UINT, 0, 1, &o->pass->sample_mask)) + { + FIXME("Failed to read sample mask.\n"); + return E_FAIL; + } + break; + + case D3D10_EOT_BLEND_FACTOR: + if (!read_value_list(data, data_size, offset, D3D10_SVT_FLOAT, 0, 4, &o->pass->blend_factor[0])) + { + FIXME("Failed to read blend factor.\n"); + return E_FAIL; + } + break; + + default: + FIXME("Unhandled object type %#x\n", o->type); + return E_FAIL; + } + break; + + case D3D10_EOO_PARSED_OBJECT: + /* This is a local object, we've parsed in parse_fx10_local_object. */ + if (!fx10_get_string(data, data_size, offset, &name, &name_len)) + { + WARN("Failed to get variable name.\n"); + return E_FAIL; + } + TRACE("Variable name %s.\n", debugstr_a(name)); + + variable = e->lpVtbl->GetVariableByName(e, name); + break; + + case D3D10_EOO_PARSED_OBJECT_INDEX: + /* This is a local object, we've parsed in parse_fx10_local_object, which has an array index. */ + if (offset >= data_size || !require_space(offset, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + data_ptr = data + offset; + read_dword(&data_ptr, &offset); + read_dword(&data_ptr, &variable_idx); + + if (!fx10_get_string(data, data_size, offset, &name, &name_len)) + { + WARN("Failed to get variable name.\n"); + return E_FAIL; + } + + TRACE("Variable name %s[%u].\n", debugstr_a(name), variable_idx); + + variable = e->lpVtbl->GetVariableByName(e, name); + break; + + case D3D10_EOO_ANONYMOUS_SHADER: + TRACE("Anonymous shader\n"); + + /* check anonymous_shader_current for validity */ + if (effect->anonymous_shader_current >= effect->anonymous_shader_count) + { + ERR("Anonymous shader count is wrong!\n"); + return E_FAIL; + } + + if (offset >= data_size || !require_space(offset, 1, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } + data_ptr = data + offset; + read_dword(&data_ptr, &offset); + TRACE("Effect object starts at offset %#x.\n", offset); + + if (FAILED(hr = parse_fx10_anonymous_shader(effect, + &effect->anonymous_shaders[effect->anonymous_shader_current], o->type))) + return hr; + + v = &effect->anonymous_shaders[effect->anonymous_shader_current].shader; + variable = &v->ID3D10EffectVariable_iface; + ++effect->anonymous_shader_current; + + switch (o->type) + { + case D3D10_EOT_VERTEXSHADER: + case D3D10_EOT_PIXELSHADER: + case D3D10_EOT_GEOMETRYSHADER: + if (FAILED(hr = parse_fx10_shader(data, data_size, offset, v))) + return hr; + break; + + default: + FIXME("Unhandled object type %#x\n", o->type); + return E_FAIL; + } + break; + + default: + FIXME("Unhandled operation %#x.\n", operation); + return E_FAIL; + } + + switch (o->type) + { + case D3D10_EOT_RASTERIZER_STATE: + { + ID3D10EffectRasterizerVariable *rv = variable->lpVtbl->AsRasterizer(variable); + if (FAILED(hr = rv->lpVtbl->GetRasterizerState(rv, variable_idx, &o->object.rs))) + return hr; + break; + } + + case D3D10_EOT_DEPTH_STENCIL_STATE: + { + ID3D10EffectDepthStencilVariable *dv = variable->lpVtbl->AsDepthStencil(variable); + if (FAILED(hr = dv->lpVtbl->GetDepthStencilState(dv, variable_idx, &o->object.ds))) + return hr; + break; + } + + case D3D10_EOT_BLEND_STATE: + { + ID3D10EffectBlendVariable *bv = variable->lpVtbl->AsBlend(variable); + if (FAILED(hr = bv->lpVtbl->GetBlendState(bv, variable_idx, &o->object.bs))) + return hr; + break; + } + + case D3D10_EOT_VERTEXSHADER: + { + ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); + if (FAILED(hr = sv->lpVtbl->GetVertexShader(sv, variable_idx, &o->object.vs))) + return hr; + o->pass->vs.pShaderVariable = sv; + o->pass->vs.ShaderIndex = variable_idx; + break; + } + + case D3D10_EOT_PIXELSHADER: + { + ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); + if (FAILED(hr = sv->lpVtbl->GetPixelShader(sv, variable_idx, &o->object.ps))) + return hr; + o->pass->ps.pShaderVariable = sv; + o->pass->ps.ShaderIndex = variable_idx; + break; + } + + case D3D10_EOT_GEOMETRYSHADER: + { + ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable); + if (FAILED(hr = sv->lpVtbl->GetGeometryShader(sv, variable_idx, &o->object.gs))) + return hr; + o->pass->gs.pShaderVariable = sv; + o->pass->gs.ShaderIndex = variable_idx; + break; + } + + case D3D10_EOT_STENCIL_REF: + case D3D10_EOT_BLEND_FACTOR: + case D3D10_EOT_SAMPLE_MASK: + break; + + default: + FIXME("Unhandled object type %#x.\n", o->type); + return E_FAIL; + } + + return S_OK; +} + +static HRESULT parse_fx10_pass(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_pass *p) +{ + HRESULT hr = S_OK; + unsigned int i; + DWORD offset; + + read_dword(ptr, &offset); + TRACE("Pass name at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &p->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Pass name: %s.\n", debugstr_a(p->name)); + + read_dword(ptr, &p->object_count); + TRACE("Pass has %u effect objects.\n", p->object_count); + + read_dword(ptr, &p->annotation_count); + TRACE("Pass has %u annotations.\n", p->annotation_count); + + if (!(p->annotations = heap_calloc(p->annotation_count, sizeof(*p->annotations)))) + { + ERR("Failed to allocate pass annotations memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < p->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &p->annotations[i]; + + a->effect = p->technique->effect; + a->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_annotation(data, data_size, ptr, a))) + return hr; + } + + if (!(p->objects = heap_calloc(p->object_count, sizeof(*p->objects)))) + { + ERR("Failed to allocate effect objects memory.\n"); + return E_OUTOFMEMORY; + } + + p->vs.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; + p->ps.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; + p->gs.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; + + for (i = 0; i < p->object_count; ++i) + { + struct d3d10_effect_object *o = &p->objects[i]; + + o->pass = p; + + if (FAILED(hr = parse_fx10_object(data, data_size, ptr, o))) + return hr; + } + + return hr; +} + +static HRESULT parse_fx10_technique(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_technique *t) +{ + unsigned int i; + DWORD offset; + HRESULT hr; + + read_dword(ptr, &offset); + TRACE("Technique name at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &t->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Technique name: %s.\n", debugstr_a(t->name)); + + read_dword(ptr, &t->pass_count); + TRACE("Technique has %u passes\n", t->pass_count); + + read_dword(ptr, &t->annotation_count); + TRACE("Technique has %u annotations.\n", t->annotation_count); + + if (!(t->annotations = heap_calloc(t->annotation_count, sizeof(*t->annotations)))) + { + ERR("Failed to allocate technique annotations memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < t->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &t->annotations[i]; + + a->effect = t->effect; + a->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_annotation(data, data_size, ptr, a))) + return hr; + } + + if (!(t->passes = heap_calloc(t->pass_count, sizeof(*t->passes)))) + { + ERR("Failed to allocate passes memory\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < t->pass_count; ++i) + { + struct d3d10_effect_pass *p = &t->passes[i]; + + p->ID3D10EffectPass_iface.lpVtbl = &d3d10_effect_pass_vtbl; + p->technique = t; + + if (FAILED(hr = parse_fx10_pass(data, data_size, ptr, p))) + return hr; + } + + return S_OK; +} + +static HRESULT parse_fx10_variable(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_variable *v) +{ + DWORD offset; + unsigned int i; + HRESULT hr; + + if (FAILED(hr = parse_fx10_variable_head(data, data_size, ptr, v))) + return hr; + + read_dword(ptr, &offset); + TRACE("Variable semantic at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &v->semantic)) + { + ERR("Failed to copy semantic.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable semantic: %s.\n", debugstr_a(v->semantic)); + + read_dword(ptr, &v->buffer_offset); + TRACE("Variable offset in buffer: %#x.\n", v->buffer_offset); + + skip_dword_unknown("variable", ptr, 1); + + read_dword(ptr, &v->flag); + TRACE("Variable flag: %#x.\n", v->flag); + + read_dword(ptr, &v->annotation_count); + TRACE("Variable has %u annotations.\n", v->annotation_count); + + if (!(v->annotations = heap_calloc(v->annotation_count, sizeof(*v->annotations)))) + { + ERR("Failed to allocate variable annotations memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < v->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &v->annotations[i]; + + a->effect = v->effect; + a->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_annotation(data, data_size, ptr, a))) + return hr; + } + + return S_OK; +} + +static HRESULT create_state_object(struct d3d10_effect_variable *v) +{ + ID3D10Device *device = v->effect->device; + HRESULT hr; + + switch (v->type->basetype) + { + case D3D10_SVT_DEPTHSTENCIL: + if (FAILED(hr = ID3D10Device_CreateDepthStencilState(device, + &v->u.state.desc.depth_stencil, &v->u.state.object.depth_stencil))) + return hr; + break; + + case D3D10_SVT_BLEND: + if (FAILED(hr = ID3D10Device_CreateBlendState(device, + &v->u.state.desc.blend, &v->u.state.object.blend))) + return hr; + break; + + case D3D10_SVT_RASTERIZER: + if (FAILED(hr = ID3D10Device_CreateRasterizerState(device, + &v->u.state.desc.rasterizer, &v->u.state.object.rasterizer))) + return hr; + break; + + case D3D10_SVT_SAMPLER: + if (FAILED(hr = ID3D10Device_CreateSamplerState(device, + &v->u.state.desc.sampler, &v->u.state.object.sampler))) + return hr; + break; + + default: + ERR("Unhandled variable type %s.\n", debug_d3d10_shader_variable_type(v->type->basetype)); + return E_FAIL; + } + + return S_OK; +} + +static HRESULT parse_fx10_local_variable(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_variable *v) +{ + unsigned int i; + HRESULT hr; + DWORD offset; + + if (FAILED(hr = parse_fx10_variable_head(data, data_size, ptr, v))) + return hr; + + read_dword(ptr, &offset); + TRACE("Variable semantic at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &v->semantic)) + { + ERR("Failed to copy semantic.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable semantic: %s.\n", debugstr_a(v->semantic)); + + skip_dword_unknown("local variable", ptr, 1); + + switch (v->type->basetype) + { + case D3D10_SVT_TEXTURE1D: + case D3D10_SVT_TEXTURE1DARRAY: + case D3D10_SVT_TEXTURE2D: + case D3D10_SVT_TEXTURE2DARRAY: + case D3D10_SVT_TEXTURE2DMS: + case D3D10_SVT_TEXTURE2DMSARRAY: + case D3D10_SVT_TEXTURE3D: + case D3D10_SVT_TEXTURECUBE: + case D3D10_SVT_RENDERTARGETVIEW: + case D3D10_SVT_DEPTHSTENCILVIEW: + case D3D10_SVT_BUFFER: + TRACE("SVT could not have elements.\n"); + break; + + case D3D10_SVT_VERTEXSHADER: + case D3D10_SVT_PIXELSHADER: + case D3D10_SVT_GEOMETRYSHADER: + TRACE("Shader type is %s\n", debug_d3d10_shader_variable_type(v->type->basetype)); + for (i = 0; i < max(v->type->element_count, 1); ++i) + { + DWORD shader_offset; + struct d3d10_effect_variable *var; + + if (!v->type->element_count) + { + var = v; + } + else + { + var = &v->elements[i]; + } + + read_dword(ptr, &shader_offset); + TRACE("Shader offset: %#x.\n", shader_offset); + + if (FAILED(hr = parse_fx10_shader(data, data_size, shader_offset, var))) + return hr; + } + break; + + case D3D10_SVT_DEPTHSTENCIL: + case D3D10_SVT_BLEND: + case D3D10_SVT_RASTERIZER: + case D3D10_SVT_SAMPLER: + { + const struct d3d10_effect_state_storage_info *storage_info; + unsigned int count = max(v->type->element_count, 1); + + if (!(storage_info = get_storage_info(v->type->basetype))) + { + FIXME("Failed to get backing store info for type %s.\n", + debug_d3d10_shader_variable_type(v->type->basetype)); + return E_FAIL; + } + + if (storage_info->size > sizeof(v->u.state.desc)) + { + ERR("Invalid storage size %#lx.\n", storage_info->size); + return E_FAIL; + } + + for (i = 0; i < count; ++i) + { + struct d3d10_effect_variable *var; + + if (v->type->element_count) + var = &v->elements[i]; + else + var = v; + + memcpy(&var->u.state.desc, storage_info->default_state, storage_info->size); + if (!parse_fx10_state_group(data, data_size, ptr, var->type->basetype, &var->u.state.desc)) + { + ERR("Failed to read property list.\n"); + return E_FAIL; + } + + if (FAILED(hr = create_state_object(v))) + return hr; + } + } + break; + + default: + FIXME("Unhandled case %s.\n", debug_d3d10_shader_variable_type(v->type->basetype)); + return E_FAIL; + } + + read_dword(ptr, &v->annotation_count); + TRACE("Variable has %u annotations.\n", v->annotation_count); + + if (!(v->annotations = heap_calloc(v->annotation_count, sizeof(*v->annotations)))) + { + ERR("Failed to allocate variable annotations memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < v->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &v->annotations[i]; + + a->effect = v->effect; + a->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_annotation(data, data_size, ptr, a))) + return hr; + } + + return S_OK; +} + +static HRESULT parse_fx10_local_buffer(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_variable *l) +{ + unsigned int i; + DWORD offset; + D3D10_CBUFFER_TYPE d3d10_cbuffer_type; + HRESULT hr; + unsigned int stride = 0; + + /* Generate our own type, it isn't in the fx blob. */ + if (!(l->type = heap_alloc_zero(sizeof(*l->type)))) + { + ERR("Failed to allocate local buffer type memory.\n"); + return E_OUTOFMEMORY; + } + l->type->ID3D10EffectType_iface.lpVtbl = &d3d10_effect_type_vtbl; + l->type->type_class = D3D10_SVC_OBJECT; + l->type->effect = l->effect; + + read_dword(ptr, &offset); + TRACE("Local buffer name at offset %#x.\n", offset); + + if (!fx10_copy_string(data, data_size, offset, &l->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Local buffer name: %s.\n", debugstr_a(l->name)); + + read_dword(ptr, &l->data_size); + TRACE("Local buffer data size: %#x.\n", l->data_size); + +#ifdef __REACTOS__ + read_dword(ptr, (DWORD*)&d3d10_cbuffer_type); +#else + read_dword(ptr, &d3d10_cbuffer_type); +#endif + TRACE("Local buffer type: %#x.\n", d3d10_cbuffer_type); + + switch(d3d10_cbuffer_type) + { + case D3D10_CT_CBUFFER: + l->type->basetype = D3D10_SVT_CBUFFER; + if (!copy_name("cbuffer", &l->type->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + break; + + case D3D10_CT_TBUFFER: + l->type->basetype = D3D10_SVT_TBUFFER; + if (!copy_name("tbuffer", &l->type->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + break; + + default: + ERR("Unexpected D3D10_CBUFFER_TYPE %#x!\n", d3d10_cbuffer_type); + return E_FAIL; + } + + read_dword(ptr, &l->type->member_count); + TRACE("Local buffer member count: %#x.\n", l->type->member_count); + + skip_dword_unknown("local buffer", ptr, 1); + + read_dword(ptr, &l->annotation_count); + TRACE("Local buffer has %u annotations.\n", l->annotation_count); + + if (!(l->annotations = heap_calloc(l->annotation_count, sizeof(*l->annotations)))) + { + ERR("Failed to allocate local buffer annotations memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < l->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &l->annotations[i]; + + a->effect = l->effect; + a->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_annotation(data, data_size, ptr, a))) + return hr; + } + + if (!(l->members = heap_calloc(l->type->member_count, sizeof(*l->members)))) + { + ERR("Failed to allocate members memory.\n"); + return E_OUTOFMEMORY; + } + + if (!(l->type->members = heap_calloc(l->type->member_count, sizeof(*l->type->members)))) + { + ERR("Failed to allocate type members memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < l->type->member_count; ++i) + { + struct d3d10_effect_variable *v = &l->members[i]; + struct d3d10_effect_type_member *typem = &l->type->members[i]; + + v->buffer = l; + v->effect = l->effect; + + if (FAILED(hr = parse_fx10_variable(data, data_size, ptr, v))) + return hr; + + /* + * Copy the values from the variable type to the constant buffers type + * members structure, because it is our own generated type. + */ + typem->type = v->type; + + if (!copy_name(v->name, &typem->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable name: %s.\n", debugstr_a(typem->name)); + + if (!copy_name(v->semantic, &typem->semantic)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Variable semantic: %s.\n", debugstr_a(typem->semantic)); + + typem->buffer_offset = v->buffer_offset; + TRACE("Variable buffer offset: %u.\n", typem->buffer_offset); + + l->type->size_packed += v->type->size_packed; + + /* + * For the complete constantbuffer the size_unpacked = stride, + * the stride is calculated like this: + * + * 1) if the constant buffer variables are packed with packoffset + * - stride = the highest used constant + * - the complete stride has to be a multiple of 0x10 + * + * 2) if the constant buffer variables are NOT packed with packoffset + * - sum of unpacked size for all variables which fit in a 0x10 part + * - if the size exceeds a 0x10 part, the rest of the old part is skipped + * and a new part is started + * - if the variable is a struct it is always used a new part + * - the complete stride has to be a multiple of 0x10 + * + * e.g.: + * 0x4, 0x4, 0x4, 0x8, 0x4, 0x14, 0x4 + * part 0x10 0x10 0x20 -> 0x40 + */ + if (v->flag & D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT) + { + if ((v->type->size_unpacked + v->buffer_offset) > stride) + { + stride = v->type->size_unpacked + v->buffer_offset; + } + } + else + { + if (v->type->type_class == D3D10_SVC_STRUCT) + { + stride = (stride + 0xf) & ~0xf; + } + + if ( ((stride & 0xf) + v->type->size_unpacked) > 0x10) + { + stride = (stride + 0xf) & ~0xf; + } + + stride += v->type->size_unpacked; + } + } + l->type->stride = l->type->size_unpacked = (stride + 0xf) & ~0xf; + + TRACE("Constant buffer:\n"); + TRACE("\tType name: %s.\n", debugstr_a(l->type->name)); + TRACE("\tElement count: %u.\n", l->type->element_count); + TRACE("\tMember count: %u.\n", l->type->member_count); + TRACE("\tUnpacked size: %#x.\n", l->type->size_unpacked); + TRACE("\tStride: %#x.\n", l->type->stride); + TRACE("\tPacked size %#x.\n", l->type->size_packed); + TRACE("\tBasetype: %s.\n", debug_d3d10_shader_variable_type(l->type->basetype)); + TRACE("\tTypeclass: %s.\n", debug_d3d10_shader_variable_class(l->type->type_class)); + + return S_OK; +} + +static void d3d10_effect_type_member_destroy(struct d3d10_effect_type_member *typem) +{ + TRACE("effect type member %p.\n", typem); + + /* Do not release typem->type, it will be covered by d3d10_effect_type_destroy(). */ + heap_free(typem->semantic); + heap_free(typem->name); +} + +static void d3d10_effect_type_destroy(struct wine_rb_entry *entry, void *context) +{ + struct d3d10_effect_type *t = WINE_RB_ENTRY_VALUE(entry, struct d3d10_effect_type, entry); + + TRACE("effect type %p.\n", t); + + if (t->elementtype) + { + heap_free(t->elementtype->name); + heap_free(t->elementtype); + } + + if (t->members) + { + unsigned int i; + + for (i = 0; i < t->member_count; ++i) + { + d3d10_effect_type_member_destroy(&t->members[i]); + } + heap_free(t->members); + } + + heap_free(t->name); + heap_free(t); +} + +static HRESULT parse_fx10_body(struct d3d10_effect *e, const char *data, DWORD data_size) +{ + const char *ptr; + unsigned int i; + HRESULT hr; + + if (e->index_offset >= data_size) + { + WARN("Invalid index offset %#x (data size %#x).\n", e->index_offset, data_size); + return E_FAIL; + } + ptr = data + e->index_offset; + + if (!(e->local_buffers = heap_calloc(e->local_buffer_count, sizeof(*e->local_buffers)))) + { + ERR("Failed to allocate local buffer memory.\n"); + return E_OUTOFMEMORY; + } + + if (!(e->local_variables = heap_calloc(e->local_variable_count, sizeof(*e->local_variables)))) + { + ERR("Failed to allocate local variable memory.\n"); + return E_OUTOFMEMORY; + } + + if (!(e->anonymous_shaders = heap_calloc(e->anonymous_shader_count, sizeof(*e->anonymous_shaders)))) + { + ERR("Failed to allocate anonymous shaders memory\n"); + return E_OUTOFMEMORY; + } + + if (!(e->used_shaders = heap_calloc(e->used_shader_count, sizeof(*e->used_shaders)))) + { + ERR("Failed to allocate used shaders memory\n"); + return E_OUTOFMEMORY; + } + + if (!(e->techniques = heap_calloc(e->technique_count, sizeof(*e->techniques)))) + { + ERR("Failed to allocate techniques memory\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < e->local_buffer_count; ++i) + { + struct d3d10_effect_variable *l = &e->local_buffers[i]; + l->ID3D10EffectVariable_iface.lpVtbl = (const ID3D10EffectVariableVtbl *)&d3d10_effect_constant_buffer_vtbl; + l->effect = e; + l->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_local_buffer(data, data_size, &ptr, l))) + return hr; + } + + for (i = 0; i < e->local_variable_count; ++i) + { + struct d3d10_effect_variable *v = &e->local_variables[i]; + + v->effect = e; + v->ID3D10EffectVariable_iface.lpVtbl = &d3d10_effect_variable_vtbl; + v->buffer = &null_local_buffer; + + if (FAILED(hr = parse_fx10_local_variable(data, data_size, &ptr, v))) + return hr; + } + + for (i = 0; i < e->technique_count; ++i) + { + struct d3d10_effect_technique *t = &e->techniques[i]; + + t->ID3D10EffectTechnique_iface.lpVtbl = &d3d10_effect_technique_vtbl; + t->effect = e; + + if (FAILED(hr = parse_fx10_technique(data, data_size, &ptr, t))) + return hr; + } + + return S_OK; +} + +static HRESULT parse_fx10(struct d3d10_effect *e, const char *data, DWORD data_size) +{ + const char *ptr = data; + DWORD unknown; + + if (!require_space(0, 19, sizeof(DWORD), data_size)) + { + WARN("Invalid data size %#x.\n", data_size); + return E_INVALIDARG; + } + + /* Compiled target version (e.g. fx_4_0=0xfeff1001, fx_4_1=0xfeff1011). */ + read_dword(&ptr, &e->version); + TRACE("Target: %#x\n", e->version); + + read_dword(&ptr, &e->local_buffer_count); + TRACE("Local buffer count: %u.\n", e->local_buffer_count); + + read_dword(&ptr, &e->variable_count); + TRACE("Variable count: %u\n", e->variable_count); + + read_dword(&ptr, &e->local_variable_count); + TRACE("Object count: %u\n", e->local_variable_count); + + read_dword(&ptr, &e->sharedbuffers_count); + TRACE("Sharedbuffers count: %u\n", e->sharedbuffers_count); + + /* Number of variables in shared buffers? */ + read_dword(&ptr, &unknown); + FIXME("Unknown 0: %u\n", unknown); + + read_dword(&ptr, &e->sharedobjects_count); + TRACE("Sharedobjects count: %u\n", e->sharedobjects_count); + + read_dword(&ptr, &e->technique_count); + TRACE("Technique count: %u\n", e->technique_count); + + read_dword(&ptr, &e->index_offset); + TRACE("Index offset: %#x\n", e->index_offset); + + read_dword(&ptr, &unknown); + FIXME("Unknown 1: %u\n", unknown); + + read_dword(&ptr, &e->texture_count); + TRACE("Texture count: %u\n", e->texture_count); + + read_dword(&ptr, &e->depthstencilstate_count); + TRACE("Depthstencilstate count: %u\n", e->depthstencilstate_count); + + read_dword(&ptr, &e->blendstate_count); + TRACE("Blendstate count: %u\n", e->blendstate_count); + + read_dword(&ptr, &e->rasterizerstate_count); + TRACE("Rasterizerstate count: %u\n", e->rasterizerstate_count); + + read_dword(&ptr, &e->samplerstate_count); + TRACE("Samplerstate count: %u\n", e->samplerstate_count); + + read_dword(&ptr, &e->rendertargetview_count); + TRACE("Rendertargetview count: %u\n", e->rendertargetview_count); + + read_dword(&ptr, &e->depthstencilview_count); + TRACE("Depthstencilview count: %u\n", e->depthstencilview_count); + + read_dword(&ptr, &e->used_shader_count); + TRACE("Used shader count: %u\n", e->used_shader_count); + + read_dword(&ptr, &e->anonymous_shader_count); + TRACE("Anonymous shader count: %u\n", e->anonymous_shader_count); + + return parse_fx10_body(e, ptr, data_size - (ptr - data)); +} + +static HRESULT fx10_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +{ + struct d3d10_effect *e = ctx; + + TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4)); + + TRACE("chunk size: %#x\n", data_size); + + switch(tag) + { + case TAG_FX10: + return parse_fx10(e, data, data_size); + + default: + FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag, 4)); + return S_OK; + } +} + +HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T data_size) +{ + return parse_dxbc(data, data_size, fx10_chunk_handler, This); +} + +static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o) +{ + ID3D10Device *device = o->pass->technique->effect->device; + + TRACE("effect object %p, type %#x.\n", o, o->type); + + switch(o->type) + { + case D3D10_EOT_RASTERIZER_STATE: + ID3D10Device_RSSetState(device, o->object.rs); + return S_OK; + + case D3D10_EOT_DEPTH_STENCIL_STATE: + ID3D10Device_OMSetDepthStencilState(device, o->object.ds, o->pass->stencil_ref); + return S_OK; + + case D3D10_EOT_BLEND_STATE: + ID3D10Device_OMSetBlendState(device, o->object.bs, o->pass->blend_factor, o->pass->sample_mask); + return S_OK; + + case D3D10_EOT_VERTEXSHADER: + ID3D10Device_VSSetShader(device, o->object.vs); + return S_OK; + + case D3D10_EOT_PIXELSHADER: + ID3D10Device_PSSetShader(device, o->object.ps); + return S_OK; + + case D3D10_EOT_GEOMETRYSHADER: + ID3D10Device_GSSetShader(device, o->object.gs); + return S_OK; + + case D3D10_EOT_STENCIL_REF: + case D3D10_EOT_BLEND_FACTOR: + case D3D10_EOT_SAMPLE_MASK: + return S_OK; + + default: + FIXME("Unhandled effect object type %#x.\n", o->type); + return E_FAIL; + } +} + +static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_variable *s, + D3D10_SHADER_VARIABLE_TYPE type) +{ + shader_free_signature(&s->input_signature); + shader_free_signature(&s->output_signature); + + switch (type) + { + case D3D10_SVT_VERTEXSHADER: + if (s->shader.vs) + ID3D10VertexShader_Release(s->shader.vs); + break; + + case D3D10_SVT_PIXELSHADER: + if (s->shader.ps) + ID3D10PixelShader_Release(s->shader.ps); + break; + + case D3D10_SVT_GEOMETRYSHADER: + if (s->shader.gs) + ID3D10GeometryShader_Release(s->shader.gs); + break; + + default: + FIXME("Unhandled shader type %s.\n", debug_d3d10_shader_variable_type(type)); + break; + } +} + +static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) +{ + unsigned int i; + + TRACE("variable %p.\n", v); + + heap_free(v->name); + heap_free(v->semantic); + if (v->annotations) + { + for (i = 0; i < v->annotation_count; ++i) + { + d3d10_effect_variable_destroy(&v->annotations[i]); + } + heap_free(v->annotations); + } + + if (v->members) + { + for (i = 0; i < v->type->member_count; ++i) + { + d3d10_effect_variable_destroy(&v->members[i]); + } + heap_free(v->members); + } + + if (v->elements) + { + for (i = 0; i < v->type->element_count; ++i) + { + d3d10_effect_variable_destroy(&v->elements[i]); + } + heap_free(v->elements); + } + + if (v->type) + { + switch (v->type->basetype) + { + case D3D10_SVT_VERTEXSHADER: + case D3D10_SVT_PIXELSHADER: + case D3D10_SVT_GEOMETRYSHADER: + d3d10_effect_shader_variable_destroy(&v->u.shader, v->type->basetype); + break; + + case D3D10_SVT_DEPTHSTENCIL: + if (v->u.state.object.depth_stencil) + ID3D10DepthStencilState_Release(v->u.state.object.depth_stencil); + break; + + case D3D10_SVT_BLEND: + if (v->u.state.object.blend) + ID3D10BlendState_Release(v->u.state.object.blend); + break; + + case D3D10_SVT_RASTERIZER: + if (v->u.state.object.rasterizer) + ID3D10RasterizerState_Release(v->u.state.object.rasterizer); + break; + + case D3D10_SVT_SAMPLER: + if (v->u.state.object.sampler) + ID3D10SamplerState_Release(v->u.state.object.sampler); + break; + + default: + break; + } + } +} + +static void d3d10_effect_object_destroy(struct d3d10_effect_object *o) +{ + switch (o->type) + { + case D3D10_EOT_RASTERIZER_STATE: + if (o->object.rs) + ID3D10RasterizerState_Release(o->object.rs); + break; + + case D3D10_EOT_DEPTH_STENCIL_STATE: + if (o->object.ds) + ID3D10DepthStencilState_Release(o->object.ds); + break; + + case D3D10_EOT_BLEND_STATE: + if (o->object.bs) + ID3D10BlendState_Release(o->object.bs); + break; + + case D3D10_EOT_VERTEXSHADER: + if (o->object.vs) + ID3D10VertexShader_Release(o->object.vs); + break; + + case D3D10_EOT_PIXELSHADER: + if (o->object.ps) + ID3D10PixelShader_Release(o->object.ps); + break; + + case D3D10_EOT_GEOMETRYSHADER: + if (o->object.gs) + ID3D10GeometryShader_Release(o->object.gs); + break; + + default: + break; + } +} + +static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p) +{ + unsigned int i; + + TRACE("pass %p\n", p); + + heap_free(p->name); + + if (p->objects) + { + for (i = 0; i < p->object_count; ++i) + { + d3d10_effect_object_destroy(&p->objects[i]); + } + heap_free(p->objects); + } + + if (p->annotations) + { + for (i = 0; i < p->annotation_count; ++i) + { + d3d10_effect_variable_destroy(&p->annotations[i]); + } + heap_free(p->annotations); + } +} + +static void d3d10_effect_technique_destroy(struct d3d10_effect_technique *t) +{ + unsigned int i; + + TRACE("technique %p\n", t); + + heap_free(t->name); + if (t->passes) + { + for (i = 0; i < t->pass_count; ++i) + { + d3d10_effect_pass_destroy(&t->passes[i]); + } + heap_free(t->passes); + } + + if (t->annotations) + { + for (i = 0; i < t->annotation_count; ++i) + { + d3d10_effect_variable_destroy(&t->annotations[i]); + } + heap_free(t->annotations); + } +} + +static void d3d10_effect_local_buffer_destroy(struct d3d10_effect_variable *l) +{ + unsigned int i; + + TRACE("local buffer %p.\n", l); + + heap_free(l->name); + if (l->members) + { + for (i = 0; i < l->type->member_count; ++i) + { + d3d10_effect_variable_destroy(&l->members[i]); + } + heap_free(l->members); + } + + if (l->type) + d3d10_effect_type_destroy(&l->type->entry, NULL); + + if (l->annotations) + { + for (i = 0; i < l->annotation_count; ++i) + { + d3d10_effect_variable_destroy(&l->annotations[i]); + } + heap_free(l->annotations); + } +} + +/* IUnknown methods */ + +static inline struct d3d10_effect *impl_from_ID3D10Effect(ID3D10Effect *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect, ID3D10Effect_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_QueryInterface(ID3D10Effect *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D10Effect) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_effect_AddRef(ID3D10Effect *iface) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_effect_Release(ID3D10Effect *iface) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + unsigned int i; + + if (This->techniques) + { + for (i = 0; i < This->technique_count; ++i) + { + d3d10_effect_technique_destroy(&This->techniques[i]); + } + heap_free(This->techniques); + } + + if (This->local_variables) + { + for (i = 0; i < This->local_variable_count; ++i) + { + d3d10_effect_variable_destroy(&This->local_variables[i]); + } + heap_free(This->local_variables); + } + + if (This->local_buffers) + { + for (i = 0; i < This->local_buffer_count; ++i) + { + d3d10_effect_local_buffer_destroy(&This->local_buffers[i]); + } + heap_free(This->local_buffers); + } + + if (This->anonymous_shaders) + { + for (i = 0; i < This->anonymous_shader_count; ++i) + { + d3d10_effect_variable_destroy(&This->anonymous_shaders[i].shader); + heap_free(This->anonymous_shaders[i].type.name); + } + heap_free(This->anonymous_shaders); + } + + heap_free(This->used_shaders); + + wine_rb_destroy(&This->types, d3d10_effect_type_destroy, NULL); + + ID3D10Device_Release(This->device); + heap_free(This); + } + + return refcount; +} + +/* ID3D10Effect methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_IsValid(ID3D10Effect *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static BOOL STDMETHODCALLTYPE d3d10_effect_IsPool(ID3D10Effect *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDevice(ID3D10Effect *iface, ID3D10Device **device) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + + TRACE("iface %p, device %p\n", iface, device); + + ID3D10Device_AddRef(This->device); + *device = This->device; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDesc(ID3D10Effect *iface, D3D10_EFFECT_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); + + return E_NOTIMPL; +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_GetConstantBufferByIndex(ID3D10Effect *iface, + UINT index) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + struct d3d10_effect_variable *l; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->local_buffer_count) + { + WARN("Invalid index specified\n"); + return (ID3D10EffectConstantBuffer *)&null_local_buffer.ID3D10EffectVariable_iface; + } + + l = &This->local_buffers[index]; + + TRACE("Returning buffer %p, %s.\n", l, debugstr_a(l->name)); + + return (ID3D10EffectConstantBuffer *)&l->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_GetConstantBufferByName(ID3D10Effect *iface, + const char *name) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + for (i = 0; i < This->local_buffer_count; ++i) + { + struct d3d10_effect_variable *l = &This->local_buffers[i]; + + if (l->name && !strcmp(l->name, name)) + { + TRACE("Returning buffer %p.\n", l); + return (ID3D10EffectConstantBuffer *)&l->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid name specified\n"); + + return (ID3D10EffectConstantBuffer *)&null_local_buffer.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_GetVariableByIndex(ID3D10Effect *iface, UINT index) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + unsigned int i; + + TRACE("iface %p, index %u\n", iface, index); + + for (i = 0; i < This->local_buffer_count; ++i) + { + struct d3d10_effect_variable *l = &This->local_buffers[i]; + + if (index < l->type->member_count) + { + struct d3d10_effect_variable *v = &l->members[index]; + + TRACE("Returning variable %p.\n", v); + return &v->ID3D10EffectVariable_iface; + } + index -= l->type->member_count; + } + + if (index < This->local_variable_count) + { + struct d3d10_effect_variable *v = &This->local_variables[index]; + + TRACE("Returning variable %p.\n", v); + return &v->ID3D10EffectVariable_iface; + } + + WARN("Invalid index specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_GetVariableByName(ID3D10Effect *iface, + const char *name) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid name specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + for (i = 0; i < This->local_buffer_count; ++i) + { + struct d3d10_effect_variable *l = &This->local_buffers[i]; + unsigned int j; + + for (j = 0; j < l->type->member_count; ++j) + { + struct d3d10_effect_variable *v = &l->members[j]; + + if (v->name && !strcmp(v->name, name)) + { + TRACE("Returning variable %p.\n", v); + return &v->ID3D10EffectVariable_iface; + } + } + } + + for (i = 0; i < This->local_variable_count; ++i) + { + struct d3d10_effect_variable *v = &This->local_variables[i]; + + if (v->name && !strcmp(v->name, name)) + { + TRACE("Returning variable %p.\n", v); + return &v->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_GetVariableBySemantic(ID3D10Effect *iface, + const char *semantic) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + unsigned int i; + + TRACE("iface %p, semantic %s\n", iface, debugstr_a(semantic)); + + if (!semantic) + { + WARN("Invalid semantic specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + for (i = 0; i < This->local_buffer_count; ++i) + { + struct d3d10_effect_variable *l = &This->local_buffers[i]; + unsigned int j; + + for (j = 0; j < l->type->member_count; ++j) + { + struct d3d10_effect_variable *v = &l->members[j]; + + if (v->semantic && !strcmp(v->semantic, semantic)) + { + TRACE("Returning variable %p.\n", v); + return &v->ID3D10EffectVariable_iface; + } + } + } + + for (i = 0; i < This->local_variable_count; ++i) + { + struct d3d10_effect_variable *v = &This->local_variables[i]; + + if (v->semantic && !strcmp(v->semantic, semantic)) + { + TRACE("Returning variable %p.\n", v); + return &v->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid semantic specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectTechnique * STDMETHODCALLTYPE d3d10_effect_GetTechniqueByIndex(ID3D10Effect *iface, + UINT index) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + struct d3d10_effect_technique *t; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->technique_count) + { + WARN("Invalid index specified\n"); + return &null_technique.ID3D10EffectTechnique_iface; + } + + t = &This->techniques[index]; + + TRACE("Returning technique %p, %s.\n", t, debugstr_a(t->name)); + + return &t->ID3D10EffectTechnique_iface; +} + +static struct ID3D10EffectTechnique * STDMETHODCALLTYPE d3d10_effect_GetTechniqueByName(ID3D10Effect *iface, + const char *name) +{ + struct d3d10_effect *This = impl_from_ID3D10Effect(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid name specified\n"); + return &null_technique.ID3D10EffectTechnique_iface; + } + + for (i = 0; i < This->technique_count; ++i) + { + struct d3d10_effect_technique *t = &This->techniques[i]; + if (t->name && !strcmp(t->name, name)) + { + TRACE("Returning technique %p\n", t); + return &t->ID3D10EffectTechnique_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_technique.ID3D10EffectTechnique_iface; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_Optimize(ID3D10Effect *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static BOOL STDMETHODCALLTYPE d3d10_effect_IsOptimized(ID3D10Effect *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +const struct ID3D10EffectVtbl d3d10_effect_vtbl = +{ + /* IUnknown methods */ + d3d10_effect_QueryInterface, + d3d10_effect_AddRef, + d3d10_effect_Release, + /* ID3D10Effect methods */ + d3d10_effect_IsValid, + d3d10_effect_IsPool, + d3d10_effect_GetDevice, + d3d10_effect_GetDesc, + d3d10_effect_GetConstantBufferByIndex, + d3d10_effect_GetConstantBufferByName, + d3d10_effect_GetVariableByIndex, + d3d10_effect_GetVariableByName, + d3d10_effect_GetVariableBySemantic, + d3d10_effect_GetTechniqueByIndex, + d3d10_effect_GetTechniqueByName, + d3d10_effect_Optimize, + d3d10_effect_IsOptimized, +}; + +/* ID3D10EffectTechnique methods */ + +static inline struct d3d10_effect_technique *impl_from_ID3D10EffectTechnique(ID3D10EffectTechnique *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_technique, ID3D10EffectTechnique_iface); +} + +static BOOL STDMETHODCALLTYPE d3d10_effect_technique_IsValid(ID3D10EffectTechnique *iface) +{ + struct d3d10_effect_technique *This = impl_from_ID3D10EffectTechnique(iface); + + TRACE("iface %p\n", iface); + + return This != &null_technique; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_technique_GetDesc(ID3D10EffectTechnique *iface, + D3D10_TECHNIQUE_DESC *desc) +{ + struct d3d10_effect_technique *This = impl_from_ID3D10EffectTechnique(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + if(This == &null_technique) + { + WARN("Null technique specified\n"); + return E_FAIL; + } + + if(!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + desc->Name = This->name; + desc->Passes = This->pass_count; + desc->Annotations = This->annotation_count; + + return S_OK; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_technique_GetAnnotationByIndex( + ID3D10EffectTechnique *iface, UINT index) +{ + struct d3d10_effect_technique *This = impl_from_ID3D10EffectTechnique(iface); + struct d3d10_effect_variable *a; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->annotation_count) + { + WARN("Invalid index specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + a = &This->annotations[index]; + + TRACE("Returning annotation %p, %s\n", a, debugstr_a(a->name)); + + return &a->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_technique_GetAnnotationByName( + ID3D10EffectTechnique *iface, const char *name) +{ + struct d3d10_effect_technique *This = impl_from_ID3D10EffectTechnique(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + for (i = 0; i < This->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &This->annotations[i]; + if (a->name && !strcmp(a->name, name)) + { + TRACE("Returning annotation %p\n", a); + return &a->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectPass * STDMETHODCALLTYPE d3d10_effect_technique_GetPassByIndex(ID3D10EffectTechnique *iface, + UINT index) +{ + struct d3d10_effect_technique *This = impl_from_ID3D10EffectTechnique(iface); + struct d3d10_effect_pass *p; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->pass_count) + { + WARN("Invalid index specified\n"); + return &null_pass.ID3D10EffectPass_iface; + } + + p = &This->passes[index]; + + TRACE("Returning pass %p, %s.\n", p, debugstr_a(p->name)); + + return &p->ID3D10EffectPass_iface; +} + +static struct ID3D10EffectPass * STDMETHODCALLTYPE d3d10_effect_technique_GetPassByName(ID3D10EffectTechnique *iface, + const char *name) +{ + struct d3d10_effect_technique *This = impl_from_ID3D10EffectTechnique(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + /* Do not check for name==NULL, W7/DX10 crashes in that case. */ + + for (i = 0; i < This->pass_count; ++i) + { + struct d3d10_effect_pass *p = &This->passes[i]; + if (p->name && !strcmp(p->name, name)) + { + TRACE("Returning pass %p\n", p); + return &p->ID3D10EffectPass_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_pass.ID3D10EffectPass_iface; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_technique_ComputeStateBlockMask(ID3D10EffectTechnique *iface, + D3D10_STATE_BLOCK_MASK *mask) +{ + FIXME("iface %p,mask %p stub!\n", iface, mask); + + return E_NOTIMPL; +} + +static const struct ID3D10EffectTechniqueVtbl d3d10_effect_technique_vtbl = +{ + /* ID3D10EffectTechnique methods */ + d3d10_effect_technique_IsValid, + d3d10_effect_technique_GetDesc, + d3d10_effect_technique_GetAnnotationByIndex, + d3d10_effect_technique_GetAnnotationByName, + d3d10_effect_technique_GetPassByIndex, + d3d10_effect_technique_GetPassByName, + d3d10_effect_technique_ComputeStateBlockMask, +}; + +/* ID3D10EffectPass methods */ + +static inline struct d3d10_effect_pass *impl_from_ID3D10EffectPass(ID3D10EffectPass *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_pass, ID3D10EffectPass_iface); +} + +static BOOL STDMETHODCALLTYPE d3d10_effect_pass_IsValid(ID3D10EffectPass *iface) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + + TRACE("iface %p\n", iface); + + return This != &null_pass; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *iface, + D3D10_PASS_DESC *desc) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + struct d3d10_effect_shader_variable *s; + + FIXME("iface %p, desc %p partial stub!\n", iface, desc); + + if(This == &null_pass) + { + WARN("Null pass specified\n"); + return E_FAIL; + } + + if(!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + memset(desc, 0, sizeof(*desc)); + desc->Name = This->name; + + s = &impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)This->vs.pShaderVariable)->u.shader; + desc->pIAInputSignature = (BYTE *)s->input_signature.signature; + desc->IAInputSignatureSize = s->input_signature.signature_size; + + desc->StencilRef = This->stencil_ref; + desc->SampleMask = This->sample_mask; + memcpy(desc->BlendFactor, This->blend_factor, 4 * sizeof(float)); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10EffectPass *iface, + D3D10_PASS_SHADER_DESC *desc) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + if (This == &null_pass) + { + WARN("Null pass specified\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + *desc = This->vs; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10EffectPass *iface, + D3D10_PASS_SHADER_DESC *desc) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + if (This == &null_pass) + { + WARN("Null pass specified\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + *desc = This->gs; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetPixelShaderDesc(ID3D10EffectPass *iface, + D3D10_PASS_SHADER_DESC *desc) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + if (This == &null_pass) + { + WARN("Null pass specified\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + *desc = This->ps; + + return S_OK; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_pass_GetAnnotationByIndex(ID3D10EffectPass *iface, + UINT index) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + struct d3d10_effect_variable *a; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->annotation_count) + { + WARN("Invalid index specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + a = &This->annotations[index]; + + TRACE("Returning annotation %p, %s\n", a, debugstr_a(a->name)); + + return &a->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_pass_GetAnnotationByName(ID3D10EffectPass *iface, + const char *name) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + for (i = 0; i < This->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &This->annotations[i]; + if (a->name && !strcmp(a->name, name)) + { + TRACE("Returning annotation %p\n", a); + return &a->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) +{ + struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface); + HRESULT hr = S_OK; + unsigned int i; + + TRACE("iface %p, flags %#x\n", iface, flags); + + if (flags) FIXME("Ignoring flags (%#x)\n", flags); + + for (i = 0; i < This->object_count; ++i) + { + hr = d3d10_effect_object_apply(&This->objects[i]); + if (FAILED(hr)) break; + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_ComputeStateBlockMask(ID3D10EffectPass *iface, + D3D10_STATE_BLOCK_MASK *mask) +{ + FIXME("iface %p, mask %p stub!\n", iface, mask); + + return E_NOTIMPL; +} + +static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl = +{ + /* ID3D10EffectPass methods */ + d3d10_effect_pass_IsValid, + d3d10_effect_pass_GetDesc, + d3d10_effect_pass_GetVertexShaderDesc, + d3d10_effect_pass_GetGeometryShaderDesc, + d3d10_effect_pass_GetPixelShaderDesc, + d3d10_effect_pass_GetAnnotationByIndex, + d3d10_effect_pass_GetAnnotationByName, + d3d10_effect_pass_Apply, + d3d10_effect_pass_ComputeStateBlockMask, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_variable_IsValid(ID3D10EffectVariable *iface) +{ + TRACE("iface %p\n", iface); + + return impl_from_ID3D10EffectVariable(iface) != &null_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_variable_GetType(ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + return &This->type->ID3D10EffectType_iface; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetDesc(ID3D10EffectVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Null variable specified\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + /* FIXME: This isn't correct. Anonymous shaders let desc->ExplicitBindPoint untouched, but normal shaders set it! */ + memset(desc, 0, sizeof(*desc)); + desc->Name = This->name; + desc->Semantic = This->semantic; + desc->Flags = This->flag; + desc->Annotations = This->annotation_count; + desc->BufferOffset = This->buffer_offset; + + if (This->flag & D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT) + { + desc->ExplicitBindPoint = This->buffer_offset; + } + + return S_OK; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_variable_GetAnnotationByIndex( + ID3D10EffectVariable *iface, UINT index) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + struct d3d10_effect_variable *a; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->annotation_count) + { + WARN("Invalid index specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + a = &This->annotations[index]; + + TRACE("Returning annotation %p, %s\n", a, debugstr_a(a->name)); + + return &a->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_variable_GetAnnotationByName( + ID3D10EffectVariable *iface, const char *name) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + for (i = 0; i < This->annotation_count; ++i) + { + struct d3d10_effect_variable *a = &This->annotations[i]; + if (a->name && !strcmp(a->name, name)) + { + TRACE("Returning annotation %p\n", a); + return &a->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_variable_GetMemberByIndex( + ID3D10EffectVariable *iface, UINT index) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + struct d3d10_effect_variable *m; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->type->member_count) + { + WARN("Invalid index specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + m = &This->members[index]; + + TRACE("Returning member %p, %s\n", m, debugstr_a(m->name)); + + return &m->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_variable_GetMemberByName( + ID3D10EffectVariable *iface, const char *name) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + unsigned int i; + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid name specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + for (i = 0; i < This->type->member_count; ++i) + { + struct d3d10_effect_variable *m = &This->members[i]; + + if (m->name && !strcmp(m->name, name)) + { + TRACE("Returning member %p\n", m); + return &m->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_variable_GetMemberBySemantic( + ID3D10EffectVariable *iface, const char *semantic) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + unsigned int i; + + TRACE("iface %p, semantic %s.\n", iface, debugstr_a(semantic)); + + if (!semantic) + { + WARN("Invalid semantic specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + for (i = 0; i < This->type->member_count; ++i) + { + struct d3d10_effect_variable *m = &This->members[i]; + + if (m->semantic && !strcmp(m->semantic, semantic)) + { + TRACE("Returning member %p\n", m); + return &m->ID3D10EffectVariable_iface; + } + } + + WARN("Invalid semantic specified\n"); + + return &null_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_variable_GetElement( + ID3D10EffectVariable *iface, UINT index) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + struct d3d10_effect_variable *v; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->type->element_count) + { + WARN("Invalid index specified\n"); + return &null_variable.ID3D10EffectVariable_iface; + } + + v = &This->elements[index]; + + TRACE("Returning element %p, %s\n", v, debugstr_a(v->name)); + + return &v->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_variable_GetParentConstantBuffer( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + return (ID3D10EffectConstantBuffer *)&This->buffer->ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsScalar( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_scalar_variable_vtbl) + return (ID3D10EffectScalarVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectScalarVariable *)&null_scalar_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsVector( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_vector_variable_vtbl) + return (ID3D10EffectVectorVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectVectorVariable *)&null_vector_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsMatrix( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_matrix_variable_vtbl) + return (ID3D10EffectMatrixVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectMatrixVariable *)&null_matrix_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsString( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_string_variable_vtbl) + return (ID3D10EffectStringVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectStringVariable *)&null_string_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsShaderResource( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_resource_variable_vtbl) + return (ID3D10EffectShaderResourceVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectShaderResourceVariable *)&null_shader_resource_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsRenderTargetView( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_render_target_view_variable_vtbl) + return (ID3D10EffectRenderTargetViewVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectRenderTargetViewVariable *)&null_render_target_view_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsDepthStencilView( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_depth_stencil_view_variable_vtbl) + return (ID3D10EffectDepthStencilViewVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectDepthStencilViewVariable *)&null_depth_stencil_view_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_variable_AsConstantBuffer( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_constant_buffer_vtbl) + return (ID3D10EffectConstantBuffer *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectConstantBuffer *)&null_local_buffer.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsShader( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_shader_variable_vtbl) + return (ID3D10EffectShaderVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsBlend(ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_blend_variable_vtbl) + return (ID3D10EffectBlendVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectBlendVariable *)&null_blend_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsDepthStencil( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_depth_stencil_variable_vtbl) + return (ID3D10EffectDepthStencilVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectDepthStencilVariable *)&null_depth_stencil_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsRasterizer( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_rasterizer_variable_vtbl) + return (ID3D10EffectRasterizerVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectRasterizerVariable *)&null_rasterizer_variable.ID3D10EffectVariable_iface; +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_variable_AsSampler( + ID3D10EffectVariable *iface) +{ + struct d3d10_effect_variable *This = impl_from_ID3D10EffectVariable(iface); + + TRACE("iface %p\n", iface); + + if (This->ID3D10EffectVariable_iface.lpVtbl == (const ID3D10EffectVariableVtbl *)&d3d10_effect_sampler_variable_vtbl) + return (ID3D10EffectSamplerVariable *)&This->ID3D10EffectVariable_iface; + + return (ID3D10EffectSamplerVariable *)&null_sampler_variable.ID3D10EffectVariable_iface; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_SetRawValue(ID3D10EffectVariable *iface, + void *data, UINT offset, UINT count) +{ + FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectVariable *iface, + void *data, UINT offset, UINT count) +{ + FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + + return E_NOTIMPL; +} + +static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_variable_IsValid, + d3d10_effect_variable_GetType, + d3d10_effect_variable_GetDesc, + d3d10_effect_variable_GetAnnotationByIndex, + d3d10_effect_variable_GetAnnotationByName, + d3d10_effect_variable_GetMemberByIndex, + d3d10_effect_variable_GetMemberByName, + d3d10_effect_variable_GetMemberBySemantic, + d3d10_effect_variable_GetElement, + d3d10_effect_variable_GetParentConstantBuffer, + d3d10_effect_variable_AsScalar, + d3d10_effect_variable_AsVector, + d3d10_effect_variable_AsMatrix, + d3d10_effect_variable_AsString, + d3d10_effect_variable_AsShaderResource, + d3d10_effect_variable_AsRenderTargetView, + d3d10_effect_variable_AsDepthStencilView, + d3d10_effect_variable_AsConstantBuffer, + d3d10_effect_variable_AsShader, + d3d10_effect_variable_AsBlend, + d3d10_effect_variable_AsDepthStencil, + d3d10_effect_variable_AsRasterizer, + d3d10_effect_variable_AsSampler, + d3d10_effect_variable_SetRawValue, + d3d10_effect_variable_GetRawValue, +}; + +/* ID3D10EffectVariable methods */ +static BOOL STDMETHODCALLTYPE d3d10_effect_constant_buffer_IsValid(ID3D10EffectConstantBuffer *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_local_buffer; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetType(ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetDesc(ID3D10EffectConstantBuffer *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetAnnotationByIndex( + ID3D10EffectConstantBuffer *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetAnnotationByName( + ID3D10EffectConstantBuffer *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetMemberByIndex( + ID3D10EffectConstantBuffer *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetMemberByName( + ID3D10EffectConstantBuffer *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetMemberBySemantic( + ID3D10EffectConstantBuffer *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetElement( + ID3D10EffectConstantBuffer *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetParentConstantBuffer( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsScalar( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsVector( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsMatrix( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsString( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsShaderResource( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsRenderTargetView( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsDepthStencilView( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsConstantBuffer( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsShader( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsBlend(ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsDepthStencil( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsRasterizer( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_constant_buffer_AsSampler( + ID3D10EffectConstantBuffer *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_SetRawValue(ID3D10EffectConstantBuffer *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetRawValue(ID3D10EffectConstantBuffer *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectConstantBuffer methods */ +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_SetConstantBuffer(ID3D10EffectConstantBuffer *iface, + ID3D10Buffer *buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetConstantBuffer(ID3D10EffectConstantBuffer *iface, + ID3D10Buffer **buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_SetTextureBuffer(ID3D10EffectConstantBuffer *iface, + ID3D10ShaderResourceView *view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetTextureBuffer(ID3D10EffectConstantBuffer *iface, + ID3D10ShaderResourceView **view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); + + return E_NOTIMPL; +} + +static const struct ID3D10EffectConstantBufferVtbl d3d10_effect_constant_buffer_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_constant_buffer_IsValid, + d3d10_effect_constant_buffer_GetType, + d3d10_effect_constant_buffer_GetDesc, + d3d10_effect_constant_buffer_GetAnnotationByIndex, + d3d10_effect_constant_buffer_GetAnnotationByName, + d3d10_effect_constant_buffer_GetMemberByIndex, + d3d10_effect_constant_buffer_GetMemberByName, + d3d10_effect_constant_buffer_GetMemberBySemantic, + d3d10_effect_constant_buffer_GetElement, + d3d10_effect_constant_buffer_GetParentConstantBuffer, + d3d10_effect_constant_buffer_AsScalar, + d3d10_effect_constant_buffer_AsVector, + d3d10_effect_constant_buffer_AsMatrix, + d3d10_effect_constant_buffer_AsString, + d3d10_effect_constant_buffer_AsShaderResource, + d3d10_effect_constant_buffer_AsRenderTargetView, + d3d10_effect_constant_buffer_AsDepthStencilView, + d3d10_effect_constant_buffer_AsConstantBuffer, + d3d10_effect_constant_buffer_AsShader, + d3d10_effect_constant_buffer_AsBlend, + d3d10_effect_constant_buffer_AsDepthStencil, + d3d10_effect_constant_buffer_AsRasterizer, + d3d10_effect_constant_buffer_AsSampler, + d3d10_effect_constant_buffer_SetRawValue, + d3d10_effect_constant_buffer_GetRawValue, + /* ID3D10EffectConstantBuffer methods */ + d3d10_effect_constant_buffer_SetConstantBuffer, + d3d10_effect_constant_buffer_GetConstantBuffer, + d3d10_effect_constant_buffer_SetTextureBuffer, + d3d10_effect_constant_buffer_GetTextureBuffer, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_scalar_variable_IsValid(ID3D10EffectScalarVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_scalar_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetType( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetDesc(ID3D10EffectScalarVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetAnnotationByIndex( + ID3D10EffectScalarVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetAnnotationByName( + ID3D10EffectScalarVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetMemberByIndex( + ID3D10EffectScalarVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetMemberByName( + ID3D10EffectScalarVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetMemberBySemantic( + ID3D10EffectScalarVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetElement( + ID3D10EffectScalarVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetParentConstantBuffer( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsScalar( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsVector( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsMatrix( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsString( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsShaderResource( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsRenderTargetView( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsDepthStencilView( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsConstantBuffer( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsShader( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsBlend( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsDepthStencil( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsRasterizer( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_scalar_variable_AsSampler( + ID3D10EffectScalarVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetRawValue(ID3D10EffectScalarVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetRawValue(ID3D10EffectScalarVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectScalarVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloat(ID3D10EffectScalarVariable *iface, + float value) +{ + FIXME("iface %p, value %.8e stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloat(ID3D10EffectScalarVariable *iface, + float *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloatArray(ID3D10EffectScalarVariable *iface, + float *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloatArray(ID3D10EffectScalarVariable *iface, + float *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetInt(ID3D10EffectScalarVariable *iface, + int value) +{ + FIXME("iface %p, value %d stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetInt(ID3D10EffectScalarVariable *iface, + int *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetIntArray(ID3D10EffectScalarVariable *iface, + int *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetIntArray(ID3D10EffectScalarVariable *iface, + int *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBool(ID3D10EffectScalarVariable *iface, + BOOL value) +{ + FIXME("iface %p, value %d stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBool(ID3D10EffectScalarVariable *iface, + BOOL *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBoolArray(ID3D10EffectScalarVariable *iface, + BOOL *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBoolArray(ID3D10EffectScalarVariable *iface, + BOOL *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static const struct ID3D10EffectScalarVariableVtbl d3d10_effect_scalar_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_scalar_variable_IsValid, + d3d10_effect_scalar_variable_GetType, + d3d10_effect_scalar_variable_GetDesc, + d3d10_effect_scalar_variable_GetAnnotationByIndex, + d3d10_effect_scalar_variable_GetAnnotationByName, + d3d10_effect_scalar_variable_GetMemberByIndex, + d3d10_effect_scalar_variable_GetMemberByName, + d3d10_effect_scalar_variable_GetMemberBySemantic, + d3d10_effect_scalar_variable_GetElement, + d3d10_effect_scalar_variable_GetParentConstantBuffer, + d3d10_effect_scalar_variable_AsScalar, + d3d10_effect_scalar_variable_AsVector, + d3d10_effect_scalar_variable_AsMatrix, + d3d10_effect_scalar_variable_AsString, + d3d10_effect_scalar_variable_AsShaderResource, + d3d10_effect_scalar_variable_AsRenderTargetView, + d3d10_effect_scalar_variable_AsDepthStencilView, + d3d10_effect_scalar_variable_AsConstantBuffer, + d3d10_effect_scalar_variable_AsShader, + d3d10_effect_scalar_variable_AsBlend, + d3d10_effect_scalar_variable_AsDepthStencil, + d3d10_effect_scalar_variable_AsRasterizer, + d3d10_effect_scalar_variable_AsSampler, + d3d10_effect_scalar_variable_SetRawValue, + d3d10_effect_scalar_variable_GetRawValue, + /* ID3D10EffectScalarVariable methods */ + d3d10_effect_scalar_variable_SetFloat, + d3d10_effect_scalar_variable_GetFloat, + d3d10_effect_scalar_variable_SetFloatArray, + d3d10_effect_scalar_variable_GetFloatArray, + d3d10_effect_scalar_variable_SetInt, + d3d10_effect_scalar_variable_GetInt, + d3d10_effect_scalar_variable_SetIntArray, + d3d10_effect_scalar_variable_GetIntArray, + d3d10_effect_scalar_variable_SetBool, + d3d10_effect_scalar_variable_GetBool, + d3d10_effect_scalar_variable_SetBoolArray, + d3d10_effect_scalar_variable_GetBoolArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_vector_variable_IsValid(ID3D10EffectVectorVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_vector_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetType( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetDesc(ID3D10EffectVectorVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetAnnotationByIndex( + ID3D10EffectVectorVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetAnnotationByName( + ID3D10EffectVectorVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetMemberByIndex( + ID3D10EffectVectorVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetMemberByName( + ID3D10EffectVectorVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetMemberBySemantic( + ID3D10EffectVectorVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetElement( + ID3D10EffectVectorVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_vector_variable_GetParentConstantBuffer( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsScalar( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsVector( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsMatrix( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsString( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsShaderResource( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsRenderTargetView( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsDepthStencilView( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsConstantBuffer( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsShader( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsBlend( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsDepthStencil( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsRasterizer( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_vector_variable_AsSampler( + ID3D10EffectVectorVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetRawValue(ID3D10EffectVectorVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetRawValue(ID3D10EffectVectorVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectVectorVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetBoolVector(ID3D10EffectVectorVariable *iface, + BOOL *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetIntVector(ID3D10EffectVectorVariable *iface, + int *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetFloatVector(ID3D10EffectVectorVariable *iface, + float *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetBoolVector(ID3D10EffectVectorVariable *iface, + BOOL *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetIntVector(ID3D10EffectVectorVariable *iface, + int *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetFloatVector(ID3D10EffectVectorVariable *iface, + float *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetBoolVectorArray(ID3D10EffectVectorVariable *iface, + BOOL *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetIntVectorArray(ID3D10EffectVectorVariable *iface, + int *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetFloatVectorArray(ID3D10EffectVectorVariable *iface, + float *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetBoolVectorArray(ID3D10EffectVectorVariable *iface, + BOOL *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetIntVectorArray(ID3D10EffectVectorVariable *iface, + int *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetFloatVectorArray(ID3D10EffectVectorVariable *iface, + float *values, UINT offset, UINT count) +{ + FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + + return E_NOTIMPL; +} + +static const struct ID3D10EffectVectorVariableVtbl d3d10_effect_vector_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_vector_variable_IsValid, + d3d10_effect_vector_variable_GetType, + d3d10_effect_vector_variable_GetDesc, + d3d10_effect_vector_variable_GetAnnotationByIndex, + d3d10_effect_vector_variable_GetAnnotationByName, + d3d10_effect_vector_variable_GetMemberByIndex, + d3d10_effect_vector_variable_GetMemberByName, + d3d10_effect_vector_variable_GetMemberBySemantic, + d3d10_effect_vector_variable_GetElement, + d3d10_effect_vector_variable_GetParentConstantBuffer, + d3d10_effect_vector_variable_AsScalar, + d3d10_effect_vector_variable_AsVector, + d3d10_effect_vector_variable_AsMatrix, + d3d10_effect_vector_variable_AsString, + d3d10_effect_vector_variable_AsShaderResource, + d3d10_effect_vector_variable_AsRenderTargetView, + d3d10_effect_vector_variable_AsDepthStencilView, + d3d10_effect_vector_variable_AsConstantBuffer, + d3d10_effect_vector_variable_AsShader, + d3d10_effect_vector_variable_AsBlend, + d3d10_effect_vector_variable_AsDepthStencil, + d3d10_effect_vector_variable_AsRasterizer, + d3d10_effect_vector_variable_AsSampler, + d3d10_effect_vector_variable_SetRawValue, + d3d10_effect_vector_variable_GetRawValue, + /* ID3D10EffectVectorVariable methods */ + d3d10_effect_vector_variable_SetBoolVector, + d3d10_effect_vector_variable_SetIntVector, + d3d10_effect_vector_variable_SetFloatVector, + d3d10_effect_vector_variable_GetBoolVector, + d3d10_effect_vector_variable_GetIntVector, + d3d10_effect_vector_variable_GetFloatVector, + d3d10_effect_vector_variable_SetBoolVectorArray, + d3d10_effect_vector_variable_SetIntVectorArray, + d3d10_effect_vector_variable_SetFloatVectorArray, + d3d10_effect_vector_variable_GetBoolVectorArray, + d3d10_effect_vector_variable_GetIntVectorArray, + d3d10_effect_vector_variable_GetFloatVectorArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_matrix_variable_IsValid(ID3D10EffectMatrixVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_matrix_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetType( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetDesc(ID3D10EffectMatrixVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetAnnotationByIndex( + ID3D10EffectMatrixVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetAnnotationByName( + ID3D10EffectMatrixVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMemberByIndex( + ID3D10EffectMatrixVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMemberByName( + ID3D10EffectMatrixVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMemberBySemantic( + ID3D10EffectMatrixVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetElement( + ID3D10EffectMatrixVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetParentConstantBuffer( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsScalar( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsVector( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsMatrix( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsString( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsShaderResource( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsRenderTargetView( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsDepthStencilView( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsConstantBuffer( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsShader( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsBlend( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsDepthStencil( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsRasterizer( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_matrix_variable_AsSampler( + ID3D10EffectMatrixVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetRawValue(ID3D10EffectMatrixVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetRawValue(ID3D10EffectMatrixVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectMatrixVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrix(ID3D10EffectMatrixVariable *iface, + float *data) +{ + FIXME("iface %p, data %p stub!\n", iface, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrix(ID3D10EffectMatrixVariable *iface, + float *data) +{ + FIXME("iface %p, data %p stub!\n", iface, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixArray(ID3D10EffectMatrixVariable *iface, + float *data, UINT offset, UINT count) +{ + FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixArray(ID3D10EffectMatrixVariable *iface, + float *data, UINT offset, UINT count) +{ + FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTranspose(ID3D10EffectMatrixVariable *iface, + float *data) +{ + FIXME("iface %p, data %p stub!\n", iface, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTranspose(ID3D10EffectMatrixVariable *iface, + float *data) +{ + FIXME("iface %p, data %p stub!\n", iface, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface, + float *data, UINT offset, UINT count) +{ + FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface, + float *data, UINT offset, UINT count) +{ + FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + + return E_NOTIMPL; +} + + +static const struct ID3D10EffectMatrixVariableVtbl d3d10_effect_matrix_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_matrix_variable_IsValid, + d3d10_effect_matrix_variable_GetType, + d3d10_effect_matrix_variable_GetDesc, + d3d10_effect_matrix_variable_GetAnnotationByIndex, + d3d10_effect_matrix_variable_GetAnnotationByName, + d3d10_effect_matrix_variable_GetMemberByIndex, + d3d10_effect_matrix_variable_GetMemberByName, + d3d10_effect_matrix_variable_GetMemberBySemantic, + d3d10_effect_matrix_variable_GetElement, + d3d10_effect_matrix_variable_GetParentConstantBuffer, + d3d10_effect_matrix_variable_AsScalar, + d3d10_effect_matrix_variable_AsVector, + d3d10_effect_matrix_variable_AsMatrix, + d3d10_effect_matrix_variable_AsString, + d3d10_effect_matrix_variable_AsShaderResource, + d3d10_effect_matrix_variable_AsRenderTargetView, + d3d10_effect_matrix_variable_AsDepthStencilView, + d3d10_effect_matrix_variable_AsConstantBuffer, + d3d10_effect_matrix_variable_AsShader, + d3d10_effect_matrix_variable_AsBlend, + d3d10_effect_matrix_variable_AsDepthStencil, + d3d10_effect_matrix_variable_AsRasterizer, + d3d10_effect_matrix_variable_AsSampler, + d3d10_effect_matrix_variable_SetRawValue, + d3d10_effect_matrix_variable_GetRawValue, + /* ID3D10EffectMatrixVariable methods */ + d3d10_effect_matrix_variable_SetMatrix, + d3d10_effect_matrix_variable_GetMatrix, + d3d10_effect_matrix_variable_SetMatrixArray, + d3d10_effect_matrix_variable_GetMatrixArray, + d3d10_effect_matrix_variable_SetMatrixTranspose, + d3d10_effect_matrix_variable_GetMatrixTranspose, + d3d10_effect_matrix_variable_SetMatrixTransposeArray, + d3d10_effect_matrix_variable_GetMatrixTransposeArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_string_variable_IsValid(ID3D10EffectStringVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_string_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_string_variable_GetType( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_string_variable_GetDesc(ID3D10EffectStringVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_GetAnnotationByIndex( + ID3D10EffectStringVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_GetAnnotationByName( + ID3D10EffectStringVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_GetMemberByIndex( + ID3D10EffectStringVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_GetMemberByName( + ID3D10EffectStringVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_GetMemberBySemantic( + ID3D10EffectStringVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_GetElement( + ID3D10EffectStringVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_string_variable_GetParentConstantBuffer( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsScalar( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsVector( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsMatrix( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsString( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsShaderResource( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsRenderTargetView( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsDepthStencilView( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_string_variable_AsConstantBuffer( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsShader( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsBlend( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsDepthStencil( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsRasterizer( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_string_variable_AsSampler( + ID3D10EffectStringVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_string_variable_SetRawValue(ID3D10EffectStringVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_string_variable_GetRawValue(ID3D10EffectStringVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectStringVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_string_variable_GetString(ID3D10EffectStringVariable *iface, + const char **str) +{ + FIXME("iface %p, str %p stub!\n", iface, str); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_string_variable_GetStringArray(ID3D10EffectStringVariable *iface, + const char **strs, UINT offset, UINT count) +{ + FIXME("iface %p, strs %p, offset %u, count %u stub!\n", iface, strs, offset, count); + + return E_NOTIMPL; +} + + +static const struct ID3D10EffectStringVariableVtbl d3d10_effect_string_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_string_variable_IsValid, + d3d10_effect_string_variable_GetType, + d3d10_effect_string_variable_GetDesc, + d3d10_effect_string_variable_GetAnnotationByIndex, + d3d10_effect_string_variable_GetAnnotationByName, + d3d10_effect_string_variable_GetMemberByIndex, + d3d10_effect_string_variable_GetMemberByName, + d3d10_effect_string_variable_GetMemberBySemantic, + d3d10_effect_string_variable_GetElement, + d3d10_effect_string_variable_GetParentConstantBuffer, + d3d10_effect_string_variable_AsScalar, + d3d10_effect_string_variable_AsVector, + d3d10_effect_string_variable_AsMatrix, + d3d10_effect_string_variable_AsString, + d3d10_effect_string_variable_AsShaderResource, + d3d10_effect_string_variable_AsRenderTargetView, + d3d10_effect_string_variable_AsDepthStencilView, + d3d10_effect_string_variable_AsConstantBuffer, + d3d10_effect_string_variable_AsShader, + d3d10_effect_string_variable_AsBlend, + d3d10_effect_string_variable_AsDepthStencil, + d3d10_effect_string_variable_AsRasterizer, + d3d10_effect_string_variable_AsSampler, + d3d10_effect_string_variable_SetRawValue, + d3d10_effect_string_variable_GetRawValue, + /* ID3D10EffectStringVariable methods */ + d3d10_effect_string_variable_GetString, + d3d10_effect_string_variable_GetStringArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_IsValid(ID3D10EffectShaderResourceVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_shader_resource_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetType( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetDesc( + ID3D10EffectShaderResourceVariable *iface, D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetAnnotationByIndex( + ID3D10EffectShaderResourceVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetAnnotationByName( + ID3D10EffectShaderResourceVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetMemberByIndex( + ID3D10EffectShaderResourceVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetMemberByName( + ID3D10EffectShaderResourceVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetMemberBySemantic( + ID3D10EffectShaderResourceVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetElement( + ID3D10EffectShaderResourceVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetParentConstantBuffer( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsScalar( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsVector( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsMatrix( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsString( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsShaderResource( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsRenderTargetView( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsDepthStencilView( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsConstantBuffer( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsShader( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsBlend( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsDepthStencil( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsRasterizer( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_AsSampler( + ID3D10EffectShaderResourceVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetRawValue( + ID3D10EffectShaderResourceVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetRawValue( + ID3D10EffectShaderResourceVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectShaderResourceVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetResource( + ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView *resource) +{ + FIXME("iface %p, resource %p stub!\n", iface, resource); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResource( + ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView **resource) +{ + FIXME("iface %p, resource %p stub!\n", iface, resource); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_SetResourceArray( + ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView **resources, UINT offset, UINT count) +{ + FIXME("iface %p, resources %p, offset %u, count %u stub!\n", iface, resources, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_resource_variable_GetResourceArray( + ID3D10EffectShaderResourceVariable *iface, ID3D10ShaderResourceView **resources, UINT offset, UINT count) +{ + FIXME("iface %p, resources %p, offset %u, count %u stub!\n", iface, resources, offset, count); + + return E_NOTIMPL; +} + + +static const struct ID3D10EffectShaderResourceVariableVtbl d3d10_effect_shader_resource_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_shader_resource_variable_IsValid, + d3d10_effect_shader_resource_variable_GetType, + d3d10_effect_shader_resource_variable_GetDesc, + d3d10_effect_shader_resource_variable_GetAnnotationByIndex, + d3d10_effect_shader_resource_variable_GetAnnotationByName, + d3d10_effect_shader_resource_variable_GetMemberByIndex, + d3d10_effect_shader_resource_variable_GetMemberByName, + d3d10_effect_shader_resource_variable_GetMemberBySemantic, + d3d10_effect_shader_resource_variable_GetElement, + d3d10_effect_shader_resource_variable_GetParentConstantBuffer, + d3d10_effect_shader_resource_variable_AsScalar, + d3d10_effect_shader_resource_variable_AsVector, + d3d10_effect_shader_resource_variable_AsMatrix, + d3d10_effect_shader_resource_variable_AsString, + d3d10_effect_shader_resource_variable_AsShaderResource, + d3d10_effect_shader_resource_variable_AsRenderTargetView, + d3d10_effect_shader_resource_variable_AsDepthStencilView, + d3d10_effect_shader_resource_variable_AsConstantBuffer, + d3d10_effect_shader_resource_variable_AsShader, + d3d10_effect_shader_resource_variable_AsBlend, + d3d10_effect_shader_resource_variable_AsDepthStencil, + d3d10_effect_shader_resource_variable_AsRasterizer, + d3d10_effect_shader_resource_variable_AsSampler, + d3d10_effect_shader_resource_variable_SetRawValue, + d3d10_effect_shader_resource_variable_GetRawValue, + /* ID3D10EffectShaderResourceVariable methods */ + d3d10_effect_shader_resource_variable_SetResource, + d3d10_effect_shader_resource_variable_GetResource, + d3d10_effect_shader_resource_variable_SetResourceArray, + d3d10_effect_shader_resource_variable_GetResourceArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_IsValid( + ID3D10EffectRenderTargetViewVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_render_target_view_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetType( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetDesc( + ID3D10EffectRenderTargetViewVariable *iface, D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetAnnotationByIndex( + ID3D10EffectRenderTargetViewVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetAnnotationByName( + ID3D10EffectRenderTargetViewVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetMemberByIndex( + ID3D10EffectRenderTargetViewVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetMemberByName( + ID3D10EffectRenderTargetViewVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetMemberBySemantic( + ID3D10EffectRenderTargetViewVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetElement( + ID3D10EffectRenderTargetViewVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetParentConstantBuffer( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsScalar( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsVector( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsMatrix( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsString( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsShaderResource( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsRenderTargetView( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsDepthStencilView( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsConstantBuffer( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsShader( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsBlend( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsDepthStencil( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsRasterizer( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_AsSampler( + ID3D10EffectRenderTargetViewVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_SetRawValue( + ID3D10EffectRenderTargetViewVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetRawValue( + ID3D10EffectRenderTargetViewVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectRenderTargetViewVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_SetRenderTarget( + ID3D10EffectRenderTargetViewVariable *iface, ID3D10RenderTargetView *view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetRenderTarget( + ID3D10EffectRenderTargetViewVariable *iface, ID3D10RenderTargetView **view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_SetRenderTargetArray( + ID3D10EffectRenderTargetViewVariable *iface, ID3D10RenderTargetView **views, UINT offset, UINT count) +{ + FIXME("iface %p, views %p, offset %u, count %u stub!\n", iface, views, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_render_target_view_variable_GetRenderTargetArray( + ID3D10EffectRenderTargetViewVariable *iface, ID3D10RenderTargetView **views, UINT offset, UINT count) +{ + FIXME("iface %p, views %p, offset %u, count %u stub!\n", iface, views, offset, count); + + return E_NOTIMPL; +} + + +static const struct ID3D10EffectRenderTargetViewVariableVtbl d3d10_effect_render_target_view_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_render_target_view_variable_IsValid, + d3d10_effect_render_target_view_variable_GetType, + d3d10_effect_render_target_view_variable_GetDesc, + d3d10_effect_render_target_view_variable_GetAnnotationByIndex, + d3d10_effect_render_target_view_variable_GetAnnotationByName, + d3d10_effect_render_target_view_variable_GetMemberByIndex, + d3d10_effect_render_target_view_variable_GetMemberByName, + d3d10_effect_render_target_view_variable_GetMemberBySemantic, + d3d10_effect_render_target_view_variable_GetElement, + d3d10_effect_render_target_view_variable_GetParentConstantBuffer, + d3d10_effect_render_target_view_variable_AsScalar, + d3d10_effect_render_target_view_variable_AsVector, + d3d10_effect_render_target_view_variable_AsMatrix, + d3d10_effect_render_target_view_variable_AsString, + d3d10_effect_render_target_view_variable_AsShaderResource, + d3d10_effect_render_target_view_variable_AsRenderTargetView, + d3d10_effect_render_target_view_variable_AsDepthStencilView, + d3d10_effect_render_target_view_variable_AsConstantBuffer, + d3d10_effect_render_target_view_variable_AsShader, + d3d10_effect_render_target_view_variable_AsBlend, + d3d10_effect_render_target_view_variable_AsDepthStencil, + d3d10_effect_render_target_view_variable_AsRasterizer, + d3d10_effect_render_target_view_variable_AsSampler, + d3d10_effect_render_target_view_variable_SetRawValue, + d3d10_effect_render_target_view_variable_GetRawValue, + /* ID3D10EffectRenderTargetViewVariable methods */ + d3d10_effect_render_target_view_variable_SetRenderTarget, + d3d10_effect_render_target_view_variable_GetRenderTarget, + d3d10_effect_render_target_view_variable_SetRenderTargetArray, + d3d10_effect_render_target_view_variable_GetRenderTargetArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_IsValid( + ID3D10EffectDepthStencilViewVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_depth_stencil_view_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetType( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetDesc( + ID3D10EffectDepthStencilViewVariable *iface, D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetAnnotationByIndex( + ID3D10EffectDepthStencilViewVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetAnnotationByName( + ID3D10EffectDepthStencilViewVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetMemberByIndex( + ID3D10EffectDepthStencilViewVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetMemberByName( + ID3D10EffectDepthStencilViewVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetMemberBySemantic( + ID3D10EffectDepthStencilViewVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetElement( + ID3D10EffectDepthStencilViewVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetParentConstantBuffer( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsScalar( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsVector( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsMatrix( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsString( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsShaderResource( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsRenderTargetView( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsDepthStencilView( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsConstantBuffer( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsShader( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsBlend( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsDepthStencil( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsRasterizer( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_AsSampler( + ID3D10EffectDepthStencilViewVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_SetRawValue( + ID3D10EffectDepthStencilViewVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetRawValue( + ID3D10EffectDepthStencilViewVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectDepthStencilViewVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_SetDepthStencil( + ID3D10EffectDepthStencilViewVariable *iface, ID3D10DepthStencilView *view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetDepthStencil( + ID3D10EffectDepthStencilViewVariable *iface, ID3D10DepthStencilView **view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_SetDepthStencilArray( + ID3D10EffectDepthStencilViewVariable *iface, ID3D10DepthStencilView **views, UINT offset, UINT count) +{ + FIXME("iface %p, views %p, offset %u, count %u stub!\n", iface, views, offset, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_view_variable_GetDepthStencilArray( + ID3D10EffectDepthStencilViewVariable *iface, ID3D10DepthStencilView **views, UINT offset, UINT count) +{ + FIXME("iface %p, views %p, offset %u, count %u stub!\n", iface, views, offset, count); + + return E_NOTIMPL; +} + + +static const struct ID3D10EffectDepthStencilViewVariableVtbl d3d10_effect_depth_stencil_view_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_depth_stencil_view_variable_IsValid, + d3d10_effect_depth_stencil_view_variable_GetType, + d3d10_effect_depth_stencil_view_variable_GetDesc, + d3d10_effect_depth_stencil_view_variable_GetAnnotationByIndex, + d3d10_effect_depth_stencil_view_variable_GetAnnotationByName, + d3d10_effect_depth_stencil_view_variable_GetMemberByIndex, + d3d10_effect_depth_stencil_view_variable_GetMemberByName, + d3d10_effect_depth_stencil_view_variable_GetMemberBySemantic, + d3d10_effect_depth_stencil_view_variable_GetElement, + d3d10_effect_depth_stencil_view_variable_GetParentConstantBuffer, + d3d10_effect_depth_stencil_view_variable_AsScalar, + d3d10_effect_depth_stencil_view_variable_AsVector, + d3d10_effect_depth_stencil_view_variable_AsMatrix, + d3d10_effect_depth_stencil_view_variable_AsString, + d3d10_effect_depth_stencil_view_variable_AsShaderResource, + d3d10_effect_depth_stencil_view_variable_AsRenderTargetView, + d3d10_effect_depth_stencil_view_variable_AsDepthStencilView, + d3d10_effect_depth_stencil_view_variable_AsConstantBuffer, + d3d10_effect_depth_stencil_view_variable_AsShader, + d3d10_effect_depth_stencil_view_variable_AsBlend, + d3d10_effect_depth_stencil_view_variable_AsDepthStencil, + d3d10_effect_depth_stencil_view_variable_AsRasterizer, + d3d10_effect_depth_stencil_view_variable_AsSampler, + d3d10_effect_depth_stencil_view_variable_SetRawValue, + d3d10_effect_depth_stencil_view_variable_GetRawValue, + /* ID3D10EffectDepthStencilViewVariable methods */ + d3d10_effect_depth_stencil_view_variable_SetDepthStencil, + d3d10_effect_depth_stencil_view_variable_GetDepthStencil, + d3d10_effect_depth_stencil_view_variable_SetDepthStencilArray, + d3d10_effect_depth_stencil_view_variable_GetDepthStencilArray, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_shader_variable_IsValid(ID3D10EffectShaderVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_shader_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetType( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetDesc(ID3D10EffectShaderVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetAnnotationByIndex( + ID3D10EffectShaderVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetAnnotationByName( + ID3D10EffectShaderVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetMemberByIndex( + ID3D10EffectShaderVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetMemberByName( + ID3D10EffectShaderVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetMemberBySemantic( + ID3D10EffectShaderVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetElement( + ID3D10EffectShaderVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_shader_variable_GetParentConstantBuffer( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsScalar( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsVector( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsMatrix( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsString( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsShaderResource( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsRenderTargetView( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsDepthStencilView( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsConstantBuffer( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsShader( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsBlend( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsDepthStencil( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsRasterizer( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_shader_variable_AsSampler( + ID3D10EffectShaderVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_SetRawValue( + ID3D10EffectShaderVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetRawValue( + ID3D10EffectShaderVariable *iface, void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectShaderVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetShaderDesc( + ID3D10EffectShaderVariable *iface, UINT index, D3D10_EFFECT_SHADER_DESC *desc) +{ + FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetVertexShader( + ID3D10EffectShaderVariable *iface, UINT index, ID3D10VertexShader **shader) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, shader %p.\n", iface, index, shader); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_VERTEXSHADER) + { + WARN("Shader is not a vertex shader.\n"); + return E_FAIL; + } + + if ((*shader = v->u.shader.shader.vs)) + ID3D10VertexShader_AddRef(*shader); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetGeometryShader( + ID3D10EffectShaderVariable *iface, UINT index, ID3D10GeometryShader **shader) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, shader %p.\n", iface, index, shader); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_GEOMETRYSHADER) + { + WARN("Shader is not a geometry shader.\n"); + return E_FAIL; + } + + if ((*shader = v->u.shader.shader.gs)) + ID3D10GeometryShader_AddRef(*shader); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetPixelShader( + ID3D10EffectShaderVariable *iface, UINT index, ID3D10PixelShader **shader) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, shader %p.\n", iface, index, shader); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_PIXELSHADER) + { + WARN("Shader is not a pixel shader.\n"); + return E_FAIL; + } + + if ((*shader = v->u.shader.shader.ps)) + ID3D10PixelShader_AddRef(*shader); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetInputSignatureElementDesc( + ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index, + D3D10_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3d10_effect_variable *This = (struct d3d10_effect_variable *)iface; + struct d3d10_effect_shader_variable *s; + D3D10_SIGNATURE_PARAMETER_DESC *d; + + TRACE("iface %p, shader_index %u, element_index %u, desc %p\n", + iface, shader_index, element_index, desc); + + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Null variable specified\n"); + return E_FAIL; + } + + /* Check shader_index, this crashes on W7/DX10 */ + if (shader_index >= This->effect->used_shader_count) + { + WARN("This should crash on W7/DX10!\n"); + return E_FAIL; + } + + s = &This->effect->used_shaders[shader_index]->u.shader; + if (!s->input_signature.signature) + { + WARN("No shader signature\n"); + return D3DERR_INVALIDCALL; + } + + /* Check desc for NULL, this crashes on W7/DX10 */ + if (!desc) + { + WARN("This should crash on W7/DX10!\n"); + return E_FAIL; + } + + if (element_index >= s->input_signature.element_count) + { + WARN("Invalid element index specified\n"); + return E_INVALIDARG; + } + + d = &s->input_signature.elements[element_index]; + desc->SemanticName = d->SemanticName; + desc->SemanticIndex = d->SemanticIndex; + desc->SystemValueType = d->SystemValueType; + desc->ComponentType = d->ComponentType; + desc->Register = d->Register; + desc->ReadWriteMask = d->ReadWriteMask; + desc->Mask = d->Mask; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignatureElementDesc( + ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index, + D3D10_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3d10_effect_variable *This = (struct d3d10_effect_variable *)iface; + struct d3d10_effect_shader_variable *s; + D3D10_SIGNATURE_PARAMETER_DESC *d; + + TRACE("iface %p, shader_index %u, element_index %u, desc %p\n", + iface, shader_index, element_index, desc); + + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Null variable specified\n"); + return E_FAIL; + } + + /* Check shader_index, this crashes on W7/DX10 */ + if (shader_index >= This->effect->used_shader_count) + { + WARN("This should crash on W7/DX10!\n"); + return E_FAIL; + } + + s = &This->effect->used_shaders[shader_index]->u.shader; + if (!s->output_signature.signature) + { + WARN("No shader signature\n"); + return D3DERR_INVALIDCALL; + } + + /* Check desc for NULL, this crashes on W7/DX10 */ + if (!desc) + { + WARN("This should crash on W7/DX10!\n"); + return E_FAIL; + } + + if (element_index >= s->output_signature.element_count) + { + WARN("Invalid element index specified\n"); + return E_INVALIDARG; + } + + d = &s->output_signature.elements[element_index]; + desc->SemanticName = d->SemanticName; + desc->SemanticIndex = d->SemanticIndex; + desc->SystemValueType = d->SystemValueType; + desc->ComponentType = d->ComponentType; + desc->Register = d->Register; + desc->ReadWriteMask = d->ReadWriteMask; + desc->Mask = d->Mask; + + return S_OK; +} + + +static const struct ID3D10EffectShaderVariableVtbl d3d10_effect_shader_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_shader_variable_IsValid, + d3d10_effect_shader_variable_GetType, + d3d10_effect_shader_variable_GetDesc, + d3d10_effect_shader_variable_GetAnnotationByIndex, + d3d10_effect_shader_variable_GetAnnotationByName, + d3d10_effect_shader_variable_GetMemberByIndex, + d3d10_effect_shader_variable_GetMemberByName, + d3d10_effect_shader_variable_GetMemberBySemantic, + d3d10_effect_shader_variable_GetElement, + d3d10_effect_shader_variable_GetParentConstantBuffer, + d3d10_effect_shader_variable_AsScalar, + d3d10_effect_shader_variable_AsVector, + d3d10_effect_shader_variable_AsMatrix, + d3d10_effect_shader_variable_AsString, + d3d10_effect_shader_variable_AsShaderResource, + d3d10_effect_shader_variable_AsRenderTargetView, + d3d10_effect_shader_variable_AsDepthStencilView, + d3d10_effect_shader_variable_AsConstantBuffer, + d3d10_effect_shader_variable_AsShader, + d3d10_effect_shader_variable_AsBlend, + d3d10_effect_shader_variable_AsDepthStencil, + d3d10_effect_shader_variable_AsRasterizer, + d3d10_effect_shader_variable_AsSampler, + d3d10_effect_shader_variable_SetRawValue, + d3d10_effect_shader_variable_GetRawValue, + /* ID3D10EffectShaderVariable methods */ + d3d10_effect_shader_variable_GetShaderDesc, + d3d10_effect_shader_variable_GetVertexShader, + d3d10_effect_shader_variable_GetGeometryShader, + d3d10_effect_shader_variable_GetPixelShader, + d3d10_effect_shader_variable_GetInputSignatureElementDesc, + d3d10_effect_shader_variable_GetOutputSignatureElementDesc, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_blend_variable_IsValid(ID3D10EffectBlendVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_blend_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetType( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_blend_variable_GetDesc(ID3D10EffectBlendVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetAnnotationByIndex( + ID3D10EffectBlendVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetAnnotationByName( + ID3D10EffectBlendVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetMemberByIndex( + ID3D10EffectBlendVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetMemberByName( + ID3D10EffectBlendVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetMemberBySemantic( + ID3D10EffectBlendVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetElement( + ID3D10EffectBlendVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_blend_variable_GetParentConstantBuffer( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsScalar( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsVector( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsMatrix( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsString( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsShaderResource( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsRenderTargetView( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsDepthStencilView( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsConstantBuffer( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsShader( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsBlend( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsDepthStencil( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsRasterizer( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_blend_variable_AsSampler( + ID3D10EffectBlendVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_blend_variable_SetRawValue(ID3D10EffectBlendVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_blend_variable_GetRawValue(ID3D10EffectBlendVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectBlendVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_blend_variable_GetBlendState(ID3D10EffectBlendVariable *iface, + UINT index, ID3D10BlendState **blend_state) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, blend_state %p.\n", iface, index, blend_state); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + else if (index) + return E_FAIL; + + if (v->type->basetype != D3D10_SVT_BLEND) + { + WARN("Variable is not a blend state.\n"); + return E_FAIL; + } + + if ((*blend_state = v->u.state.object.blend)) + ID3D10BlendState_AddRef(*blend_state); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_blend_variable_GetBackingStore(ID3D10EffectBlendVariable *iface, + UINT index, D3D10_BLEND_DESC *desc) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_BLEND) + { + WARN("Variable is not a blend state.\n"); + return E_FAIL; + } + + *desc = v->u.state.desc.blend; + + return S_OK; +} + + +static const struct ID3D10EffectBlendVariableVtbl d3d10_effect_blend_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_blend_variable_IsValid, + d3d10_effect_blend_variable_GetType, + d3d10_effect_blend_variable_GetDesc, + d3d10_effect_blend_variable_GetAnnotationByIndex, + d3d10_effect_blend_variable_GetAnnotationByName, + d3d10_effect_blend_variable_GetMemberByIndex, + d3d10_effect_blend_variable_GetMemberByName, + d3d10_effect_blend_variable_GetMemberBySemantic, + d3d10_effect_blend_variable_GetElement, + d3d10_effect_blend_variable_GetParentConstantBuffer, + d3d10_effect_blend_variable_AsScalar, + d3d10_effect_blend_variable_AsVector, + d3d10_effect_blend_variable_AsMatrix, + d3d10_effect_blend_variable_AsString, + d3d10_effect_blend_variable_AsShaderResource, + d3d10_effect_blend_variable_AsRenderTargetView, + d3d10_effect_blend_variable_AsDepthStencilView, + d3d10_effect_blend_variable_AsConstantBuffer, + d3d10_effect_blend_variable_AsShader, + d3d10_effect_blend_variable_AsBlend, + d3d10_effect_blend_variable_AsDepthStencil, + d3d10_effect_blend_variable_AsRasterizer, + d3d10_effect_blend_variable_AsSampler, + d3d10_effect_blend_variable_SetRawValue, + d3d10_effect_blend_variable_GetRawValue, + /* ID3D10EffectBlendVariable methods */ + d3d10_effect_blend_variable_GetBlendState, + d3d10_effect_blend_variable_GetBackingStore, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_IsValid(ID3D10EffectDepthStencilVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_depth_stencil_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetType( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetDesc(ID3D10EffectDepthStencilVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetAnnotationByIndex( + ID3D10EffectDepthStencilVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetAnnotationByName( + ID3D10EffectDepthStencilVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetMemberByIndex( + ID3D10EffectDepthStencilVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetMemberByName( + ID3D10EffectDepthStencilVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetMemberBySemantic( + ID3D10EffectDepthStencilVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetElement( + ID3D10EffectDepthStencilVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetParentConstantBuffer( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsScalar( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsVector( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsMatrix( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsString( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsShaderResource( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsRenderTargetView( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsDepthStencilView( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsConstantBuffer( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsShader( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsBlend( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsDepthStencil( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsRasterizer( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_AsSampler( + ID3D10EffectDepthStencilVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_SetRawValue(ID3D10EffectDepthStencilVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetRawValue(ID3D10EffectDepthStencilVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectDepthStencilVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetDepthStencilState(ID3D10EffectDepthStencilVariable *iface, + UINT index, ID3D10DepthStencilState **depth_stencil_state) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, depth_stencil_state %p.\n", iface, index, depth_stencil_state); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + else if (index) + return E_FAIL; + + if (v->type->basetype != D3D10_SVT_DEPTHSTENCIL) + { + WARN("Variable is not a depth stencil state.\n"); + return E_FAIL; + } + + if ((*depth_stencil_state = v->u.state.object.depth_stencil)) + ID3D10DepthStencilState_AddRef(*depth_stencil_state); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_depth_stencil_variable_GetBackingStore(ID3D10EffectDepthStencilVariable *iface, + UINT index, D3D10_DEPTH_STENCIL_DESC *desc) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_DEPTHSTENCIL) + { + WARN("Variable is not a depth stencil state.\n"); + return E_FAIL; + } + + *desc = v->u.state.desc.depth_stencil; + + return S_OK; +} + + +static const struct ID3D10EffectDepthStencilVariableVtbl d3d10_effect_depth_stencil_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_depth_stencil_variable_IsValid, + d3d10_effect_depth_stencil_variable_GetType, + d3d10_effect_depth_stencil_variable_GetDesc, + d3d10_effect_depth_stencil_variable_GetAnnotationByIndex, + d3d10_effect_depth_stencil_variable_GetAnnotationByName, + d3d10_effect_depth_stencil_variable_GetMemberByIndex, + d3d10_effect_depth_stencil_variable_GetMemberByName, + d3d10_effect_depth_stencil_variable_GetMemberBySemantic, + d3d10_effect_depth_stencil_variable_GetElement, + d3d10_effect_depth_stencil_variable_GetParentConstantBuffer, + d3d10_effect_depth_stencil_variable_AsScalar, + d3d10_effect_depth_stencil_variable_AsVector, + d3d10_effect_depth_stencil_variable_AsMatrix, + d3d10_effect_depth_stencil_variable_AsString, + d3d10_effect_depth_stencil_variable_AsShaderResource, + d3d10_effect_depth_stencil_variable_AsRenderTargetView, + d3d10_effect_depth_stencil_variable_AsDepthStencilView, + d3d10_effect_depth_stencil_variable_AsConstantBuffer, + d3d10_effect_depth_stencil_variable_AsShader, + d3d10_effect_depth_stencil_variable_AsBlend, + d3d10_effect_depth_stencil_variable_AsDepthStencil, + d3d10_effect_depth_stencil_variable_AsRasterizer, + d3d10_effect_depth_stencil_variable_AsSampler, + d3d10_effect_depth_stencil_variable_SetRawValue, + d3d10_effect_depth_stencil_variable_GetRawValue, + /* ID3D10EffectDepthStencilVariable methods */ + d3d10_effect_depth_stencil_variable_GetDepthStencilState, + d3d10_effect_depth_stencil_variable_GetBackingStore, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_IsValid(ID3D10EffectRasterizerVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_rasterizer_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetType( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetDesc(ID3D10EffectRasterizerVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetAnnotationByIndex( + ID3D10EffectRasterizerVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetAnnotationByName( + ID3D10EffectRasterizerVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetMemberByIndex( + ID3D10EffectRasterizerVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetMemberByName( + ID3D10EffectRasterizerVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetMemberBySemantic( + ID3D10EffectRasterizerVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetElement( + ID3D10EffectRasterizerVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetParentConstantBuffer( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsScalar( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsVector( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsMatrix( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsString( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsShaderResource( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsRenderTargetView( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsDepthStencilView( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsConstantBuffer( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsShader( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsBlend( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsDepthStencil( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsRasterizer( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_AsSampler( + ID3D10EffectRasterizerVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_SetRawValue(ID3D10EffectRasterizerVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetRawValue(ID3D10EffectRasterizerVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectRasterizerVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetRasterizerState(ID3D10EffectRasterizerVariable *iface, + UINT index, ID3D10RasterizerState **rasterizer_state) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, rasterizer_state %p.\n", iface, index, rasterizer_state); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + else if (index) + return E_FAIL; + + if (v->type->basetype != D3D10_SVT_RASTERIZER) + { + WARN("Variable is not a rasterizer state.\n"); + return E_FAIL; + } + + if ((*rasterizer_state = v->u.state.object.rasterizer)) + ID3D10RasterizerState_AddRef(*rasterizer_state); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_rasterizer_variable_GetBackingStore(ID3D10EffectRasterizerVariable *iface, + UINT index, D3D10_RASTERIZER_DESC *desc) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_RASTERIZER) + { + WARN("Variable is not a rasterizer state.\n"); + return E_FAIL; + } + + *desc = v->u.state.desc.rasterizer; + + return S_OK; +} + + +static const struct ID3D10EffectRasterizerVariableVtbl d3d10_effect_rasterizer_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_rasterizer_variable_IsValid, + d3d10_effect_rasterizer_variable_GetType, + d3d10_effect_rasterizer_variable_GetDesc, + d3d10_effect_rasterizer_variable_GetAnnotationByIndex, + d3d10_effect_rasterizer_variable_GetAnnotationByName, + d3d10_effect_rasterizer_variable_GetMemberByIndex, + d3d10_effect_rasterizer_variable_GetMemberByName, + d3d10_effect_rasterizer_variable_GetMemberBySemantic, + d3d10_effect_rasterizer_variable_GetElement, + d3d10_effect_rasterizer_variable_GetParentConstantBuffer, + d3d10_effect_rasterizer_variable_AsScalar, + d3d10_effect_rasterizer_variable_AsVector, + d3d10_effect_rasterizer_variable_AsMatrix, + d3d10_effect_rasterizer_variable_AsString, + d3d10_effect_rasterizer_variable_AsShaderResource, + d3d10_effect_rasterizer_variable_AsRenderTargetView, + d3d10_effect_rasterizer_variable_AsDepthStencilView, + d3d10_effect_rasterizer_variable_AsConstantBuffer, + d3d10_effect_rasterizer_variable_AsShader, + d3d10_effect_rasterizer_variable_AsBlend, + d3d10_effect_rasterizer_variable_AsDepthStencil, + d3d10_effect_rasterizer_variable_AsRasterizer, + d3d10_effect_rasterizer_variable_AsSampler, + d3d10_effect_rasterizer_variable_SetRawValue, + d3d10_effect_rasterizer_variable_GetRawValue, + /* ID3D10EffectRasterizerVariable methods */ + d3d10_effect_rasterizer_variable_GetRasterizerState, + d3d10_effect_rasterizer_variable_GetBackingStore, +}; + +/* ID3D10EffectVariable methods */ + +static BOOL STDMETHODCALLTYPE d3d10_effect_sampler_variable_IsValid(ID3D10EffectSamplerVariable *iface) +{ + TRACE("iface %p\n", iface); + + return (struct d3d10_effect_variable *)iface != &null_sampler_variable; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetType( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_GetType((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetDesc(ID3D10EffectSamplerVariable *iface, + D3D10_EFFECT_VARIABLE_DESC *desc) +{ + return d3d10_effect_variable_GetDesc((ID3D10EffectVariable *)iface, desc); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetAnnotationByIndex( + ID3D10EffectSamplerVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetAnnotationByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetAnnotationByName( + ID3D10EffectSamplerVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetAnnotationByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetMemberByIndex( + ID3D10EffectSamplerVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetMemberByIndex((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetMemberByName( + ID3D10EffectSamplerVariable *iface, const char *name) +{ + return d3d10_effect_variable_GetMemberByName((ID3D10EffectVariable *)iface, name); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetMemberBySemantic( + ID3D10EffectSamplerVariable *iface, const char *semantic) +{ + return d3d10_effect_variable_GetMemberBySemantic((ID3D10EffectVariable *)iface, semantic); +} + +static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetElement( + ID3D10EffectSamplerVariable *iface, UINT index) +{ + return d3d10_effect_variable_GetElement((ID3D10EffectVariable *)iface, index); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetParentConstantBuffer( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_GetParentConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectScalarVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsScalar( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsScalar((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectVectorVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsVector( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsVector((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectMatrixVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsMatrix( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsMatrix((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectStringVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsString( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsString((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderResourceVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsShaderResource( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsShaderResource((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRenderTargetViewVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsRenderTargetView( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsRenderTargetView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilViewVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsDepthStencilView( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencilView((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsConstantBuffer( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsConstantBuffer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectShaderVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsShader( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsShader((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectBlendVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsBlend( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsBlend((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectDepthStencilVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsDepthStencil( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsDepthStencil((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectRasterizerVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsRasterizer( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsRasterizer((ID3D10EffectVariable *)iface); +} + +static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_sampler_variable_AsSampler( + ID3D10EffectSamplerVariable *iface) +{ + return d3d10_effect_variable_AsSampler((ID3D10EffectVariable *)iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_sampler_variable_SetRawValue(ID3D10EffectSamplerVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_SetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetRawValue(ID3D10EffectSamplerVariable *iface, + void *data, UINT offset, UINT count) +{ + return d3d10_effect_variable_GetRawValue((ID3D10EffectVariable *)iface, data, offset, count); +} + +/* ID3D10EffectSamplerVariable methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetSampler(ID3D10EffectSamplerVariable *iface, + UINT index, ID3D10SamplerState **sampler) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, sampler %p.\n", iface, index, sampler); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + else if (index) + return E_FAIL; + + if (v->type->basetype != D3D10_SVT_SAMPLER) + { + WARN("Variable is not a sampler state.\n"); + return E_FAIL; + } + + if ((*sampler = v->u.state.object.sampler)) + ID3D10SamplerState_AddRef(*sampler); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_sampler_variable_GetBackingStore(ID3D10EffectSamplerVariable *iface, + UINT index, D3D10_SAMPLER_DESC *desc) +{ + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (v->type->element_count) + v = impl_from_ID3D10EffectVariable(iface->lpVtbl->GetElement(iface, index)); + + if (v->type->basetype != D3D10_SVT_SAMPLER) + { + WARN("Variable is not a sampler state.\n"); + return E_FAIL; + } + + *desc = v->u.state.desc.sampler; + + return S_OK; +} + + +static const struct ID3D10EffectSamplerVariableVtbl d3d10_effect_sampler_variable_vtbl = +{ + /* ID3D10EffectVariable methods */ + d3d10_effect_sampler_variable_IsValid, + d3d10_effect_sampler_variable_GetType, + d3d10_effect_sampler_variable_GetDesc, + d3d10_effect_sampler_variable_GetAnnotationByIndex, + d3d10_effect_sampler_variable_GetAnnotationByName, + d3d10_effect_sampler_variable_GetMemberByIndex, + d3d10_effect_sampler_variable_GetMemberByName, + d3d10_effect_sampler_variable_GetMemberBySemantic, + d3d10_effect_sampler_variable_GetElement, + d3d10_effect_sampler_variable_GetParentConstantBuffer, + d3d10_effect_sampler_variable_AsScalar, + d3d10_effect_sampler_variable_AsVector, + d3d10_effect_sampler_variable_AsMatrix, + d3d10_effect_sampler_variable_AsString, + d3d10_effect_sampler_variable_AsShaderResource, + d3d10_effect_sampler_variable_AsRenderTargetView, + d3d10_effect_sampler_variable_AsDepthStencilView, + d3d10_effect_sampler_variable_AsConstantBuffer, + d3d10_effect_sampler_variable_AsShader, + d3d10_effect_sampler_variable_AsBlend, + d3d10_effect_sampler_variable_AsDepthStencil, + d3d10_effect_sampler_variable_AsRasterizer, + d3d10_effect_sampler_variable_AsSampler, + d3d10_effect_sampler_variable_SetRawValue, + d3d10_effect_sampler_variable_GetRawValue, + /* ID3D10EffectSamplerVariable methods */ + d3d10_effect_sampler_variable_GetSampler, + d3d10_effect_sampler_variable_GetBackingStore, +}; + +/* ID3D10EffectType methods */ + +static inline struct d3d10_effect_type *impl_from_ID3D10EffectType(ID3D10EffectType *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_type, ID3D10EffectType_iface); +} + +static BOOL STDMETHODCALLTYPE d3d10_effect_type_IsValid(ID3D10EffectType *iface) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + + TRACE("iface %p\n", iface); + + return This != &null_type; +} + +static HRESULT STDMETHODCALLTYPE d3d10_effect_type_GetDesc(ID3D10EffectType *iface, D3D10_EFFECT_TYPE_DESC *desc) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + if (This == &null_type) + { + WARN("Null type specified\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified\n"); + return E_INVALIDARG; + } + + desc->TypeName = This->name; + desc->Class = This->type_class; + desc->Type = This->basetype; + desc->Elements = This->element_count; + desc->Members = This->member_count; + desc->Rows = This->row_count; + desc->Columns = This->column_count; + desc->PackedSize = This->size_packed; + desc->UnpackedSize = This->size_unpacked; + desc->Stride = This->stride; + + return S_OK; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_type_GetMemberTypeByIndex(ID3D10EffectType *iface, + UINT index) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + struct d3d10_effect_type *t; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->member_count) + { + WARN("Invalid index specified\n"); + return &null_type.ID3D10EffectType_iface; + } + + t = (&This->members[index])->type; + + TRACE("Returning member %p, %s\n", t, debugstr_a(t->name)); + + return &t->ID3D10EffectType_iface; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_type_GetMemberTypeByName(ID3D10EffectType *iface, + const char *name) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + unsigned int i; + + TRACE("iface %p, name %s\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid name specified\n"); + return &null_type.ID3D10EffectType_iface; + } + + for (i = 0; i < This->member_count; ++i) + { + struct d3d10_effect_type_member *typem = &This->members[i]; + + if (typem->name && !strcmp(typem->name, name)) + { + TRACE("Returning type %p.\n", typem->type); + return &typem->type->ID3D10EffectType_iface; + } + } + + WARN("Invalid name specified\n"); + + return &null_type.ID3D10EffectType_iface; +} + +static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_type_GetMemberTypeBySemantic(ID3D10EffectType *iface, + const char *semantic) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + unsigned int i; + + TRACE("iface %p, semantic %s\n", iface, debugstr_a(semantic)); + + if (!semantic) + { + WARN("Invalid semantic specified\n"); + return &null_type.ID3D10EffectType_iface; + } + + for (i = 0; i < This->member_count; ++i) + { + struct d3d10_effect_type_member *typem = &This->members[i]; + + if (typem->semantic && !strcmp(typem->semantic, semantic)) + { + TRACE("Returning type %p.\n", typem->type); + return &typem->type->ID3D10EffectType_iface; + } + } + + WARN("Invalid semantic specified\n"); + + return &null_type.ID3D10EffectType_iface; +} + +static const char * STDMETHODCALLTYPE d3d10_effect_type_GetMemberName(ID3D10EffectType *iface, UINT index) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + struct d3d10_effect_type_member *typem; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->member_count) + { + WARN("Invalid index specified\n"); + return NULL; + } + + typem = &This->members[index]; + + TRACE("Returning name %s\n", debugstr_a(typem->name)); + + return typem->name; +} + +static const char * STDMETHODCALLTYPE d3d10_effect_type_GetMemberSemantic(ID3D10EffectType *iface, UINT index) +{ + struct d3d10_effect_type *This = impl_from_ID3D10EffectType(iface); + struct d3d10_effect_type_member *typem; + + TRACE("iface %p, index %u\n", iface, index); + + if (index >= This->member_count) + { + WARN("Invalid index specified\n"); + return NULL; + } + + typem = &This->members[index]; + + TRACE("Returning semantic %s\n", debugstr_a(typem->semantic)); + + return typem->semantic; +} + +static const struct ID3D10EffectTypeVtbl d3d10_effect_type_vtbl = +{ + /* ID3D10EffectType */ + d3d10_effect_type_IsValid, + d3d10_effect_type_GetDesc, + d3d10_effect_type_GetMemberTypeByIndex, + d3d10_effect_type_GetMemberTypeByName, + d3d10_effect_type_GetMemberTypeBySemantic, + d3d10_effect_type_GetMemberName, + d3d10_effect_type_GetMemberSemantic, +}; diff --git a/dll/directx/wine/d3d10/shader.c b/dll/directx/wine/d3d10/shader.c new file mode 100644 index 00000000000..52e3cc06bf4 --- /dev/null +++ b/dll/directx/wine/d3d10/shader.c @@ -0,0 +1,153 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2010 Rico Schüller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d10_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10); + +/* IUnknown methods */ + +static inline struct d3d10_shader_reflection *impl_from_ID3D10ShaderReflection(ID3D10ShaderReflection *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_shader_reflection, ID3D10ShaderReflection_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_reflection_QueryInterface(ID3D10ShaderReflection *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D10ShaderReflection) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_shader_reflection_AddRef(ID3D10ShaderReflection *iface) +{ + struct d3d10_shader_reflection *This = impl_from_ID3D10ShaderReflection(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_shader_reflection_Release(ID3D10ShaderReflection *iface) +{ + struct d3d10_shader_reflection *This = impl_from_ID3D10ShaderReflection(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + heap_free(This); + + return refcount; +} + +/* ID3D10ShaderReflection methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_shader_reflection_GetDesc(ID3D10ShaderReflection *iface, D3D10_SHADER_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); + + return E_NOTIMPL; +} + +static struct ID3D10ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d10_shader_reflection_GetConstantBufferByIndex( + ID3D10ShaderReflection *iface, UINT index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return NULL; +} + +static struct ID3D10ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d10_shader_reflection_GetConstantBufferByName( + ID3D10ShaderReflection *iface, const char *name) +{ + FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name)); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_reflection_GetResourceBindingDesc( + ID3D10ShaderReflection *iface, UINT index, D3D10_SHADER_INPUT_BIND_DESC *desc) +{ + FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_reflection_GetInputParameterDesc( + ID3D10ShaderReflection *iface, UINT index, D3D10_SIGNATURE_PARAMETER_DESC *desc) +{ + FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_reflection_GetOutputParameterDesc( + ID3D10ShaderReflection *iface, UINT index, D3D10_SIGNATURE_PARAMETER_DESC *desc) +{ + FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc); + + return E_NOTIMPL; +} + +const struct ID3D10ShaderReflectionVtbl d3d10_shader_reflection_vtbl = +{ + /* IUnknown methods */ + d3d10_shader_reflection_QueryInterface, + d3d10_shader_reflection_AddRef, + d3d10_shader_reflection_Release, + /* ID3D10ShaderReflection methods */ + d3d10_shader_reflection_GetDesc, + d3d10_shader_reflection_GetConstantBufferByIndex, + d3d10_shader_reflection_GetConstantBufferByName, + d3d10_shader_reflection_GetResourceBindingDesc, + d3d10_shader_reflection_GetInputParameterDesc, + d3d10_shader_reflection_GetOutputParameterDesc, +}; + +HRESULT WINAPI D3D10CompileShader(const char *data, SIZE_T data_size, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entrypoint, + const char *profile, UINT flags, ID3D10Blob **shader, ID3D10Blob **error_messages) +{ + /* Forward to d3dcompiler */ + return D3DCompile(data, data_size, filename, defines, include, + entrypoint, profile, flags, 0, shader, error_messages); +} + +HRESULT WINAPI D3D10DisassembleShader(const void *data, SIZE_T data_size, + BOOL color_code, const char *comments, ID3D10Blob **disassembly) +{ + TRACE("data %p, data_size %#lx, color_code %#x, comments %p, disassembly %p.\n", + data, data_size, color_code, comments, disassembly); + + return D3DDisassemble(data, data_size, color_code ? D3D_DISASM_ENABLE_COLOR_CODE : 0, comments, disassembly); +} diff --git a/dll/directx/wine/d3d10/stateblock.c b/dll/directx/wine/d3d10/stateblock.c new file mode 100644 index 00000000000..e20a4e31f3c --- /dev/null +++ b/dll/directx/wine/d3d10/stateblock.c @@ -0,0 +1,927 @@ +/* + * Copyright 2011 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d10_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10); + +struct d3d10_stateblock +{ + ID3D10StateBlock ID3D10StateBlock_iface; + LONG refcount; + + ID3D10Device *device; + D3D10_STATE_BLOCK_MASK mask; + + ID3D10VertexShader *vs; + ID3D10SamplerState *vs_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D10ShaderResourceView *vs_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D10Buffer *vs_cbs[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D10GeometryShader *gs; + ID3D10SamplerState *gs_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D10ShaderResourceView *gs_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D10Buffer *gs_cbs[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D10PixelShader *ps; + ID3D10SamplerState *ps_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D10ShaderResourceView *ps_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D10Buffer *ps_cbs[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D10Buffer *vbs[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT vb_strides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT vb_offsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + ID3D10Buffer *ib; + DXGI_FORMAT ib_format; + UINT ib_offset; + ID3D10InputLayout *il; + D3D10_PRIMITIVE_TOPOLOGY topology; + ID3D10RenderTargetView *rtvs[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT]; + ID3D10DepthStencilView *dsv; + ID3D10DepthStencilState *dss; + UINT stencil_ref; + ID3D10BlendState *bs; + float blend_factor[4]; + UINT sample_mask; + D3D10_VIEWPORT vps[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D10_RECT scissor_rects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D10RasterizerState *rs; + ID3D10Buffer *so_buffers[D3D10_SO_BUFFER_SLOT_COUNT]; + UINT so_offsets[D3D10_SO_BUFFER_SLOT_COUNT]; + ID3D10Predicate *predicate; + BOOL predicate_value; +}; + +static inline struct d3d10_stateblock *impl_from_ID3D10StateBlock(ID3D10StateBlock *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_stateblock, ID3D10StateBlock_iface); +} + +static void stateblock_cleanup(struct d3d10_stateblock *stateblock) +{ + unsigned int i; + + if (stateblock->vs) + { + ID3D10VertexShader_Release(stateblock->vs); + stateblock->vs = NULL; + } + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->vs_samplers[i]) + { + ID3D10SamplerState_Release(stateblock->vs_samplers[i]); + stateblock->vs_samplers[i] = NULL; + } + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->vs_resources[i]) + { + ID3D10ShaderResourceView_Release(stateblock->vs_resources[i]); + stateblock->vs_resources[i] = NULL; + } + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->vs_cbs[i]) + { + ID3D10Buffer_Release(stateblock->vs_cbs[i]); + stateblock->vs_cbs[i] = NULL; + } + } + + if (stateblock->gs) + { + ID3D10GeometryShader_Release(stateblock->gs); + stateblock->gs = NULL; + } + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->gs_samplers[i]) + { + ID3D10SamplerState_Release(stateblock->gs_samplers[i]); + stateblock->gs_samplers[i] = NULL; + } + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->gs_resources[i]) + { + ID3D10ShaderResourceView_Release(stateblock->gs_resources[i]); + stateblock->gs_resources[i] = NULL; + } + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->gs_cbs[i]) + { + ID3D10Buffer_Release(stateblock->gs_cbs[i]); + stateblock->gs_cbs[i] = NULL; + } + } + + if (stateblock->ps) + { + ID3D10PixelShader_Release(stateblock->ps); + stateblock->ps = NULL; + } + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->ps_samplers[i]) + { + ID3D10SamplerState_Release(stateblock->ps_samplers[i]); + stateblock->ps_samplers[i] = NULL; + } + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->ps_resources[i]) + { + ID3D10ShaderResourceView_Release(stateblock->ps_resources[i]); + stateblock->ps_resources[i] = NULL; + } + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->ps_cbs[i]) + { + ID3D10Buffer_Release(stateblock->ps_cbs[i]); + stateblock->ps_cbs[i] = NULL; + } + } + + for (i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->vbs[i]) + { + ID3D10Buffer_Release(stateblock->vbs[i]); + stateblock->vbs[i] = NULL; + } + } + if (stateblock->ib) + { + ID3D10Buffer_Release(stateblock->ib); + stateblock->ib = NULL; + } + if (stateblock->il) + { + ID3D10InputLayout_Release(stateblock->il); + stateblock->il = NULL; + } + + for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + if (stateblock->rtvs[i]) + { + ID3D10RenderTargetView_Release(stateblock->rtvs[i]); + stateblock->rtvs[i] = NULL; + } + } + if (stateblock->dsv) + { + ID3D10DepthStencilView_Release(stateblock->dsv); + stateblock->dsv = NULL; + } + if (stateblock->dss) + { + ID3D10DepthStencilState_Release(stateblock->dss); + stateblock->dss = NULL; + } + if (stateblock->bs) + { + ID3D10BlendState_Release(stateblock->bs); + stateblock->bs = NULL; + } + + if (stateblock->rs) + { + ID3D10RasterizerState_Release(stateblock->rs); + stateblock->rs = NULL; + } + + for (i = 0; i < D3D10_SO_BUFFER_SLOT_COUNT; ++i) + { + if (stateblock->so_buffers[i]) + { + ID3D10Buffer_Release(stateblock->so_buffers[i]); + stateblock->so_buffers[i] = NULL; + } + } + + if (stateblock->predicate) + { + ID3D10Predicate_Release(stateblock->predicate); + stateblock->predicate = NULL; + } +} + +static HRESULT STDMETHODCALLTYPE d3d10_stateblock_QueryInterface(ID3D10StateBlock *iface, REFIID iid, void **object) +{ + struct d3d10_stateblock *stateblock; + + TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + + stateblock = impl_from_ID3D10StateBlock(iface); + + if (IsEqualGUID(iid, &IID_ID3D10StateBlock) + || IsEqualGUID(iid, &IID_IUnknown)) + { + IUnknown_AddRef(&stateblock->ID3D10StateBlock_iface); + *object = &stateblock->ID3D10StateBlock_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *object = NULL; + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_stateblock_AddRef(ID3D10StateBlock *iface) +{ + struct d3d10_stateblock *stateblock = impl_from_ID3D10StateBlock(iface); + ULONG refcount = InterlockedIncrement(&stateblock->refcount); + + TRACE("%p increasing refcount to %u.\n", stateblock, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_stateblock_Release(ID3D10StateBlock *iface) +{ + struct d3d10_stateblock *stateblock = impl_from_ID3D10StateBlock(iface); + ULONG refcount = InterlockedDecrement(&stateblock->refcount); + + TRACE("%p decreasing refcount to %u.\n", stateblock, refcount); + + if (!refcount) + { + stateblock_cleanup(stateblock); + ID3D10Device_Release(stateblock->device); + heap_free(stateblock); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE d3d10_stateblock_Capture(ID3D10StateBlock *iface) +{ + unsigned int vp_count = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + struct d3d10_stateblock *stateblock = impl_from_ID3D10StateBlock(iface); + unsigned int i; + + TRACE("iface %p.\n", iface); + + stateblock_cleanup(stateblock); + + if (stateblock->mask.VS) + ID3D10Device_VSGetShader(stateblock->device, &stateblock->vs); + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->mask.VSSamplers[i >> 3] & (1 << (i & 7))) + ID3D10Device_VSGetSamplers(stateblock->device, i, 1, &stateblock->vs_samplers[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.VSShaderResources[i >> 3] & (1 << (i & 7))) + ID3D10Device_VSGetShaderResources(stateblock->device, i, 1, &stateblock->vs_resources[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->mask.VSConstantBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_VSGetConstantBuffers(stateblock->device, i, 1, &stateblock->vs_cbs[i]); + } + + if (stateblock->mask.GS) + ID3D10Device_GSGetShader(stateblock->device, &stateblock->gs); + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->mask.GSSamplers[i >> 3] & (1 << (i & 7))) + ID3D10Device_GSGetSamplers(stateblock->device, i, 1, &stateblock->gs_samplers[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.GSShaderResources[i >> 3] & (1 << (i & 7))) + ID3D10Device_GSGetShaderResources(stateblock->device, i, 1, &stateblock->gs_resources[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->mask.GSConstantBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_GSGetConstantBuffers(stateblock->device, i, 1, &stateblock->gs_cbs[i]); + } + + if (stateblock->mask.PS) + ID3D10Device_PSGetShader(stateblock->device, &stateblock->ps); + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->mask.PSSamplers[i >> 3] & (1 << (i & 7))) + ID3D10Device_PSGetSamplers(stateblock->device, i, 1, &stateblock->ps_samplers[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.PSShaderResources[i >> 3] & (1 << (i & 7))) + ID3D10Device_PSGetShaderResources(stateblock->device, i, 1, &stateblock->ps_resources[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->mask.PSConstantBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_PSGetConstantBuffers(stateblock->device, i, 1, &stateblock->ps_cbs[i]); + } + + for (i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.IAVertexBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_IAGetVertexBuffers(stateblock->device, i, 1, &stateblock->vbs[i], + &stateblock->vb_strides[i], &stateblock->vb_offsets[i]); + } + if (stateblock->mask.IAIndexBuffer) + ID3D10Device_IAGetIndexBuffer(stateblock->device, &stateblock->ib, + &stateblock->ib_format, &stateblock->ib_offset); + if (stateblock->mask.IAInputLayout) + ID3D10Device_IAGetInputLayout(stateblock->device, &stateblock->il); + if (stateblock->mask.IAPrimitiveTopology) + ID3D10Device_IAGetPrimitiveTopology(stateblock->device, &stateblock->topology); + + if (stateblock->mask.OMRenderTargets) + ID3D10Device_OMGetRenderTargets(stateblock->device, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, + stateblock->rtvs, &stateblock->dsv); + if (stateblock->mask.OMDepthStencilState) + ID3D10Device_OMGetDepthStencilState(stateblock->device, &stateblock->dss, &stateblock->stencil_ref); + if (stateblock->mask.OMBlendState) + ID3D10Device_OMGetBlendState(stateblock->device, &stateblock->bs, + stateblock->blend_factor, &stateblock->sample_mask); + + if (stateblock->mask.RSViewports) + ID3D10Device_RSGetViewports(stateblock->device, &vp_count, stateblock->vps); + if (stateblock->mask.RSScissorRects) + ID3D10Device_RSGetScissorRects(stateblock->device, &vp_count, stateblock->scissor_rects); + if (stateblock->mask.RSRasterizerState) + ID3D10Device_RSGetState(stateblock->device, &stateblock->rs); + + if (stateblock->mask.SOBuffers) + ID3D10Device_SOGetTargets(stateblock->device, D3D10_SO_BUFFER_SLOT_COUNT, + stateblock->so_buffers, stateblock->so_offsets); + + if (stateblock->mask.Predication) + ID3D10Device_GetPredication(stateblock->device, &stateblock->predicate, &stateblock->predicate_value); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_stateblock_Apply(ID3D10StateBlock *iface) +{ + struct d3d10_stateblock *stateblock = impl_from_ID3D10StateBlock(iface); + unsigned int i; + + TRACE("iface %p.\n", iface); + + if (stateblock->mask.VS) + ID3D10Device_VSSetShader(stateblock->device, stateblock->vs); + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->mask.VSSamplers[i >> 3] & (1 << (i & 7))) + ID3D10Device_VSSetSamplers(stateblock->device, i, 1, &stateblock->vs_samplers[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.VSShaderResources[i >> 3] & (1 << (i & 7))) + ID3D10Device_VSSetShaderResources(stateblock->device, i, 1, &stateblock->vs_resources[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->mask.VSConstantBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_VSSetConstantBuffers(stateblock->device, i, 1, &stateblock->vs_cbs[i]); + } + + if (stateblock->mask.GS) + ID3D10Device_GSSetShader(stateblock->device, stateblock->gs); + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->mask.GSSamplers[i >> 3] & (1 << (i & 7))) + ID3D10Device_GSSetSamplers(stateblock->device, i, 1, &stateblock->gs_samplers[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.GSShaderResources[i >> 3] & (1 << (i & 7))) + ID3D10Device_GSSetShaderResources(stateblock->device, i, 1, &stateblock->gs_resources[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->mask.GSConstantBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_GSSetConstantBuffers(stateblock->device, i, 1, &stateblock->gs_cbs[i]); + } + + if (stateblock->mask.PS) + ID3D10Device_PSSetShader(stateblock->device, stateblock->ps); + for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + if (stateblock->mask.PSSamplers[i >> 3] & (1 << (i & 7))) + ID3D10Device_PSSetSamplers(stateblock->device, i, 1, &stateblock->ps_samplers[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.PSShaderResources[i >> 3] & (1 << (i & 7))) + ID3D10Device_PSSetShaderResources(stateblock->device, i, 1, &stateblock->ps_resources[i]); + } + for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i) + { + if (stateblock->mask.PSConstantBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_PSSetConstantBuffers(stateblock->device, i, 1, &stateblock->ps_cbs[i]); + } + + for (i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + if (stateblock->mask.IAVertexBuffers[i >> 3] & (1 << (i & 7))) + ID3D10Device_IASetVertexBuffers(stateblock->device, i, 1, &stateblock->vbs[i], + &stateblock->vb_strides[i], &stateblock->vb_offsets[i]); + } + if (stateblock->mask.IAIndexBuffer) + ID3D10Device_IASetIndexBuffer(stateblock->device, stateblock->ib, + stateblock->ib_format, stateblock->ib_offset); + if (stateblock->mask.IAInputLayout) + ID3D10Device_IASetInputLayout(stateblock->device, stateblock->il); + if (stateblock->mask.IAPrimitiveTopology) + ID3D10Device_IASetPrimitiveTopology(stateblock->device, stateblock->topology); + + if (stateblock->mask.OMRenderTargets) + ID3D10Device_OMSetRenderTargets(stateblock->device, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, + stateblock->rtvs, stateblock->dsv); + if (stateblock->mask.OMDepthStencilState) + ID3D10Device_OMSetDepthStencilState(stateblock->device, stateblock->dss, stateblock->stencil_ref); + if (stateblock->mask.OMBlendState) + ID3D10Device_OMSetBlendState(stateblock->device, stateblock->bs, + stateblock->blend_factor, stateblock->sample_mask); + + if (stateblock->mask.RSViewports) + ID3D10Device_RSSetViewports(stateblock->device, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, + stateblock->vps); + if (stateblock->mask.RSScissorRects) + ID3D10Device_RSSetScissorRects(stateblock->device, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, + stateblock->scissor_rects); + if (stateblock->mask.RSRasterizerState) + ID3D10Device_RSSetState(stateblock->device, stateblock->rs); + + if (stateblock->mask.SOBuffers) + ID3D10Device_SOSetTargets(stateblock->device, D3D10_SO_BUFFER_SLOT_COUNT, + stateblock->so_buffers, stateblock->so_offsets); + + if (stateblock->mask.Predication) + ID3D10Device_SetPredication(stateblock->device, stateblock->predicate, stateblock->predicate_value); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_stateblock_ReleaseAllDeviceObjects(ID3D10StateBlock *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_stateblock_GetDevice(ID3D10StateBlock *iface, ID3D10Device **device) +{ + FIXME("iface %p, device %p stub!\n", iface, device); + + return E_NOTIMPL; +} + +static const struct ID3D10StateBlockVtbl d3d10_stateblock_vtbl = +{ + /* IUnknown methods */ + d3d10_stateblock_QueryInterface, + d3d10_stateblock_AddRef, + d3d10_stateblock_Release, + /* ID3D10StateBlock methods */ + d3d10_stateblock_Capture, + d3d10_stateblock_Apply, + d3d10_stateblock_ReleaseAllDeviceObjects, + d3d10_stateblock_GetDevice, +}; + +HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *device, + D3D10_STATE_BLOCK_MASK *mask, ID3D10StateBlock **stateblock) +{ + struct d3d10_stateblock *object; + + TRACE("device %p, mask %p, stateblock %p.\n", device, mask, stateblock); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate D3D10 stateblock object memory.\n"); + return E_OUTOFMEMORY; + } + + object->ID3D10StateBlock_iface.lpVtbl = &d3d10_stateblock_vtbl; + object->refcount = 1; + + object->device = device; + ID3D10Device_AddRef(object->device); + object->mask = *mask; + + TRACE("Created stateblock %p.\n", object); + *stateblock = &object->ID3D10StateBlock_iface; + + return S_OK; +} + +static BOOL stateblock_mask_get_bit(BYTE *field, UINT field_size, UINT idx) +{ + if (idx >= field_size) + return FALSE; + + return field[idx >> 3] & (1 << (idx & 7)); +} + +static HRESULT stateblock_mask_set_bits(BYTE *field, UINT field_size, UINT start_bit, UINT count) +{ + UINT end_bit = start_bit + count; + BYTE start_mask = 0xff << (start_bit & 7); + BYTE end_mask = 0x7f >> (~end_bit & 7); + UINT start_idx = start_bit >> 3; + UINT end_idx = end_bit >> 3; + + if (start_bit >= field_size || field_size - start_bit < count) + return E_INVALIDARG; + + if (start_idx == end_idx) + { + field[start_idx] |= start_mask & end_mask; + return S_OK; + } + + if (start_bit & 7) + { + field[start_idx] |= start_mask; + ++start_idx; + } + + memset(&field[start_idx], 0xff, end_idx - start_idx); + + if (end_bit & 7) + field[end_idx] |= end_mask; + + return S_OK; +} + +static HRESULT stateblock_mask_clear_bits(BYTE *field, UINT field_size, UINT start_bit, UINT count) +{ + UINT end_bit = start_bit + count; + BYTE start_mask = 0x7f >> (~start_bit & 7); + BYTE end_mask = 0xff << (end_bit & 7); + UINT start_idx = start_bit >> 3; + UINT end_idx = end_bit >> 3; + + if (start_bit >= field_size || field_size - start_bit < count) + return E_INVALIDARG; + + if (start_idx == end_idx) + { + field[start_idx] &= start_mask | end_mask; + return S_OK; + } + + if (start_bit & 7) + { + field[start_idx] &= start_mask; + ++start_idx; + } + + memset(&field[start_idx], 0, end_idx - start_idx); + + if (end_bit & 7) + field[end_idx] &= end_mask; + + return S_OK; +} + +HRESULT WINAPI D3D10StateBlockMaskDifference(D3D10_STATE_BLOCK_MASK *mask_x, + D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result) +{ + UINT count = sizeof(*result) / sizeof(DWORD); + UINT i; + + TRACE("mask_x %p, mask_y %p, result %p.\n", mask_x, mask_y, result); + + if (!mask_x || !mask_y || !result) + return E_INVALIDARG; + + for (i = 0; i < count; ++i) + { + ((DWORD *)result)[i] = ((DWORD *)mask_x)[i] ^ ((DWORD *)mask_y)[i]; + } + for (i = count * sizeof(DWORD); i < sizeof(*result); ++i) + { + ((BYTE *)result)[i] = ((BYTE *)mask_x)[i] ^ ((BYTE *)mask_y)[i]; + } + + return S_OK; +} + +HRESULT WINAPI D3D10StateBlockMaskDisableAll(D3D10_STATE_BLOCK_MASK *mask) +{ + TRACE("mask %p.\n", mask); + + if (!mask) + return E_INVALIDARG; + + memset(mask, 0, sizeof(*mask)); + + return S_OK; +} + +HRESULT WINAPI D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT start_idx, UINT count) +{ + TRACE("mask %p state_type %s, start_idx %u, count %u.\n", + mask, debug_d3d10_device_state_types(state_type), start_idx, count); + + if (!mask) + return E_INVALIDARG; + + switch (state_type) + { + case D3D10_DST_SO_BUFFERS: + return stateblock_mask_clear_bits(&mask->SOBuffers, 1, start_idx, count); + case D3D10_DST_OM_RENDER_TARGETS: + return stateblock_mask_clear_bits(&mask->OMRenderTargets, 1, start_idx, count); + case D3D10_DST_DEPTH_STENCIL_STATE: + return stateblock_mask_clear_bits(&mask->OMDepthStencilState, 1, start_idx, count); + case D3D10_DST_BLEND_STATE: + return stateblock_mask_clear_bits(&mask->OMBlendState, 1, start_idx, count); + case D3D10_DST_VS: + return stateblock_mask_clear_bits(&mask->VS, 1, start_idx, count); + case D3D10_DST_VS_SAMPLERS: + return stateblock_mask_clear_bits(mask->VSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_VS_SHADER_RESOURCES: + return stateblock_mask_clear_bits(mask->VSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_VS_CONSTANT_BUFFERS: + return stateblock_mask_clear_bits(mask->VSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS: + return stateblock_mask_clear_bits(&mask->GS, 1, start_idx, count); + case D3D10_DST_GS_SAMPLERS: + return stateblock_mask_clear_bits(mask->GSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS_SHADER_RESOURCES: + return stateblock_mask_clear_bits(mask->GSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS_CONSTANT_BUFFERS: + return stateblock_mask_clear_bits(mask->GSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS: + return stateblock_mask_clear_bits(&mask->PS, 1, start_idx, count); + case D3D10_DST_PS_SAMPLERS: + return stateblock_mask_clear_bits(mask->PSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS_SHADER_RESOURCES: + return stateblock_mask_clear_bits(mask->PSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS_CONSTANT_BUFFERS: + return stateblock_mask_clear_bits(mask->PSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_IA_VERTEX_BUFFERS: + return stateblock_mask_clear_bits(mask->IAVertexBuffers, + D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_IA_INDEX_BUFFER: + return stateblock_mask_clear_bits(&mask->IAIndexBuffer, 1, start_idx, count); + case D3D10_DST_IA_INPUT_LAYOUT: + return stateblock_mask_clear_bits(&mask->IAInputLayout, 1, start_idx, count); + case D3D10_DST_IA_PRIMITIVE_TOPOLOGY: + return stateblock_mask_clear_bits(&mask->IAPrimitiveTopology, 1, start_idx, count); + case D3D10_DST_RS_VIEWPORTS: + return stateblock_mask_clear_bits(&mask->RSViewports, 1, start_idx, count); + case D3D10_DST_RS_SCISSOR_RECTS: + return stateblock_mask_clear_bits(&mask->RSScissorRects, 1, start_idx, count); + case D3D10_DST_RS_RASTERIZER_STATE: + return stateblock_mask_clear_bits(&mask->RSRasterizerState, 1, start_idx, count); + case D3D10_DST_PREDICATION: + return stateblock_mask_clear_bits(&mask->Predication, 1, start_idx, count); + default: + FIXME("Unhandled state_type %#x.\n", state_type); + return E_INVALIDARG; + } +} + +HRESULT WINAPI D3D10StateBlockMaskEnableAll(D3D10_STATE_BLOCK_MASK *mask) +{ + TRACE("mask %p.\n", mask); + + if (!mask) + return E_INVALIDARG; + + memset(mask, 0xff, sizeof(*mask)); + + return S_OK; +} + +HRESULT WINAPI D3D10StateBlockMaskEnableCapture(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT start_idx, UINT count) +{ + TRACE("mask %p state_type %s, start_idx %u, count %u.\n", + mask, debug_d3d10_device_state_types(state_type), start_idx, count); + + if (!mask) + return E_INVALIDARG; + + switch (state_type) + { + case D3D10_DST_SO_BUFFERS: + return stateblock_mask_set_bits(&mask->SOBuffers, 1, start_idx, count); + case D3D10_DST_OM_RENDER_TARGETS: + return stateblock_mask_set_bits(&mask->OMRenderTargets, 1, start_idx, count); + case D3D10_DST_DEPTH_STENCIL_STATE: + return stateblock_mask_set_bits(&mask->OMDepthStencilState, 1, start_idx, count); + case D3D10_DST_BLEND_STATE: + return stateblock_mask_set_bits(&mask->OMBlendState, 1, start_idx, count); + case D3D10_DST_VS: + return stateblock_mask_set_bits(&mask->VS, 1, start_idx, count); + case D3D10_DST_VS_SAMPLERS: + return stateblock_mask_set_bits(mask->VSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_VS_SHADER_RESOURCES: + return stateblock_mask_set_bits(mask->VSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_VS_CONSTANT_BUFFERS: + return stateblock_mask_set_bits(mask->VSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS: + return stateblock_mask_set_bits(&mask->GS, 1, start_idx, count); + case D3D10_DST_GS_SAMPLERS: + return stateblock_mask_set_bits(mask->GSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS_SHADER_RESOURCES: + return stateblock_mask_set_bits(mask->GSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS_CONSTANT_BUFFERS: + return stateblock_mask_set_bits(mask->GSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS: + return stateblock_mask_set_bits(&mask->PS, 1, start_idx, count); + case D3D10_DST_PS_SAMPLERS: + return stateblock_mask_set_bits(mask->PSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS_SHADER_RESOURCES: + return stateblock_mask_set_bits(mask->PSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS_CONSTANT_BUFFERS: + return stateblock_mask_set_bits(mask->PSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_IA_VERTEX_BUFFERS: + return stateblock_mask_set_bits(mask->IAVertexBuffers, + D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_IA_INDEX_BUFFER: + return stateblock_mask_set_bits(&mask->IAIndexBuffer, 1, start_idx, count); + case D3D10_DST_IA_INPUT_LAYOUT: + return stateblock_mask_set_bits(&mask->IAInputLayout, 1, start_idx, count); + case D3D10_DST_IA_PRIMITIVE_TOPOLOGY: + return stateblock_mask_set_bits(&mask->IAPrimitiveTopology, 1, start_idx, count); + case D3D10_DST_RS_VIEWPORTS: + return stateblock_mask_set_bits(&mask->RSViewports, 1, start_idx, count); + case D3D10_DST_RS_SCISSOR_RECTS: + return stateblock_mask_set_bits(&mask->RSScissorRects, 1, start_idx, count); + case D3D10_DST_RS_RASTERIZER_STATE: + return stateblock_mask_set_bits(&mask->RSRasterizerState, 1, start_idx, count); + case D3D10_DST_PREDICATION: + return stateblock_mask_set_bits(&mask->Predication, 1, start_idx, count); + default: + FIXME("Unhandled state_type %#x.\n", state_type); + return E_INVALIDARG; + } +} + +BOOL WINAPI D3D10StateBlockMaskGetSetting(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT idx) +{ + TRACE("mask %p state_type %s, idx %u.\n", + mask, debug_d3d10_device_state_types(state_type), idx); + + if (!mask) + return FALSE; + + switch (state_type) + { + case D3D10_DST_SO_BUFFERS: + return stateblock_mask_get_bit(&mask->SOBuffers, 1, idx); + case D3D10_DST_OM_RENDER_TARGETS: + return stateblock_mask_get_bit(&mask->OMRenderTargets, 1, idx); + case D3D10_DST_DEPTH_STENCIL_STATE: + return stateblock_mask_get_bit(&mask->OMDepthStencilState, 1, idx); + case D3D10_DST_BLEND_STATE: + return stateblock_mask_get_bit(&mask->OMBlendState, 1, idx); + case D3D10_DST_VS: + return stateblock_mask_get_bit(&mask->VS, 1, idx); + case D3D10_DST_VS_SAMPLERS: + return stateblock_mask_get_bit(mask->VSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, idx); + case D3D10_DST_VS_SHADER_RESOURCES: + return stateblock_mask_get_bit(mask->VSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, idx); + case D3D10_DST_VS_CONSTANT_BUFFERS: + return stateblock_mask_get_bit(mask->VSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, idx); + case D3D10_DST_GS: + return stateblock_mask_get_bit(&mask->GS, 1, idx); + case D3D10_DST_GS_SAMPLERS: + return stateblock_mask_get_bit(mask->GSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, idx); + case D3D10_DST_GS_SHADER_RESOURCES: + return stateblock_mask_get_bit(mask->GSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, idx); + case D3D10_DST_GS_CONSTANT_BUFFERS: + return stateblock_mask_get_bit(mask->GSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, idx); + case D3D10_DST_PS: + return stateblock_mask_get_bit(&mask->PS, 1, idx); + case D3D10_DST_PS_SAMPLERS: + return stateblock_mask_get_bit(mask->PSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, idx); + case D3D10_DST_PS_SHADER_RESOURCES: + return stateblock_mask_get_bit(mask->PSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, idx); + case D3D10_DST_PS_CONSTANT_BUFFERS: + return stateblock_mask_get_bit(mask->PSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, idx); + case D3D10_DST_IA_VERTEX_BUFFERS: + return stateblock_mask_get_bit(mask->IAVertexBuffers, + D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, idx); + case D3D10_DST_IA_INDEX_BUFFER: + return stateblock_mask_get_bit(&mask->IAIndexBuffer, 1, idx); + case D3D10_DST_IA_INPUT_LAYOUT: + return stateblock_mask_get_bit(&mask->IAInputLayout, 1, idx); + case D3D10_DST_IA_PRIMITIVE_TOPOLOGY: + return stateblock_mask_get_bit(&mask->IAPrimitiveTopology, 1, idx); + case D3D10_DST_RS_VIEWPORTS: + return stateblock_mask_get_bit(&mask->RSViewports, 1, idx); + case D3D10_DST_RS_SCISSOR_RECTS: + return stateblock_mask_get_bit(&mask->RSScissorRects, 1, idx); + case D3D10_DST_RS_RASTERIZER_STATE: + return stateblock_mask_get_bit(&mask->RSRasterizerState, 1, idx); + case D3D10_DST_PREDICATION: + return stateblock_mask_get_bit(&mask->Predication, 1, idx); + default: + FIXME("Unhandled state_type %#x.\n", state_type); + return FALSE; + } +} + +HRESULT WINAPI D3D10StateBlockMaskIntersect(D3D10_STATE_BLOCK_MASK *mask_x, + D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result) +{ + UINT count = sizeof(*result) / sizeof(DWORD); + UINT i; + + TRACE("mask_x %p, mask_y %p, result %p.\n", mask_x, mask_y, result); + + if (!mask_x || !mask_y || !result) + return E_INVALIDARG; + + for (i = 0; i < count; ++i) + { + ((DWORD *)result)[i] = ((DWORD *)mask_x)[i] & ((DWORD *)mask_y)[i]; + } + for (i = count * sizeof(DWORD); i < sizeof(*result); ++i) + { + ((BYTE *)result)[i] = ((BYTE *)mask_x)[i] & ((BYTE *)mask_y)[i]; + } + + return S_OK; +} + +HRESULT WINAPI D3D10StateBlockMaskUnion(D3D10_STATE_BLOCK_MASK *mask_x, + D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result) +{ + UINT count = sizeof(*result) / sizeof(DWORD); + UINT i; + + TRACE("mask_x %p, mask_y %p, result %p.\n", mask_x, mask_y, result); + + if (!mask_x || !mask_y || !result) + return E_INVALIDARG; + + for (i = 0; i < count; ++i) + { + ((DWORD *)result)[i] = ((DWORD *)mask_x)[i] | ((DWORD *)mask_y)[i]; + } + for (i = count * sizeof(DWORD); i < sizeof(*result); ++i) + { + ((BYTE *)result)[i] = ((BYTE *)mask_x)[i] | ((BYTE *)mask_y)[i]; + } + + return S_OK; +} diff --git a/dll/directx/wine/d3d10/utils.c b/dll/directx/wine/d3d10/utils.c new file mode 100644 index 00000000000..3b518684884 --- /dev/null +++ b/dll/directx/wine/d3d10/utils.c @@ -0,0 +1,231 @@ +/* + * Copyright 2008-2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d10_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10); + +#define WINE_D3D10_TO_STR(x) case x: return #x + +const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type) +{ + switch(driver_type) + { + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_HARDWARE); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_REFERENCE); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_NULL); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_SOFTWARE); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_WARP); + default: + FIXME("Unrecognized D3D10_DRIVER_TYPE %#x\n", driver_type); + return "unrecognized"; + } +} + +const char *debug_d3d10_shader_variable_class(D3D10_SHADER_VARIABLE_CLASS c) +{ + switch (c) + { + WINE_D3D10_TO_STR(D3D10_SVC_SCALAR); + WINE_D3D10_TO_STR(D3D10_SVC_VECTOR); + WINE_D3D10_TO_STR(D3D10_SVC_MATRIX_ROWS); + WINE_D3D10_TO_STR(D3D10_SVC_MATRIX_COLUMNS); + WINE_D3D10_TO_STR(D3D10_SVC_OBJECT); + WINE_D3D10_TO_STR(D3D10_SVC_STRUCT); + default: + FIXME("Unrecognized D3D10_SHADER_VARIABLE_CLASS %#x.\n", c); + return "unrecognized"; + } +} + +const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t) +{ + switch (t) + { + WINE_D3D10_TO_STR(D3D10_SVT_VOID); + WINE_D3D10_TO_STR(D3D10_SVT_BOOL); + WINE_D3D10_TO_STR(D3D10_SVT_INT); + WINE_D3D10_TO_STR(D3D10_SVT_FLOAT); + WINE_D3D10_TO_STR(D3D10_SVT_STRING); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE1D); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE2D); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE3D); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURECUBE); + WINE_D3D10_TO_STR(D3D10_SVT_SAMPLER); + WINE_D3D10_TO_STR(D3D10_SVT_PIXELSHADER); + WINE_D3D10_TO_STR(D3D10_SVT_VERTEXSHADER); + WINE_D3D10_TO_STR(D3D10_SVT_UINT); + WINE_D3D10_TO_STR(D3D10_SVT_UINT8); + WINE_D3D10_TO_STR(D3D10_SVT_GEOMETRYSHADER); + WINE_D3D10_TO_STR(D3D10_SVT_RASTERIZER); + WINE_D3D10_TO_STR(D3D10_SVT_DEPTHSTENCIL); + WINE_D3D10_TO_STR(D3D10_SVT_BLEND); + WINE_D3D10_TO_STR(D3D10_SVT_BUFFER); + WINE_D3D10_TO_STR(D3D10_SVT_CBUFFER); + WINE_D3D10_TO_STR(D3D10_SVT_TBUFFER); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE1DARRAY); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE2DARRAY); + WINE_D3D10_TO_STR(D3D10_SVT_RENDERTARGETVIEW); + WINE_D3D10_TO_STR(D3D10_SVT_DEPTHSTENCILVIEW); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE2DMS); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURE2DMSARRAY); + WINE_D3D10_TO_STR(D3D10_SVT_TEXTURECUBEARRAY); + default: + FIXME("Unrecognized D3D10_SHADER_VARIABLE_TYPE %#x.\n", t); + return "unrecognized"; + } +} + +const char *debug_d3d10_device_state_types(D3D10_DEVICE_STATE_TYPES t) +{ + switch (t) + { + WINE_D3D10_TO_STR(D3D10_DST_SO_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_OM_RENDER_TARGETS); + WINE_D3D10_TO_STR(D3D10_DST_DEPTH_STENCIL_STATE); + WINE_D3D10_TO_STR(D3D10_DST_BLEND_STATE); + WINE_D3D10_TO_STR(D3D10_DST_VS); + WINE_D3D10_TO_STR(D3D10_DST_VS_SAMPLERS); + WINE_D3D10_TO_STR(D3D10_DST_VS_SHADER_RESOURCES); + WINE_D3D10_TO_STR(D3D10_DST_VS_CONSTANT_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_GS); + WINE_D3D10_TO_STR(D3D10_DST_GS_SAMPLERS); + WINE_D3D10_TO_STR(D3D10_DST_GS_SHADER_RESOURCES); + WINE_D3D10_TO_STR(D3D10_DST_GS_CONSTANT_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_PS); + WINE_D3D10_TO_STR(D3D10_DST_PS_SAMPLERS); + WINE_D3D10_TO_STR(D3D10_DST_PS_SHADER_RESOURCES); + WINE_D3D10_TO_STR(D3D10_DST_PS_CONSTANT_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_IA_VERTEX_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_IA_INDEX_BUFFER); + WINE_D3D10_TO_STR(D3D10_DST_IA_INPUT_LAYOUT); + WINE_D3D10_TO_STR(D3D10_DST_IA_PRIMITIVE_TOPOLOGY); + WINE_D3D10_TO_STR(D3D10_DST_RS_VIEWPORTS); + WINE_D3D10_TO_STR(D3D10_DST_RS_SCISSOR_RECTS); + WINE_D3D10_TO_STR(D3D10_DST_RS_RASTERIZER_STATE); + WINE_D3D10_TO_STR(D3D10_DST_PREDICATION); + default: + FIXME("Unrecognized D3D10_DEVICE_STATE_TYPES %#x.\n", t); + return "unrecognized"; + } +} + +#undef WINE_D3D10_TO_STR + +void skip_dword_unknown(const char *location, const char **ptr, unsigned int count) +{ + unsigned int i; + DWORD d; + + FIXME("Skipping %u unknown DWORDs (%s):\n", count, location); + for (i = 0; i < count; ++i) + { + read_dword(ptr, &d); + FIXME("\t0x%08x\n", d); + } +} + +void write_dword_unknown(char **ptr, DWORD d) +{ + FIXME("Writing unknown DWORD 0x%08x\n", d); + write_dword(ptr, d); +} + +HRESULT parse_dxbc(const char *data, SIZE_T data_size, + HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) +{ + const char *ptr = data; + HRESULT hr = S_OK; + DWORD chunk_count; + DWORD total_size; + unsigned int i; + DWORD version; + DWORD tag; + + if (!data) + { + WARN("No data supplied.\n"); + return E_FAIL; + } + + read_dword(&ptr, &tag); + TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4)); + + if (tag != TAG_DXBC) + { + WARN("Wrong tag.\n"); + return E_FAIL; + } + + /* checksum? */ + skip_dword_unknown("DXBC header", &ptr, 4); + + read_dword(&ptr, &version); + TRACE("version: %#x.\n", version); + if (version != 0x00000001) + { + WARN("Got unexpected DXBC version %#x.\n", version); + return E_FAIL; + } + + read_dword(&ptr, &total_size); + TRACE("total size: %#x\n", total_size); + + if (data_size != total_size) + { + WARN("Wrong size supplied.\n"); + return E_FAIL; + } + + read_dword(&ptr, &chunk_count); + TRACE("chunk count: %#x\n", chunk_count); + + for (i = 0; i < chunk_count; ++i) + { + DWORD chunk_tag, chunk_size; + const char *chunk_ptr; + DWORD chunk_offset; + + read_dword(&ptr, &chunk_offset); + TRACE("chunk %u at offset %#x\n", i, chunk_offset); + + if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid chunk offset %#x (data size %#lx).\n", chunk_offset, data_size); + return E_FAIL; + } + + chunk_ptr = data + chunk_offset; + + read_dword(&chunk_ptr, &chunk_tag); + read_dword(&chunk_ptr, &chunk_size); + + if (!require_space(chunk_ptr - data, 1, chunk_size, data_size)) + { + WARN("Invalid chunk size %#x (data size %#lx, chunk offset %#x).\n", chunk_size, data_size, chunk_offset); + return E_FAIL; + } + + hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx); + if (FAILED(hr)) break; + } + + return hr; +} diff --git a/dll/directx/wine/d3d10/version.rc b/dll/directx/wine/d3d10/version.rc new file mode 100644 index 00000000000..48113258092 --- /dev/null +++ b/dll/directx/wine/d3d10/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2007 Andras Kovacs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine Direct3D" +#define WINE_FILENAME_STR "d3d10.dll" +#define WINE_FILEVERSION 6,0,6000,16386 +#define WINE_FILEVERSION_STR "6.0.6000.16386" +#define WINE_PRODUCTVERSION 6,0,6000,16386 +#define WINE_PRODUCTVERSION_STR "6.0.6000.16386" + +#include "wine/wine_common_ver.rc" diff --git a/dll/directx/wine/d3d10_1/CMakeLists.txt b/dll/directx/wine/d3d10_1/CMakeLists.txt new file mode 100644 index 00000000000..0c9931c8f7e --- /dev/null +++ b/dll/directx/wine/d3d10_1/CMakeLists.txt @@ -0,0 +1,27 @@ + +add_definitions( + -D__WINESRC__) + +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/psdk) + +spec2def(d3d10_1.dll d3d10_1.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + d3d10_1_main.c) + +add_library(d3d10_1 SHARED + ${SOURCE} + version.rc + ${CMAKE_CURRENT_BINARY_DIR}/d3d10_1_stubs.c + ${CMAKE_CURRENT_BINARY_DIR}/d3d10_1.def) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(d3d10_1 PRIVATE -Wno-incompatible-pointer-types -Wno-error) # Our favourite compiler :) +endif() + +set_module_type(d3d10_1 win32dll) +target_link_libraries(d3d10_1 wine dxguid uuid) +add_dependencies(d3d10_1 wineheaders d3d_idl_headers) +add_importlibs(d3d10_1 msvcrt kernel32 ntdll dxgi d3d10core d3d10) +add_cd_file(TARGET d3d10_1 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3d10_1/Makefile.in b/dll/directx/wine/d3d10_1/Makefile.in new file mode 100644 index 00000000000..50ae0383b92 --- /dev/null +++ b/dll/directx/wine/d3d10_1/Makefile.in @@ -0,0 +1,8 @@ +MODULE = d3d10_1.dll +IMPORTLIB = d3d10_1 +IMPORTS = dxguid d3d10core dxgi + +C_SRCS = \ + d3d10_1_main.c + +RC_SRCS = version.rc diff --git a/dll/directx/wine/d3d10_1/d3d10_1.spec b/dll/directx/wine/d3d10_1/d3d10_1.spec new file mode 100644 index 00000000000..10edc3f2f79 --- /dev/null +++ b/dll/directx/wine/d3d10_1/d3d10_1.spec @@ -0,0 +1,30 @@ +@ stub RevertToOldImplementation +@ stdcall D3D10CompileEffectFromMemory(ptr long ptr ptr ptr long long ptr ptr) d3d10.D3D10CompileEffectFromMemory +@ stdcall D3D10CompileShader(ptr long str ptr ptr str str long ptr ptr) d3d10.D3D10CompileShader +@ stdcall D3D10CreateBlob(long ptr) d3d10.D3D10CreateBlob +@ stdcall D3D10CreateDevice1(ptr long ptr long long long ptr) +@ stdcall D3D10CreateDeviceAndSwapChain1(ptr long ptr long long long ptr ptr ptr) +@ stdcall D3D10CreateEffectFromMemory(ptr long long ptr ptr ptr) d3d10.D3D10CreateEffectFromMemory +@ stdcall D3D10CreateEffectPoolFromMemory(ptr long long ptr ptr) d3d10.D3D10CreateEffectPoolFromMemory +@ stdcall D3D10CreateStateBlock(ptr ptr ptr) d3d10.D3D10CreateStateBlock +@ stub D3D10DisassembleEffect +@ stdcall D3D10DisassembleShader(ptr long long ptr ptr) d3d10.D3D10DisassembleShader +@ stdcall D3D10GetGeometryShaderProfile(ptr) d3d10.D3D10GetGeometryShaderProfile +@ stdcall D3D10GetInputAndOutputSignatureBlob(ptr long ptr) d3d10.D3D10GetInputAndOutputSignatureBlob +@ stdcall D3D10GetInputSignatureBlob(ptr long ptr) d3d10.D3D10GetInputSignatureBlob +@ stdcall D3D10GetOutputSignatureBlob(ptr long ptr) d3d10.D3D10GetOutputSignatureBlob +@ stdcall D3D10GetPixelShaderProfile(ptr) d3d10.D3D10GetPixelShaderProfile +@ stdcall D3D10GetShaderDebugInfo(ptr long ptr) d3d10.D3D10GetShaderDebugInfo +@ stub D3D10GetVersion +@ stdcall D3D10GetVertexShaderProfile(ptr) d3d10.D3D10GetVertexShaderProfile +@ stub D3D10PreprocessShader +@ stdcall D3D10ReflectShader(ptr long ptr) d3d10.D3D10ReflectShader +@ stub D3D10RegisterLayers +@ stdcall D3D10StateBlockMaskDifference(ptr ptr ptr) d3d10.D3D10StateBlockMaskDifference +@ stdcall D3D10StateBlockMaskDisableAll(ptr) d3d10.D3D10StateBlockMaskDisableAll +@ stdcall D3D10StateBlockMaskDisableCapture(ptr long long long) d3d10.D3D10StateBlockMaskDisableCapture +@ stdcall D3D10StateBlockMaskEnableAll(ptr) d3d10.D3D10StateBlockMaskEnableAll +@ stdcall D3D10StateBlockMaskEnableCapture(ptr long long long) d3d10.D3D10StateBlockMaskEnableCapture +@ stdcall D3D10StateBlockMaskGetSetting(ptr long long) d3d10.D3D10StateBlockMaskGetSetting +@ stdcall D3D10StateBlockMaskIntersect(ptr ptr ptr) d3d10.D3D10StateBlockMaskIntersect +@ stdcall D3D10StateBlockMaskUnion(ptr ptr ptr) d3d10.D3D10StateBlockMaskUnion diff --git a/dll/directx/wine/d3d10_1/d3d10_1_main.c b/dll/directx/wine/d3d10_1/d3d10_1_main.c new file mode 100644 index 00000000000..8ee5aa71f79 --- /dev/null +++ b/dll/directx/wine/d3d10_1/d3d10_1_main.c @@ -0,0 +1,253 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + +#define COBJMACROS +#include "d3d10_1.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10); + +HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, + unsigned int flags, D3D_FEATURE_LEVEL feature_level, ID3D10Device **device); + +#define WINE_D3D10_TO_STR(x) case x: return #x + +static const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type) +{ + switch (driver_type) + { + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_HARDWARE); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_REFERENCE); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_NULL); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_SOFTWARE); + WINE_D3D10_TO_STR(D3D10_DRIVER_TYPE_WARP); + default: + FIXME("Unrecognized D3D10_DRIVER_TYPE %#x.\n", driver_type); + return "unrecognized"; + } +} + +static const char *debug_d3d10_feature_level(D3D10_FEATURE_LEVEL1 feature_level) +{ + switch (feature_level) + { + WINE_D3D10_TO_STR(D3D10_FEATURE_LEVEL_10_0); + WINE_D3D10_TO_STR(D3D10_FEATURE_LEVEL_10_1); + WINE_D3D10_TO_STR(D3D10_FEATURE_LEVEL_9_1); + WINE_D3D10_TO_STR(D3D10_FEATURE_LEVEL_9_2); + WINE_D3D10_TO_STR(D3D10_FEATURE_LEVEL_9_3); + default: + FIXME("Unrecognized D3D10_FEATURE_LEVEL1 %#x.\n", feature_level); + return "unrecognized"; + } +} + +#undef WINE_D3D10_TO_STR + +static HRESULT d3d10_create_device1(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, HMODULE swrast, + UINT flags, D3D10_FEATURE_LEVEL1 hw_level, UINT sdk_version, ID3D10Device1 **device) +{ + IDXGIFactory *factory; + HRESULT hr; + + TRACE("adapter %p, driver_type %s, swrast %p, flags %#x, hw_level %s, sdk_version %d, device %p.\n", + adapter, debug_d3d10_driver_type(driver_type), swrast, flags, + debug_d3d10_feature_level(hw_level), sdk_version, device); + + if (!device) + return E_INVALIDARG; + + *device = NULL; + + if (!hw_level) + return E_INVALIDARG; + + if (adapter) + { + IDXGIAdapter_AddRef(adapter); + if (FAILED(hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory))) + { + WARN("Failed to get dxgi factory, hr %#x.\n", hr); + return hr; + } + } + else + { + if (FAILED(hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory))) + { + WARN("Failed to create dxgi factory, hr %#x.\n", hr); + return hr; + } + + switch (driver_type) + { + case D3D10_DRIVER_TYPE_WARP: + FIXME("WARP driver not implemented, falling back to hardware.\n"); + case D3D10_DRIVER_TYPE_HARDWARE: + { + if (FAILED(hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter))) + { + WARN("No adapters found, hr %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + case D3D10_DRIVER_TYPE_NULL: + FIXME("NULL device not implemented, falling back to refrast.\n"); + /* Fall through, for now. */ + case D3D10_DRIVER_TYPE_REFERENCE: + { + HMODULE refrast; + + if (!(refrast = LoadLibraryA("d3d10ref.dll"))) + { + WARN("Failed to load refrast, returning E_FAIL.\n"); + IDXGIFactory_Release(factory); + return E_FAIL; + } + hr = IDXGIFactory_CreateSoftwareAdapter(factory, refrast, &adapter); + FreeLibrary(refrast); + if (FAILED(hr)) + { + WARN("Failed to create a software adapter, hr %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + case D3D10_DRIVER_TYPE_SOFTWARE: + { + if (!swrast) + { + WARN("Software device requested, but NULL swrast passed, returning E_FAIL.\n"); + IDXGIFactory_Release(factory); + return E_FAIL; + } + if (FAILED(hr = IDXGIFactory_CreateSoftwareAdapter(factory, swrast, &adapter))) + { + WARN("Failed to create a software adapter, hr %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + default: + FIXME("Unhandled driver type %#x.\n", driver_type); + IDXGIFactory_Release(factory); + return E_FAIL; + } + } + + hr = D3D10CoreCreateDevice(factory, adapter, flags, hw_level, (ID3D10Device **)device); + IDXGIAdapter_Release(adapter); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create a device, hr %#x.\n", hr); + return hr; + } + + TRACE("Created device %p.\n", *device); + + return hr; +} + +HRESULT WINAPI D3D10CreateDevice1(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, HMODULE swrast, + UINT flags, D3D10_FEATURE_LEVEL1 hw_level, UINT sdk_version, ID3D10Device1 **device) +{ + return d3d10_create_device1(adapter, driver_type, swrast, flags, hw_level, sdk_version, device); +} + +HRESULT WINAPI D3D10CreateDeviceAndSwapChain1(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, D3D10_FEATURE_LEVEL1 feature_level, UINT sdk_version, + DXGI_SWAP_CHAIN_DESC *swapchain_desc, IDXGISwapChain **swapchain, ID3D10Device1 **device) +{ + IDXGIDevice *dxgi_device; + IDXGIFactory *factory; + HRESULT hr; + + TRACE("adapter %p, driver_type %s, swrast %p, flags %#x, " + "feature_level %s, sdk_version %d, swapchain_desc %p, swapchain %p, device %p.\n", + adapter, debug_d3d10_driver_type(driver_type), swrast, flags, + debug_d3d10_feature_level(feature_level), sdk_version, swapchain_desc, swapchain, device); + + if (swapchain) + *swapchain = NULL; + + if (!device) + return E_INVALIDARG; + + /* Avoid forwarding to D3D10CreateDevice1(), since it breaks applications + * hooking these entry-points. */ + if (FAILED(hr = d3d10_create_device1(adapter, driver_type, swrast, flags, feature_level, sdk_version, device))) + { + WARN("Failed to create a device, returning %#x.\n", hr); + *device = NULL; + return hr; + } + + if (swapchain) + { + if (FAILED(hr = ID3D10Device1_QueryInterface(*device, &IID_IDXGIDevice, (void **)&dxgi_device))) + { + ERR("Failed to get a dxgi device from the d3d10 device, returning %#x.\n", hr); + goto cleanup; + } + + hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter); + IDXGIDevice_Release(dxgi_device); + if (FAILED(hr)) + { + ERR("Failed to get the device adapter, returning %#x.\n", hr); + goto cleanup; + } + + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); + IDXGIAdapter_Release(adapter); + if (FAILED(hr)) + { + ERR("Failed to get the adapter factory, returning %#x.\n", hr); + goto cleanup; + } + + hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)*device, swapchain_desc, swapchain); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create a swapchain, returning %#x.\n", hr); + goto cleanup; + } + + TRACE("Created IDXGISwapChain %p.\n", *swapchain); + } + + return S_OK; + +cleanup: + ID3D10Device1_Release(*device); + *device = NULL; + return hr; +} diff --git a/dll/directx/wine/d3d10_1/version.rc b/dll/directx/wine/d3d10_1/version.rc new file mode 100644 index 00000000000..1e3039c3ea6 --- /dev/null +++ b/dll/directx/wine/d3d10_1/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine Direct3D" +#define WINE_FILENAME_STR "d3d10_1.dll" +#define WINE_FILEVERSION 6,2,9200,16492 +#define WINE_FILEVERSION_STR "6.2.9200.16492" +#define WINE_PRODUCTVERSION 6,2,9200,16492 +#define WINE_PRODUCTVERSION_STR "6.2.9200.16492" + +#include "wine/wine_common_ver.rc" diff --git a/dll/directx/wine/d3d10core/CMakeLists.txt b/dll/directx/wine/d3d10core/CMakeLists.txt new file mode 100644 index 00000000000..9f7b32deac2 --- /dev/null +++ b/dll/directx/wine/d3d10core/CMakeLists.txt @@ -0,0 +1,23 @@ + +add_definitions( + -D__WINESRC__ + -DUSE_WIN32_OPENGL) + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) + +spec2def(d3d10core.dll d3d10core.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + d3d10core_main.c) + +add_library(d3d10core SHARED + ${SOURCE} + version.rc + ${CMAKE_CURRENT_BINARY_DIR}/d3d10core_stubs.c + ${CMAKE_CURRENT_BINARY_DIR}/d3d10core.def) + +set_module_type(d3d10core win32dll) +target_link_libraries(d3d10core wine uuid) +add_dependencies(d3d10core d3d_idl_headers) +add_importlibs(d3d10core d3dwine d3d11 msvcrt dxgi kernel32 ntdll) +add_cd_file(TARGET d3d10core DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3d10core/d3d10core.spec b/dll/directx/wine/d3d10core/d3d10core.spec new file mode 100644 index 00000000000..9bf25b5c7f4 --- /dev/null +++ b/dll/directx/wine/d3d10core/d3d10core.spec @@ -0,0 +1,2 @@ +@ stdcall D3D10CoreCreateDevice(ptr ptr long long ptr) +@ stdcall D3D10CoreRegisterLayers() diff --git a/dll/directx/wine/d3d10core/d3d10core_main.c b/dll/directx/wine/d3d10core/d3d10core_main.c new file mode 100644 index 00000000000..d364be90d6d --- /dev/null +++ b/dll/directx/wine/d3d10core/d3d10core_main.c @@ -0,0 +1,60 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "wine/debug.h" + +#include "initguid.h" + +#define COBJMACROS +#include "d3d11.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); + +HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, unsigned int flags, + const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count, ID3D11Device **device); + +HRESULT WINAPI D3D10CoreRegisterLayers(void) +{ + TRACE("\n"); + + return E_NOTIMPL; +} + +HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, + unsigned int flags, D3D_FEATURE_LEVEL feature_level, ID3D10Device **device) +{ + ID3D11Device *device11; + HRESULT hr; + + TRACE("factory %p, adapter %p, flags %#x, feature_level %#x, device %p.\n", + factory, adapter, flags, feature_level, device); + + if (FAILED(hr = D3D11CoreCreateDevice(factory, adapter, flags, &feature_level, 1, &device11))) + return hr; + + hr = ID3D11Device_QueryInterface(device11, &IID_ID3D10Device, (void **)device); + ID3D11Device_Release(device11); + if (FAILED(hr)) + { + ERR("Device should implement ID3D10Device, returning E_FAIL.\n"); + return E_FAIL; + } + + return S_OK; +} diff --git a/dll/directx/wine/d3d10core/version.rc b/dll/directx/wine/d3d10core/version.rc new file mode 100644 index 00000000000..d02e8711fe4 --- /dev/null +++ b/dll/directx/wine/d3d10core/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine D3D10 Core" +#define WINE_FILENAME_STR "d3d10core.dll" +#define WINE_FILEVERSION 6,0,6000,16386 +#define WINE_FILEVERSION_STR "6.0.6000.16386" +#define WINE_PRODUCTVERSION 6,0,6000,16386 +#define WINE_PRODUCTVERSION_STR "6.0.6000.16386" + +#include "wine/wine_common_ver.rc" diff --git a/dll/directx/wine/d3d11/CMakeLists.txt b/dll/directx/wine/d3d11/CMakeLists.txt new file mode 100644 index 00000000000..95e6018dd0a --- /dev/null +++ b/dll/directx/wine/d3d11/CMakeLists.txt @@ -0,0 +1,32 @@ + +add_definitions( + -D__WINESRC__ + -DUSE_WIN32_OPENGL) + +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/psdk) + +spec2def(d3d11.dll d3d11.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + async.c + buffer.c + d3d11_main.c + device.c + inputlayout.c + shader.c + state.c + texture.c + utils.c + view.c) + +add_library(d3d11 SHARED + ${SOURCE} + ${CMAKE_CURRENT_BINARY_DIR}/d3d11_stubs.c + ${CMAKE_CURRENT_BINARY_DIR}/d3d11.def) + +set_module_type(d3d11 win32dll) +target_link_libraries(d3d11 wine uuid dxguid) +add_importlibs(d3d11 d3dwine msvcrt dxgi kernel32 ntdll gdi32) +add_dependencies(d3d11 wineheaders d3d_idl_headers) +add_cd_file(TARGET d3d11 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3d11/async.c b/dll/directx/wine/d3d11/async.c new file mode 100644 index 00000000000..fd83871220d --- /dev/null +++ b/dll/directx/wine/d3d11/async.c @@ -0,0 +1,515 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2015-2017 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +/* ID3D11Query methods */ + +static inline struct d3d_query *impl_from_ID3D11Query(ID3D11Query *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_query, ID3D11Query_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_query_QueryInterface(ID3D11Query *iface, REFIID riid, void **object) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if ((IsEqualGUID(riid, &IID_ID3D11Predicate) && query->predicate) + || IsEqualGUID(riid, &IID_ID3D11Query) + || IsEqualGUID(riid, &IID_ID3D11Asynchronous) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11Query_AddRef(iface); + *object = iface; + return S_OK; + } + + if ((IsEqualGUID(riid, &IID_ID3D10Predicate) && query->predicate) + || IsEqualGUID(riid, &IID_ID3D10Query) + || IsEqualGUID(riid, &IID_ID3D10Asynchronous) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10Query_AddRef(&query->ID3D10Query_iface); + *object = &query->ID3D10Query_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_query_AddRef(ID3D11Query *iface) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + ULONG refcount = InterlockedIncrement(&query->refcount); + + TRACE("%p increasing refcount to %u.\n", query, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(query->device); + wined3d_mutex_lock(); + wined3d_query_incref(query->wined3d_query); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_query_Release(ID3D11Query *iface) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + ULONG refcount = InterlockedDecrement(&query->refcount); + + TRACE("%p decreasing refcount to %u.\n", query, refcount); + + if (!refcount) + { + ID3D11Device2 *device = query->device; + + wined3d_mutex_lock(); + wined3d_query_decref(query->wined3d_query); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_query_GetDevice(ID3D11Query *iface, ID3D11Device **device) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)query->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_query_GetPrivateData(ID3D11Query *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&query->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_query_SetPrivateData(ID3D11Query *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&query->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_query_SetPrivateDataInterface(ID3D11Query *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&query->private_store, guid, data); +} + +static UINT STDMETHODCALLTYPE d3d11_query_GetDataSize(ID3D11Query *iface) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + unsigned int data_size; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + data_size = wined3d_query_get_data_size(query->wined3d_query); + wined3d_mutex_unlock(); + + return data_size; +} + +static void STDMETHODCALLTYPE d3d11_query_GetDesc(ID3D11Query *iface, D3D11_QUERY_DESC *desc) +{ + struct d3d_query *query = impl_from_ID3D11Query(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = query->desc; +} + +static const struct ID3D11QueryVtbl d3d11_query_vtbl = +{ + /* IUnknown methods */ + d3d11_query_QueryInterface, + d3d11_query_AddRef, + d3d11_query_Release, + /* ID3D11DeviceChild methods */ + d3d11_query_GetDevice, + d3d11_query_GetPrivateData, + d3d11_query_SetPrivateData, + d3d11_query_SetPrivateDataInterface, + /* ID3D11Asynchronous methods */ + d3d11_query_GetDataSize, + /* ID3D11Query methods */ + d3d11_query_GetDesc, +}; + +static void STDMETHODCALLTYPE d3d_query_wined3d_object_destroyed(void *parent) +{ + struct d3d_query *query = parent; + + wined3d_private_store_cleanup(&query->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_query_wined3d_parent_ops = +{ + d3d_query_wined3d_object_destroyed, +}; + +struct d3d_query *unsafe_impl_from_ID3D11Query(ID3D11Query *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_query_vtbl); + return CONTAINING_RECORD(iface, struct d3d_query, ID3D11Query_iface); +} + +struct d3d_query *unsafe_impl_from_ID3D11Asynchronous(ID3D11Asynchronous *iface) +{ + return unsafe_impl_from_ID3D11Query((ID3D11Query *)iface); +} + +/* ID3D10Query methods */ + +static inline struct d3d_query *impl_from_ID3D10Query(ID3D10Query *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_query, ID3D10Query_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_query_QueryInterface(ID3D10Query *iface, REFIID riid, void **object) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_query_QueryInterface(&query->ID3D11Query_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_query_AddRef(ID3D10Query *iface) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_query_AddRef(&query->ID3D11Query_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_query_Release(ID3D10Query *iface) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_query_Release(&query->ID3D11Query_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_query_GetDevice(ID3D10Query *iface, ID3D10Device **device) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(query->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_query_GetPrivateData(ID3D10Query *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&query->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_query_SetPrivateData(ID3D10Query *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&query->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_query_SetPrivateDataInterface(ID3D10Query *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&query->private_store, guid, data); +} + +/* ID3D10Asynchronous methods */ + +static void STDMETHODCALLTYPE d3d10_query_Begin(ID3D10Query *iface) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + HRESULT hr; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_query_issue(query->wined3d_query, WINED3DISSUE_BEGIN))) + ERR("Failed to issue query, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_query_End(ID3D10Query *iface) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + HRESULT hr; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_query_issue(query->wined3d_query, WINED3DISSUE_END))) + ERR("Failed to issue query, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static HRESULT STDMETHODCALLTYPE d3d10_query_GetData(ID3D10Query *iface, void *data, UINT data_size, UINT flags) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + D3D11_QUERY_DATA_PIPELINE_STATISTICS d3d11_data; + void *d3d10_data_pointer = NULL; + unsigned int wined3d_flags; + HRESULT hr; + + TRACE("iface %p, data %p, data_size %u, flags %#x.\n", iface, data, data_size, flags); + + if (!data && data_size) + return E_INVALIDARG; + + if (query->desc.Query == D3D11_QUERY_PIPELINE_STATISTICS + && data_size == sizeof(D3D10_QUERY_DATA_PIPELINE_STATISTICS)) + { + data_size = sizeof(D3D11_QUERY_DATA_PIPELINE_STATISTICS); + d3d10_data_pointer = data; + data = &d3d11_data; + } + + wined3d_flags = wined3d_getdata_flags_from_d3d11_async_getdata_flags(flags); + + wined3d_mutex_lock(); + if (!data_size || wined3d_query_get_data_size(query->wined3d_query) == data_size) + { + hr = wined3d_query_get_data(query->wined3d_query, data, data_size, wined3d_flags); + if (hr == WINED3DERR_INVALIDCALL) + hr = DXGI_ERROR_INVALID_CALL; + } + else + { + WARN("Invalid data size %u.\n", data_size); + hr = E_INVALIDARG; + } + wined3d_mutex_unlock(); + + if (d3d10_data_pointer && hr == S_OK) + memcpy(d3d10_data_pointer, data, sizeof(D3D10_QUERY_DATA_PIPELINE_STATISTICS)); + + return hr; +} + +static UINT STDMETHODCALLTYPE d3d10_query_GetDataSize(ID3D10Query *iface) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + unsigned int data_size; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + data_size = wined3d_query_get_data_size(query->wined3d_query); + wined3d_mutex_unlock(); + + if (query->desc.Query == D3D11_QUERY_PIPELINE_STATISTICS) + data_size = sizeof(D3D10_QUERY_DATA_PIPELINE_STATISTICS); + + return data_size; +} + +/* ID3D10Query methods */ + +static void STDMETHODCALLTYPE d3d10_query_GetDesc(ID3D10Query *iface, D3D10_QUERY_DESC *desc) +{ + struct d3d_query *query = impl_from_ID3D10Query(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &query->desc, sizeof(*desc)); +} + +static const struct ID3D10QueryVtbl d3d10_query_vtbl = +{ + /* IUnknown methods */ + d3d10_query_QueryInterface, + d3d10_query_AddRef, + d3d10_query_Release, + /* ID3D10DeviceChild methods */ + d3d10_query_GetDevice, + d3d10_query_GetPrivateData, + d3d10_query_SetPrivateData, + d3d10_query_SetPrivateDataInterface, + /* ID3D10Asynchronous methods */ + d3d10_query_Begin, + d3d10_query_End, + d3d10_query_GetData, + d3d10_query_GetDataSize, + /* ID3D10Query methods */ + d3d10_query_GetDesc, +}; + +struct d3d_query *unsafe_impl_from_ID3D10Query(ID3D10Query *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_query_vtbl); + return CONTAINING_RECORD(iface, struct d3d_query, ID3D10Query_iface); +} + +static HRESULT d3d_query_init(struct d3d_query *query, struct d3d_device *device, + const D3D11_QUERY_DESC *desc, BOOL predicate) +{ + HRESULT hr; + + static const enum wined3d_query_type query_type_map[] = + { + /* D3D11_QUERY_EVENT */ WINED3D_QUERY_TYPE_EVENT, + /* D3D11_QUERY_OCCLUSION */ WINED3D_QUERY_TYPE_OCCLUSION, + /* D3D11_QUERY_TIMESTAMP */ WINED3D_QUERY_TYPE_TIMESTAMP, + /* D3D11_QUERY_TIMESTAMP_DISJOINT */ WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT, + /* D3D11_QUERY_PIPELINE_STATISTICS */ WINED3D_QUERY_TYPE_PIPELINE_STATISTICS, + /* D3D11_QUERY_OCCLUSION_PREDICATE */ WINED3D_QUERY_TYPE_OCCLUSION, + /* D3D11_QUERY_SO_STATISTICS */ WINED3D_QUERY_TYPE_SO_STATISTICS, + /* D3D11_QUERY_SO_OVERFLOW_PREDICATE */ WINED3D_QUERY_TYPE_SO_OVERFLOW, + /* D3D11_QUERY_SO_STATISTICS_STREAM0 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0, + /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM0, + /* D3D11_QUERY_SO_STATISTICS_STREAM1 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1, + /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM1, + /* D3D11_QUERY_SO_STATISTICS_STREAM2 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2, + /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM2, + /* D3D11_QUERY_SO_STATISTICS_STREAM3 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3, + /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM3, + }; + + if (desc->Query >= ARRAY_SIZE(query_type_map)) + { + FIXME("Unhandled query type %#x.\n", desc->Query); + return E_INVALIDARG; + } + + if (desc->MiscFlags) + FIXME("Ignoring MiscFlags %#x.\n", desc->MiscFlags); + + query->ID3D11Query_iface.lpVtbl = &d3d11_query_vtbl; + query->ID3D10Query_iface.lpVtbl = &d3d10_query_vtbl; + query->refcount = 1; + + query->desc = *desc; + + wined3d_mutex_lock(); + wined3d_private_store_init(&query->private_store); + + if (FAILED(hr = wined3d_query_create(device->wined3d_device, query_type_map[desc->Query], + query, &d3d_query_wined3d_parent_ops, &query->wined3d_query))) + { + WARN("Failed to create wined3d query, hr %#x.\n", hr); + wined3d_private_store_cleanup(&query->private_store); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_unlock(); + + query->predicate = predicate; + ID3D11Device2_AddRef(query->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_query_create(struct d3d_device *device, const D3D11_QUERY_DESC *desc, BOOL predicate, + struct d3d_query **query) +{ + struct d3d_query *object; + BOOL is_predicate_type; + HRESULT hr; + + if (!desc) + return E_INVALIDARG; + + is_predicate_type = desc->Query == D3D11_QUERY_OCCLUSION_PREDICATE + || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE + || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0 + || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1 + || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2 + || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3; + + if (!is_predicate_type && predicate) + { + WARN("Query type %u is not a predicate.\n", desc->Query); + return E_INVALIDARG; + } + + if (is_predicate_type) + predicate = TRUE; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_query_init(object, device, desc, predicate))) + { + WARN("Failed to initialize predicate, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created query %p.\n", object); + *query = object; + + return S_OK; +} diff --git a/dll/directx/wine/d3d11/buffer.c b/dll/directx/wine/d3d11/buffer.c new file mode 100644 index 00000000000..ed9ee133118 --- /dev/null +++ b/dll/directx/wine/d3d11/buffer.c @@ -0,0 +1,495 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +/* ID3D11Buffer methods */ + +static inline struct d3d_buffer *impl_from_ID3D11Buffer(ID3D11Buffer *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_buffer, ID3D11Buffer_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_buffer_QueryInterface(ID3D11Buffer *iface, REFIID riid, void **out) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_ID3D11Buffer) + || IsEqualGUID(riid, &IID_ID3D11Resource) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11Buffer_AddRef(iface); + *out = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10Buffer) + || IsEqualGUID(riid, &IID_ID3D10Resource) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10Buffer_AddRef(&buffer->ID3D10Buffer_iface); + *out = &buffer->ID3D10Buffer_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_buffer_AddRef(ID3D11Buffer *iface) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + ULONG refcount = InterlockedIncrement(&buffer->refcount); + + TRACE("%p increasing refcount to %u.\n", buffer, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(buffer->device); + wined3d_mutex_lock(); + wined3d_buffer_incref(buffer->wined3d_buffer); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_buffer_Release(ID3D11Buffer *iface) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + ULONG refcount = InterlockedDecrement(&buffer->refcount); + + TRACE("%p decreasing refcount to %u.\n", buffer, refcount); + + if (!refcount) + { + ID3D11Device2 *device = buffer->device; + + wined3d_mutex_lock(); + wined3d_buffer_decref(buffer->wined3d_buffer); + wined3d_mutex_unlock(); + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_buffer_GetDevice(ID3D11Buffer *iface, ID3D11Device **device) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)buffer->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_buffer_GetPrivateData(ID3D11Buffer *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&buffer->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_buffer_SetPrivateData(ID3D11Buffer *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&buffer->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_buffer_SetPrivateDataInterface(ID3D11Buffer *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&buffer->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_buffer_GetType(ID3D11Buffer *iface, + D3D11_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension); + + *resource_dimension = D3D11_RESOURCE_DIMENSION_BUFFER; +} + +static void STDMETHODCALLTYPE d3d11_buffer_SetEvictionPriority(ID3D11Buffer *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d11_buffer_GetEvictionPriority(ID3D11Buffer *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d3d11_buffer_GetDesc(ID3D11Buffer *iface, D3D11_BUFFER_DESC *desc) +{ + struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = buffer->desc; +} + +static const struct ID3D11BufferVtbl d3d11_buffer_vtbl = +{ + /* IUnknown methods */ + d3d11_buffer_QueryInterface, + d3d11_buffer_AddRef, + d3d11_buffer_Release, + /* ID3D11DeviceChild methods */ + d3d11_buffer_GetDevice, + d3d11_buffer_GetPrivateData, + d3d11_buffer_SetPrivateData, + d3d11_buffer_SetPrivateDataInterface, + /* ID3D11Resource methods */ + d3d11_buffer_GetType, + d3d11_buffer_SetEvictionPriority, + d3d11_buffer_GetEvictionPriority, + /* ID3D11Buffer methods */ + d3d11_buffer_GetDesc, +}; + +struct d3d_buffer *unsafe_impl_from_ID3D11Buffer(ID3D11Buffer *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_buffer_vtbl); + return CONTAINING_RECORD(iface, struct d3d_buffer, ID3D11Buffer_iface); +} + +/* ID3D10Buffer methods */ + +static inline struct d3d_buffer *impl_from_ID3D10Buffer(ID3D10Buffer *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_buffer, ID3D10Buffer_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_buffer_QueryInterface(ID3D10Buffer *iface, REFIID riid, void **out) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + return d3d11_buffer_QueryInterface(&buffer->ID3D11Buffer_iface, riid, out); +} + +static ULONG STDMETHODCALLTYPE d3d10_buffer_AddRef(ID3D10Buffer *iface) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_buffer_AddRef(&buffer->ID3D11Buffer_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_buffer_Release(ID3D10Buffer *iface) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_buffer_Release(&buffer->ID3D11Buffer_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_buffer_GetDevice(ID3D10Buffer *iface, ID3D10Device **device) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(buffer->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_buffer_GetPrivateData(ID3D10Buffer *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&buffer->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_buffer_SetPrivateData(ID3D10Buffer *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&buffer->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_buffer_SetPrivateDataInterface(ID3D10Buffer *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&buffer->private_store, guid, data); +} + +/* ID3D10Resource methods */ + +static void STDMETHODCALLTYPE d3d10_buffer_GetType(ID3D10Buffer *iface, D3D10_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p\n", iface, resource_dimension); + + *resource_dimension = D3D10_RESOURCE_DIMENSION_BUFFER; +} + +static void STDMETHODCALLTYPE d3d10_buffer_SetEvictionPriority(ID3D10Buffer *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d10_buffer_GetEvictionPriority(ID3D10Buffer *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +/* ID3D10Buffer methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_buffer_Map(ID3D10Buffer *iface, D3D10_MAP map_type, UINT map_flags, void **data) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + struct wined3d_map_desc wined3d_map_desc; + HRESULT hr; + + TRACE("iface %p, map_type %u, map_flags %#x, data %p.\n", iface, map_type, map_flags, data); + + if (map_flags) + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_mutex_lock(); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0, + &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)); + *data = wined3d_map_desc.data; + wined3d_mutex_unlock(); + + return hr; +} + +static void STDMETHODCALLTYPE d3d10_buffer_Unmap(ID3D10Buffer *iface) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_buffer_GetDesc(ID3D10Buffer *iface, D3D10_BUFFER_DESC *desc) +{ + struct d3d_buffer *buffer = impl_from_ID3D10Buffer(iface); + const D3D11_BUFFER_DESC *d3d11_desc = &buffer->desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + desc->ByteWidth = d3d11_desc->ByteWidth; + desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc->Usage); + desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc->BindFlags); + desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc->CPUAccessFlags); + desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc->MiscFlags); +} + +static const struct ID3D10BufferVtbl d3d10_buffer_vtbl = +{ + /* IUnknown methods */ + d3d10_buffer_QueryInterface, + d3d10_buffer_AddRef, + d3d10_buffer_Release, + /* ID3D10DeviceChild methods */ + d3d10_buffer_GetDevice, + d3d10_buffer_GetPrivateData, + d3d10_buffer_SetPrivateData, + d3d10_buffer_SetPrivateDataInterface, + /* ID3D10Resource methods */ + d3d10_buffer_GetType, + d3d10_buffer_SetEvictionPriority, + d3d10_buffer_GetEvictionPriority, + /* ID3D10Buffer methods */ + d3d10_buffer_Map, + d3d10_buffer_Unmap, + d3d10_buffer_GetDesc, +}; + +struct d3d_buffer *unsafe_impl_from_ID3D10Buffer(ID3D10Buffer *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_buffer_vtbl); + return CONTAINING_RECORD(iface, struct d3d_buffer, ID3D10Buffer_iface); +} + +static void STDMETHODCALLTYPE d3d_buffer_wined3d_object_released(void *parent) +{ + struct d3d_buffer *buffer = parent; + + wined3d_private_store_cleanup(&buffer->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_buffer_wined3d_parent_ops = +{ + d3d_buffer_wined3d_object_released, +}; + +static BOOL validate_buffer_desc(D3D11_BUFFER_DESC *desc, D3D_FEATURE_LEVEL feature_level) +{ + if (!validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION_BUFFER, + desc->Usage, desc->BindFlags, desc->CPUAccessFlags, feature_level)) + return FALSE; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) + { + if (desc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) + { + WARN("Raw and structure buffers are mutually exclusive.\n"); + return FALSE; + } + if (!(desc->BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS))) + { + WARN("Invalid bind flags %#x for raw buffer.\n", desc->BindFlags); + return FALSE; + } + } + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) + { + if (!desc->StructureByteStride || desc->StructureByteStride % 4) + { + WARN("Invalid structure byte stride %u.\n", desc->StructureByteStride); + return FALSE; + } + if (desc->ByteWidth % desc->StructureByteStride) + { + WARN("Byte width %u is not divisible by structure byte stride %u.\n", + desc->ByteWidth, desc->StructureByteStride); + return FALSE; + } + } + else + { + desc->StructureByteStride = 0; + } + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) + { + WARN("Buffer with the D3D11_RESOURCE_MISC_GENERATE_MIPS flag.\n"); + return FALSE; + } + + return TRUE; +} + +static HRESULT d3d_buffer_init(struct d3d_buffer *buffer, struct d3d_device *device, + const D3D11_BUFFER_DESC *desc, const D3D11_SUBRESOURCE_DATA *data) +{ + struct wined3d_buffer_desc wined3d_desc; + HRESULT hr; + + buffer->ID3D11Buffer_iface.lpVtbl = &d3d11_buffer_vtbl; + buffer->ID3D10Buffer_iface.lpVtbl = &d3d10_buffer_vtbl; + buffer->refcount = 1; + buffer->desc = *desc; + + if (!validate_buffer_desc(&buffer->desc, device->feature_level)) + return E_INVALIDARG; + + wined3d_desc.byte_width = buffer->desc.ByteWidth; + wined3d_desc.usage = wined3d_usage_from_d3d11(buffer->desc.Usage); + wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(buffer->desc.BindFlags); + wined3d_desc.access = wined3d_access_from_d3d11(buffer->desc.Usage, buffer->desc.CPUAccessFlags); + wined3d_desc.misc_flags = buffer->desc.MiscFlags; + wined3d_desc.structure_byte_stride = buffer->desc.StructureByteStride; + + wined3d_mutex_lock(); + wined3d_private_store_init(&buffer->private_store); + + if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &wined3d_desc, + (const struct wined3d_sub_resource_data *)data, buffer, + &d3d_buffer_wined3d_parent_ops, &buffer->wined3d_buffer))) + { + WARN("Failed to create wined3d buffer, hr %#x.\n", hr); + wined3d_private_store_cleanup(&buffer->private_store); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(buffer->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_buffer_create(struct d3d_device *device, const D3D11_BUFFER_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_buffer **buffer) +{ + struct d3d_buffer *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_buffer_init(object, device, desc, data))) + { + WARN("Failed to initialize buffer, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created buffer %p.\n", object); + *buffer = object; + + return S_OK; +} diff --git a/dll/directx/wine/d3d11/d3d11.spec b/dll/directx/wine/d3d11/d3d11.spec new file mode 100644 index 00000000000..08a597f6f7d --- /dev/null +++ b/dll/directx/wine/d3d11/d3d11.spec @@ -0,0 +1,44 @@ +@ stdcall D3D11CoreCreateDevice(ptr ptr long ptr long ptr) +@ stub D3D11CoreCreateLayeredDevice +@ stub D3D11CoreGetLayeredDeviceSize +@ stdcall D3D11CoreRegisterLayers() +@ stdcall D3D11CreateDevice(ptr long ptr long ptr long long ptr ptr ptr) +@ stdcall D3D11CreateDeviceAndSwapChain(ptr long ptr long ptr long long ptr ptr ptr ptr ptr) +@ stdcall D3D11On12CreateDevice(ptr long ptr long ptr long long ptr ptr ptr) +@ stdcall -stub D3DKMTCloseAdapter(ptr) ;gdi32.D3DKMTCloseAdapter +@ stub D3DKMTCreateAllocation +@ stub D3DKMTCreateContext +@ stdcall -stub D3DKMTCreateDevice(ptr) ;gdi32.D3DKMTCreateDevice +@ stub D3DKMTCreateSynchronizationObject +@ stub D3DKMTDestroyAllocation +@ stub D3DKMTDestroyContext +@ stdcall -stub D3DKMTDestroyDevice(ptr) ;gdi32.D3DKMTDestroyDevice +@ stub D3DKMTDestroySynchronizationObject +@ stub D3DKMTEscape +@ stub D3DKMTGetContextSchedulingPriority +@ stub D3DKMTGetDeviceState +@ stub D3DKMTGetDisplayModeList +@ stub D3DKMTGetMultisampleMethodList +@ stub D3DKMTGetRuntimeData +@ stub D3DKMTGetSharedPrimaryHandle +@ stub D3DKMTLock +@ stdcall -stub D3DKMTOpenAdapterFromGdiDisplayName(ptr); gdi32.D3DKMTOpenAdapterFromGdiDisplayName +@ stub D3DKMTOpenAdapterFromHdc +@ stub D3DKMTOpenResource +@ stub D3DKMTPresent +@ stub D3DKMTQueryAdapterInfo +@ stub D3DKMTQueryAllocationResidency +@ stub D3DKMTQueryResourceInfo +@ stub D3DKMTRender +@ stub D3DKMTSetAllocationPriority +@ stub D3DKMTSetContextSchedulingPriority +@ stub D3DKMTSetDisplayMode +@ stub D3DKMTSetDisplayPrivateDriverFormat +@ stub D3DKMTSetGammaRamp +@ stub D3DKMTSetVidPnSourceOwner +@ stub D3DKMTSignalSynchronizationObject +@ stub D3DKMTUnlock +@ stub D3DKMTWaitForSynchronizationObject +@ stub D3DKMTWaitForVerticalBlankEvent +@ stub OpenAdapter10 +@ stub OpenAdapter10_2 diff --git a/dll/directx/wine/d3d11/d3d11_main.c b/dll/directx/wine/d3d11/d3d11_main.c new file mode 100644 index 00000000000..a5854a93cc3 --- /dev/null +++ b/dll/directx/wine/d3d11/d3d11_main.c @@ -0,0 +1,385 @@ +/* + * Direct3D 11 + * + * Copyright 2008 Henri Verbeet for CodeWeavers + * Copyright 2013 Austin English + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#define D3D11_INIT_GUID +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +static const char *debug_d3d_driver_type(D3D_DRIVER_TYPE driver_type) +{ + switch (driver_type) + { +#define D3D11_TO_STR(x) case x: return #x + D3D11_TO_STR(D3D_DRIVER_TYPE_UNKNOWN); + D3D11_TO_STR(D3D_DRIVER_TYPE_HARDWARE); + D3D11_TO_STR(D3D_DRIVER_TYPE_REFERENCE); + D3D11_TO_STR(D3D_DRIVER_TYPE_NULL); + D3D11_TO_STR(D3D_DRIVER_TYPE_SOFTWARE); + D3D11_TO_STR(D3D_DRIVER_TYPE_WARP); +#undef D3D11_TO_STR + default: + return wine_dbg_sprintf("Unrecognized D3D_DRIVER_TYPE %#x\n", driver_type); + } +} + +static HRESULT WINAPI layer_init(enum dxgi_device_layer_id id, DWORD *count, DWORD *values) +{ + TRACE("id %#x, count %p, values %p\n", id, count, values); + + if (id != DXGI_DEVICE_LAYER_D3D10_DEVICE) + { + WARN("Unknown layer id %#x\n", id); + return E_NOTIMPL; + } + + return S_OK; +} + +static UINT WINAPI layer_get_size(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0) +{ + TRACE("id %#x, args %p, unknown0 %#x\n", id, args, unknown0); + + if (id != DXGI_DEVICE_LAYER_D3D10_DEVICE) + { + WARN("Unknown layer id %#x\n", id); + return 0; + } + + return sizeof(struct d3d_device); +} + +static HRESULT WINAPI layer_create(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0, + void *device_object, REFIID riid, void **device_layer) +{ + struct d3d_device *object; + + TRACE("id %#x, layer_base %p, unknown0 %#x, device_object %p, riid %s, device_layer %p\n", + id, layer_base, unknown0, device_object, debugstr_guid(riid), device_layer); + + if (id != DXGI_DEVICE_LAYER_D3D10_DEVICE) + { + WARN("Unknown layer id %#x\n", id); + *device_layer = NULL; + return E_NOTIMPL; + } + + object = *layer_base; + d3d_device_init(object, device_object); + *device_layer = &object->IUnknown_inner; + + TRACE("Created d3d10 device at %p\n", object); + + return S_OK; +} + +HRESULT WINAPI D3D11CoreRegisterLayers(void) +{ + static const struct dxgi_device_layer layers[] = + { + {DXGI_DEVICE_LAYER_D3D10_DEVICE, layer_init, layer_get_size, layer_create}, + }; + + DXGID3D10RegisterLayers(layers, ARRAY_SIZE(layers)); + + return S_OK; +} + +HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device) +{ + IUnknown *dxgi_device; + HMODULE d3d11; + HRESULT hr; + + TRACE("factory %p, adapter %p, flags %#x, feature_levels %p, levels %u, device %p.\n", + factory, adapter, flags, feature_levels, levels, device); + + d3d11 = GetModuleHandleA("d3d11.dll"); + hr = DXGID3D10CreateDevice(d3d11, factory, adapter, flags, feature_levels, levels, (void **)&dxgi_device); + if (FAILED(hr)) + { + WARN("Failed to create device, returning %#x.\n", hr); + return hr; + } + + hr = IUnknown_QueryInterface(dxgi_device, &IID_ID3D11Device, (void **)device); + IUnknown_Release(dxgi_device); + if (FAILED(hr)) + { + ERR("Failed to query ID3D11Device interface, returning E_FAIL.\n"); + return E_FAIL; + } + + return S_OK; +} + +static HRESULT d3d11_create_device(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out, + D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context) +{ + static const D3D_FEATURE_LEVEL default_feature_levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, + }; + IDXGIFactory *factory; + ID3D11Device *device; + HRESULT hr; + + TRACE("adapter %p, driver_type %s, swrast %p, flags %#x, feature_levels %p, levels %u, sdk_version %u, " + "device %p, obtained_feature_level %p, immediate_context %p.\n", + adapter, debug_d3d_driver_type(driver_type), swrast, flags, feature_levels, levels, sdk_version, + device_out, obtained_feature_level, immediate_context); + + if (device_out) + *device_out = NULL; + if (obtained_feature_level) + *obtained_feature_level = 0; + if (immediate_context) + *immediate_context = NULL; + + if (adapter) + { + IDXGIAdapter_AddRef(adapter); + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); + if (FAILED(hr)) + { + WARN("Failed to get dxgi factory, returning %#x.\n", hr); + return hr; + } + } + else + { + hr = CreateDXGIFactory1(&IID_IDXGIFactory, (void **)&factory); + if (FAILED(hr)) + { + WARN("Failed to create dxgi factory, returning %#x.\n", hr); + return hr; + } + + switch(driver_type) + { + case D3D_DRIVER_TYPE_WARP: + FIXME("WARP driver not implemented, falling back to hardware.\n"); + case D3D_DRIVER_TYPE_HARDWARE: + { + hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter); + if (FAILED(hr)) + { + WARN("No adapters found, returning %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + case D3D_DRIVER_TYPE_NULL: + FIXME("NULL device not implemented, falling back to refrast.\n"); + /* fall through, for now */ + case D3D_DRIVER_TYPE_REFERENCE: + { + HMODULE refrast = LoadLibraryA("d3d11ref.dll"); + if (!refrast) + { + WARN("Failed to load refrast, returning E_FAIL.\n"); + IDXGIFactory_Release(factory); + return E_FAIL; + } + hr = IDXGIFactory_CreateSoftwareAdapter(factory, refrast, &adapter); + FreeLibrary(refrast); + if (FAILED(hr)) + { + WARN("Failed to create a software adapter, returning %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + case D3D_DRIVER_TYPE_SOFTWARE: + { + if (!swrast) + { + WARN("Software device requested, but NULL swrast passed, returning E_FAIL.\n"); + IDXGIFactory_Release(factory); + return E_FAIL; + } + hr = IDXGIFactory_CreateSoftwareAdapter(factory, swrast, &adapter); + if (FAILED(hr)) + { + WARN("Failed to create a software adapter, returning %#x.\n", hr); + IDXGIFactory_Release(factory); + return hr; + } + break; + } + + default: + FIXME("Unhandled driver type %#x.\n", driver_type); + IDXGIFactory_Release(factory); + return E_FAIL; + } + } + + if (!feature_levels) + { + feature_levels = default_feature_levels; + levels = ARRAY_SIZE(default_feature_levels); + } + hr = D3D11CoreCreateDevice(factory, adapter, flags, feature_levels, levels, &device); + IDXGIAdapter_Release(adapter); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create a device, returning %#x.\n", hr); + return hr; + } + + TRACE("Created ID3D11Device %p.\n", device); + + if (obtained_feature_level) + *obtained_feature_level = ID3D11Device_GetFeatureLevel(device); + + if (immediate_context) + ID3D11Device_GetImmediateContext(device, immediate_context); + + if (device_out) + *device_out = device; + else + ID3D11Device_Release(device); + + return (device_out || immediate_context) ? S_OK : S_FALSE; +} + +HRESULT WINAPI D3D11CreateDevice(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out, + D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context) +{ + return d3d11_create_device(adapter, driver_type, swrast, flags, feature_levels, + levels, sdk_version, device_out, obtained_feature_level, immediate_context); +} + +HRESULT WINAPI D3D11CreateDeviceAndSwapChain(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, const D3D_FEATURE_LEVEL *feature_levels, UINT levels, + UINT sdk_version, const DXGI_SWAP_CHAIN_DESC *swapchain_desc, IDXGISwapChain **swapchain, + ID3D11Device **device_out, D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context) +{ + DXGI_SWAP_CHAIN_DESC desc; + IDXGIDevice *dxgi_device; + IDXGIFactory *factory; + ID3D11Device *device; + HRESULT hr; + + TRACE("adapter %p, driver_type %s, swrast %p, flags %#x, feature_levels %p, levels %u, sdk_version %u, " + "swapchain_desc %p, swapchain %p, device %p, obtained_feature_level %p, immediate_context %p.\n", + adapter, debug_d3d_driver_type(driver_type), swrast, flags, feature_levels, levels, sdk_version, + swapchain_desc, swapchain, device_out, obtained_feature_level, immediate_context); + + if (swapchain) + *swapchain = NULL; + if (device_out) + *device_out = NULL; + + /* Avoid forwarding to D3D11CreateDevice(), since it breaks applications + * hooking these entry-points. */ + if (FAILED(hr = d3d11_create_device(adapter, driver_type, swrast, flags, feature_levels, + levels, sdk_version, &device, obtained_feature_level, immediate_context))) + { + WARN("Failed to create a device, returning %#x.\n", hr); + return hr; + } + + if (swapchain) + { + if (FAILED(hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device))) + { + ERR("Failed to get a dxgi device from the d3d11 device, returning %#x.\n", hr); + goto cleanup; + } + + hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter); + IDXGIDevice_Release(dxgi_device); + if (FAILED(hr)) + { + ERR("Failed to get the device adapter, returning %#x.\n", hr); + goto cleanup; + } + + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); + IDXGIAdapter_Release(adapter); + if (FAILED(hr)) + { + ERR("Failed to get the adapter factory, returning %#x.\n", hr); + goto cleanup; + } + + desc = *swapchain_desc; + hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &desc, swapchain); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create a swapchain, returning %#x.\n", hr); + goto cleanup; + } + + TRACE("Created IDXGISwapChain %p.\n", *swapchain); + } + + if (device_out) + *device_out = device; + else + ID3D11Device_Release(device); + + return (swapchain || device_out || immediate_context) ? S_OK : S_FALSE; + +cleanup: + ID3D11Device_Release(device); + if (obtained_feature_level) + *obtained_feature_level = 0; + if (immediate_context) + { + ID3D11DeviceContext_Release(*immediate_context); + *immediate_context = NULL; + } + + return hr; +} + +HRESULT WINAPI D3D11On12CreateDevice(IUnknown *device, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT feature_level_count, + IUnknown * const *queues, UINT queue_count, UINT node_mask, + ID3D11Device **d3d11_device, ID3D11DeviceContext **d3d11_immediate_context, + D3D_FEATURE_LEVEL *obtained_feature_level) +{ + FIXME("device %p, flags %#x, feature_levels %p, feature_level_count %u, " + "queues %p, queue_count %u, node_mask 0x%08x, " + "d3d11_device %p, d3d11_immediate_context %p, obtained_feature_level %p stub!\n", + device, flags, feature_levels, feature_level_count, queues, queue_count, + node_mask, d3d11_device, d3d11_immediate_context, obtained_feature_level); + + return E_NOTIMPL; +} diff --git a/dll/directx/wine/d3d11/d3d11_private.h b/dll/directx/wine/d3d11/d3d11_private.h new file mode 100644 index 00000000000..2f57841dbc0 --- /dev/null +++ b/dll/directx/wine/d3d11/d3d11_private.h @@ -0,0 +1,661 @@ +/* + * Copyright 2008-2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_D3D11_PRIVATE_H +#define __WINE_D3D11_PRIVATE_H + +#include "wine/debug.h" +#include "wine/heap.h" + +#include + +#define COBJMACROS +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "objbase.h" + +#include "d3d11_4.h" +#ifdef D3D11_INIT_GUID +#include "initguid.h" +#endif +#include "wine/wined3d.h" +#include "wine/winedxgi.h" +#include "wine/rbtree.h" + + + + +DEFINE_GUID(IID_ID3D10Texture3D, 0x9b7e4c05, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10ShaderResourceView, 0x9b7e4c07, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); + +DEFINE_GUID(IID_ID3D10DepthStencilView, 0x9b7e4c09, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11UnorderedAccessView, 0x28acf509, 0x7f5c, 0x48f6, 0x86,0x11, 0xf3,0x16,0x01,0x0a,0x63,0x80); +DEFINE_GUID(IID_ID3D11Texture1D, 0xf8fb5c27, 0xc6b3, 0x4f75, 0xa4,0xc8, 0x43,0x9a,0xf2,0xef,0x56,0x4c); + +DEFINE_GUID(IID_ID3D11ShaderResourceView, 0xb0e06fe0, 0x8192, 0x4e1a, 0xb1,0xca, 0x36,0xd7,0x41,0x47,0x10,0xb2); +DEFINE_GUID(IID_ID3D11RenderTargetView, 0xdfdba067, 0x0b8d, 0x4865, 0x87,0x5b, 0xd7,0xb4,0x51,0x6c,0xc1,0x64); + +DEFINE_GUID(IID_ID3D11DepthStencilView, 0x9fdac92a, 0x1876, 0x48c3, 0xaf,0xad, 0x25,0xb9,0x4f,0x84,0xa9,0xb6); +DEFINE_GUID(IID_ID3D11View, 0x839d1216, 0xbb2e, 0x412b, 0xb7,0xf4, 0xa9,0xdb,0xeb,0xe0,0x8e,0xd1); +DEFINE_GUID(IID_ID3D10Texture2D, 0x9b7e4c04, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Texture3D, 0x037e866e, 0xf56d, 0x4357, 0xa8,0xaf, 0x9d,0xab,0xbe,0x6e,0x25,0x0e); +DEFINE_GUID(IID_ID3D11Texture2D, 0x6f15aaf2, 0xd208, 0x4e89, 0x9a,0xb4, 0x48,0x95,0x35,0xd3,0x4f,0x9c); +DEFINE_GUID(IID_IDXGISurface, 0xcafcb56c, 0x6ac3, 0x4889, 0xbf,0x47, 0x9e,0x23,0xbb,0xd2,0x60,0xec); +DEFINE_GUID(IID_IDXGISurface1, 0x4ae63092, 0x6327, 0x4c1b, 0x80,0xae, 0xbf,0xe1,0x2e,0xa3,0x2b,0x86); +DEFINE_GUID(IID_ID3D10BlendState1, 0xedad8d99, 0x8a35, 0x4d6d, 0x85,0x66, 0x2e,0xa2,0x76,0xcd,0xe1,0x61); +DEFINE_GUID(IID_ID3D10SamplerState, 0x9b7e4c0c, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10RasterizerState, 0xa2a07292, 0x89af, 0x4345, 0xbe,0x2e, 0xc5,0x3d,0x9f,0xbb,0x6e,0x9f); +DEFINE_GUID(IID_ID3D10DepthStencilState, 0x2b4b1cc8, 0xa4ad, 0x41f8, 0x83,0x22, 0xca,0x86,0xfc,0x3e,0xc6,0x75); +DEFINE_GUID(IID_ID3D10BlendState, 0xedad8d19, 0x8a35, 0x4d6d, 0x85,0x66, 0x2e,0xa2,0x76,0xcd,0xe1,0x61); +DEFINE_GUID(IID_ID3D11SamplerState, 0xda6fea51, 0x564c, 0x4487, 0x98,0x10, 0xf0,0xd0,0xf9,0xb4,0xe3,0xa5); +DEFINE_GUID(IID_ID3D11RasterizerState, 0x9bb4ab81, 0xab1a, 0x4d8f, 0xb5,0x06, 0xfc,0x04,0x20,0x0b,0x6e,0xe7); +DEFINE_GUID(IID_ID3D11DepthStencilState, 0x03823efb, 0x8d8f, 0x4e1c, 0x9a,0xa2, 0xf6,0x4b,0xb2,0xcb,0xfd,0xf1); +DEFINE_GUID(IID_ID3D11DeviceContext, 0xc0bfa96c, 0xe089, 0x44fb, 0x8e,0xaf, 0x26,0xf8,0x79,0x61,0x90,0xda); +DEFINE_GUID(IID_ID3D11BlendState, 0xcc86fabe, 0xda55, 0x401d, 0x85,0xe7, 0xe3,0xc9,0xde,0x28,0x77,0xe9); +DEFINE_GUID(IID_ID3D10PixelShader, 0x4968b601, 0x9d00, 0x4cde, 0x83,0x46, 0x8e,0x7f,0x67,0x58,0x19,0xb6); +DEFINE_GUID(IID_ID3D10GeometryShader, 0x6316be88, 0x54cd, 0x4040, 0xab,0x44, 0x20,0x46,0x1b,0xc8,0x1f,0x68); +DEFINE_GUID(IID_ID3D11VertexShader, 0x3b301d64, 0xd678, 0x4289, 0x88,0x97, 0x22,0xf8,0x92,0x8b,0x72,0xf3); +DEFINE_GUID(IID_ID3D11PixelShader, 0xea82e40d, 0x51dc, 0x4f33, 0x93,0xd4, 0xdb,0x7c,0x91,0x25,0xae,0x8c); + +DEFINE_GUID(IID_ID3D11GeometryShader, 0x38325b96, 0xeffb, 0x4022, 0xba,0x02, 0x2e,0x79,0x5b,0x70,0x27,0x5c); + +DEFINE_GUID(IID_ID3D11DomainShader, 0xf582c508, 0x0f36, 0x490c, 0x99,0x77, 0x31,0xee,0xce,0x26,0x8c,0xfa); +DEFINE_GUID(IID_ID3D11ComputeShader, 0x4f5b196e, 0xc2bd, 0x495e, 0xbd,0x01, 0x1f,0xde,0xd3,0x8e,0x49,0x69); +DEFINE_GUID(IID_ID3D10InputLayout, 0x9b7e4c0b, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11InputLayout, 0xe4819ddc, 0x4cf0, 0x4025, 0xbd,0x26, 0x5d,0xe8,0x2a,0x3e,0x07,0xb7); + +DEFINE_GUID(IID_ID3D11HullShader, 0x8e5c6061, 0x628a, 0x4c8e, 0x82,0x64, 0xbb,0xe4,0x5c,0xb3,0xd5,0xdd); + +DEFINE_GUID(IID_ID3D10Multithread, 0x9b7e4e00, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11DeviceContext1, 0xbb2c6faa, 0xb5fb, 0x4082, 0x8e,0x6b, 0x38,0x8b,0x8c,0xfa,0x90,0xe1); +DEFINE_GUID(IID_ID3D11Device1, 0xa04bfb29, 0x08ef, 0x43d6, 0xa4,0x9c, 0xa9,0xbd,0xbd,0xcb,0xe6,0x86); +DEFINE_GUID(IID_ID3D11Device2, 0x9d06dffa, 0xd1e5, 0x4d07, 0x83,0xa8, 0x1b,0xb1,0x23,0xf2,0xf8,0x41); +DEFINE_GUID(IID_ID3D11Multithread, 0x9b7e4e00, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Texture1D,0x9B7E4C03,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); + +DEFINE_GUID(IID_ID3D11Device, 0xdb6f6ddb, 0xac77, 0x4e88, 0x82,0x53, 0x81,0x9d,0xf9,0xbb,0xf1,0x40); +DEFINE_GUID(IID_IDXGIDevice, 0x54ec77fa, 0x1377, 0x44e6, 0x8c,0x32, 0x88,0xfd,0x5f,0x44,0xc8,0x4c); +DEFINE_GUID(IID_IDXGIFactory, 0x7b7166ec, 0x21c7, 0x44ae, 0xb2,0x1a, 0xc9,0xae,0x32,0x1a,0xe3,0x69); +DEFINE_GUID(IID_IDXGIDeviceSubObject, 0x3d3e0379, 0xf9de, 0x4d58, 0xbb,0x6c, 0x18,0xd6,0x29,0x92,0xf1,0xa6); +DEFINE_GUID(IID_ID3D11ClassLinkage, 0xddf57cba, 0x9543, 0x46e4, 0xa1,0x2b, 0xf2,0x07,0xa0,0xfe,0x7f,0xed); +DEFINE_GUID(IID_ID3D10VertexShader, 0x9b7e4c0a, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Texture2D1, 0x51218251, 0x1e33, 0x4617, 0x9c,0xcb, 0x4d,0x3a,0x43,0x67,0xe7,0xbb); +DEFINE_GUID(IID_ID3D11BlendState1, 0xcc86fabe, 0xda55, 0x401d, 0x85,0xe7, 0xe3,0xc9,0xde,0x28,0x77,0xe9); +DEFINE_GUID(IID_ID3D11UnorderedAccessView1, 0x7b3b6153, 0xa886, 0x4544, 0xab,0x37, 0x65,0x37,0xc8,0x50,0x04,0x03); +DEFINE_GUID(IID_ID3D10View, 0xc902b03f, 0x60a7, 0x49ba, 0x99,0x36, 0x2a,0x3a,0xb3,0x7a,0x7e,0x33); +DEFINE_GUID(IID_ID3D10RenderTargetView, 0x9b7e4c08, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10ShaderResourceView1, 0x9b7e4c87, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Buffer, 0x9b7e4c02, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Resource, 0x9b7e4c01, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Buffer, 0x48570b85, 0xd1ee, 0x4fcd, 0xa2,0x50, 0xeb,0x35,0x07,0x22,0xb0,0x37); +DEFINE_GUID(IID_ID3D11Resource, 0xdc8e63f3, 0xd12b, 0x4952, 0xb4,0x7b, 0x5e,0x45,0x02,0x6a,0x86,0x2d); +DEFINE_GUID(IID_ID3D10Predicate, 0x9b7e4c10, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Query, 0x9b7e4c0e, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Asynchronous, 0x9b7e4c0d, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Predicate, 0x9eb576dd, 0x9f77, 0x4d86, 0x81,0xaa, 0x8b,0xab,0x5f,0xe4,0x90,0xe2); +DEFINE_GUID(IID_ID3D11Query, 0xd6c00747, 0x87b7, 0x425e, 0xb8,0x4d, 0x44,0xd1,0x08,0x56,0x0a,0xfd); +DEFINE_GUID(IID_ID3D11Query1, 0x631b4766, 0x36dc, 0x461d, 0x8d,0xb6, 0xc4,0x7e,0x13,0xe6,0x09,0x16); +DEFINE_GUID(IID_ID3D11Asynchronous, 0x4b35d0cd, 0x1e15, 0x4258, 0x9c,0x98, 0x1b,0x13,0x33,0xf6,0xdd,0x3b); +DEFINE_GUID(IID_ID3D11DeviceChild, 0x1841e5c8, 0x16b0, 0x489b, 0xbc,0xc8, 0x44,0xcf,0xb0,0xd5,0xde,0xae); +DEFINE_GUID(IID_ID3D10Device1, 0x9b7e4c8f, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10DeviceChild, 0x9b7e4c00, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Device, 0x9b7e4c0f, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); + +#define MAKE_TAG(ch0, ch1, ch2, ch3) \ + ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ + ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) +#define TAG_AON9 MAKE_TAG('A', 'o', 'n', '9') +#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') +#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_OSG5 MAKE_TAG('O', 'S', 'G', '5') +#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N') +#define TAG_PCSG MAKE_TAG('P', 'C', 'S', 'G') +#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') +#define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X') + +struct d3d_device; + +/* TRACE helper functions */ +const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology) DECLSPEC_HIDDEN; +const char *debug_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; +const char *debug_float4(const float *values) DECLSPEC_HIDDEN; + +DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; +enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; +void d3d11_primitive_topology_from_wined3d_primitive_type(enum wined3d_primitive_type primitive_type, + unsigned int patch_vertex_count, D3D11_PRIMITIVE_TOPOLOGY *topology) DECLSPEC_HIDDEN; +void wined3d_primitive_type_from_d3d11_primitive_topology(D3D11_PRIMITIVE_TOPOLOGY topology, + enum wined3d_primitive_type *type, unsigned int *patch_vertex_count) DECLSPEC_HIDDEN; +unsigned int wined3d_getdata_flags_from_d3d11_async_getdata_flags(unsigned int d3d11_flags) DECLSPEC_HIDDEN; +DWORD wined3d_usage_from_d3d11(enum D3D11_USAGE usage) DECLSPEC_HIDDEN; +struct wined3d_resource *wined3d_resource_from_d3d11_resource(ID3D11Resource *resource) DECLSPEC_HIDDEN; +struct wined3d_resource *wined3d_resource_from_d3d10_resource(ID3D10Resource *resource) DECLSPEC_HIDDEN; +DWORD wined3d_map_flags_from_d3d11_map_type(D3D11_MAP map_type) DECLSPEC_HIDDEN; +DWORD wined3d_clear_flags_from_d3d11_clear_flags(UINT clear_flags) DECLSPEC_HIDDEN; +unsigned int wined3d_access_from_d3d11(D3D11_USAGE usage, UINT cpu_access) DECLSPEC_HIDDEN; + +enum D3D11_USAGE d3d11_usage_from_d3d10_usage(enum D3D10_USAGE usage) DECLSPEC_HIDDEN; +enum D3D10_USAGE d3d10_usage_from_d3d11_usage(enum D3D11_USAGE usage) DECLSPEC_HIDDEN; +UINT d3d11_bind_flags_from_d3d10_bind_flags(UINT bind_flags) DECLSPEC_HIDDEN; +UINT d3d10_bind_flags_from_d3d11_bind_flags(UINT bind_flags) DECLSPEC_HIDDEN; +UINT d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(UINT cpu_access_flags) DECLSPEC_HIDDEN; +UINT d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(UINT cpu_access_flags) DECLSPEC_HIDDEN; +UINT d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(UINT resource_misc_flags) DECLSPEC_HIDDEN; +UINT d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(UINT resource_misc_flags) DECLSPEC_HIDDEN; + +BOOL validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION resource_dimension, + D3D11_USAGE usage, UINT bind_flags, UINT cpu_access_flags, + D3D_FEATURE_LEVEL feature_level) DECLSPEC_HIDDEN; + +HRESULT d3d_get_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN; +HRESULT d3d_set_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT data_size, const void *data) DECLSPEC_HIDDEN; +HRESULT d3d_set_private_data_interface(struct wined3d_private_store *store, + REFGUID guid, const IUnknown *object) DECLSPEC_HIDDEN; + +static inline unsigned int wined3d_bind_flags_from_d3d11(UINT bind_flags) +{ + return bind_flags; +} + +static inline UINT d3d11_bind_flags_from_wined3d(unsigned int bind_flags) +{ + return bind_flags; +} + +/* ID3D11Texture1D, ID3D10Texture1D */ +struct d3d_texture1d +{ + ID3D11Texture1D ID3D11Texture1D_iface; + ID3D10Texture1D ID3D10Texture1D_iface; + LONG refcount; + + struct wined3d_private_store private_store; + IUnknown *dxgi_surface; + struct wined3d_texture *wined3d_texture; + D3D11_TEXTURE1D_DESC desc; + ID3D11Device2 *device; +}; + +HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **texture) DECLSPEC_HIDDEN; +struct d3d_texture1d *unsafe_impl_from_ID3D11Texture1D(ID3D11Texture1D *iface) DECLSPEC_HIDDEN; +struct d3d_texture1d *unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D *iface) DECLSPEC_HIDDEN; + +/* ID3D11Texture2D, ID3D10Texture2D */ +struct d3d_texture2d +{ + ID3D11Texture2D ID3D11Texture2D_iface; + ID3D10Texture2D ID3D10Texture2D_iface; + LONG refcount; + + struct wined3d_private_store private_store; + IUnknown *dxgi_surface; + struct wined3d_texture *wined3d_texture; + D3D11_TEXTURE2D_DESC desc; + ID3D11Device2 *device; +}; + +static inline struct d3d_texture2d *impl_from_ID3D11Texture2D(ID3D11Texture2D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D11Texture2D_iface); +} + +HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **texture) DECLSPEC_HIDDEN; +struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface) DECLSPEC_HIDDEN; +struct d3d_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) DECLSPEC_HIDDEN; + +/* ID3D11Texture3D, ID3D10Texture3D */ +struct d3d_texture3d +{ + ID3D11Texture3D ID3D11Texture3D_iface; + ID3D10Texture3D ID3D10Texture3D_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_texture *wined3d_texture; + D3D11_TEXTURE3D_DESC desc; + ID3D11Device2 *device; +}; + +HRESULT d3d_texture3d_create(struct d3d_device *device, const D3D11_TEXTURE3D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture3d **texture) DECLSPEC_HIDDEN; +struct d3d_texture3d *unsafe_impl_from_ID3D11Texture3D(ID3D11Texture3D *iface) DECLSPEC_HIDDEN; +struct d3d_texture3d *unsafe_impl_from_ID3D10Texture3D(ID3D10Texture3D *iface) DECLSPEC_HIDDEN; + +/* ID3D11Buffer, ID3D10Buffer */ +struct d3d_buffer +{ + ID3D11Buffer ID3D11Buffer_iface; + ID3D10Buffer ID3D10Buffer_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_buffer *wined3d_buffer; + D3D11_BUFFER_DESC desc; + ID3D11Device2 *device; +}; + +HRESULT d3d_buffer_create(struct d3d_device *device, const D3D11_BUFFER_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_buffer **buffer) DECLSPEC_HIDDEN; +struct d3d_buffer *unsafe_impl_from_ID3D11Buffer(ID3D11Buffer *iface) DECLSPEC_HIDDEN; +struct d3d_buffer *unsafe_impl_from_ID3D10Buffer(ID3D10Buffer *iface) DECLSPEC_HIDDEN; + +/* ID3D11DepthStencilView, ID3D10DepthStencilView */ +struct d3d_depthstencil_view +{ + ID3D11DepthStencilView ID3D11DepthStencilView_iface; + ID3D10DepthStencilView ID3D10DepthStencilView_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_rendertarget_view *wined3d_view; + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + ID3D11Resource *resource; + ID3D11Device2 *device; +}; + +HRESULT d3d_depthstencil_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, struct d3d_depthstencil_view **view) DECLSPEC_HIDDEN; +struct d3d_depthstencil_view *unsafe_impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface) DECLSPEC_HIDDEN; +struct d3d_depthstencil_view *unsafe_impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface) DECLSPEC_HIDDEN; + +/* ID3D11RenderTargetView, ID3D10RenderTargetView */ +struct d3d_rendertarget_view +{ + ID3D11RenderTargetView ID3D11RenderTargetView_iface; + ID3D10RenderTargetView ID3D10RenderTargetView_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_rendertarget_view *wined3d_view; + D3D11_RENDER_TARGET_VIEW_DESC desc; + ID3D11Resource *resource; + ID3D11Device2 *device; +}; + +HRESULT d3d_rendertarget_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_RENDER_TARGET_VIEW_DESC *desc, struct d3d_rendertarget_view **view) DECLSPEC_HIDDEN; +struct d3d_rendertarget_view *unsafe_impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface) DECLSPEC_HIDDEN; +struct d3d_rendertarget_view *unsafe_impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface) DECLSPEC_HIDDEN; + +/* ID3D11ShaderResourceView, ID3D10ShaderResourceView1 */ +struct d3d_shader_resource_view +{ + ID3D11ShaderResourceView ID3D11ShaderResourceView_iface; + ID3D10ShaderResourceView1 ID3D10ShaderResourceView1_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader_resource_view *wined3d_view; + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + ID3D11Resource *resource; + ID3D11Device2 *device; +}; + +HRESULT d3d_shader_resource_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, struct d3d_shader_resource_view **view) DECLSPEC_HIDDEN; +struct d3d_shader_resource_view *unsafe_impl_from_ID3D11ShaderResourceView( + ID3D11ShaderResourceView *iface) DECLSPEC_HIDDEN; +struct d3d_shader_resource_view *unsafe_impl_from_ID3D10ShaderResourceView( + ID3D10ShaderResourceView *iface) DECLSPEC_HIDDEN; + +/* ID3D11UnorderedAccessView */ +struct d3d11_unordered_access_view +{ + ID3D11UnorderedAccessView ID3D11UnorderedAccessView_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_unordered_access_view *wined3d_view; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc; + ID3D11Resource *resource; + ID3D11Device2 *device; +}; + +HRESULT d3d11_unordered_access_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, struct d3d11_unordered_access_view **view) DECLSPEC_HIDDEN; +struct d3d11_unordered_access_view *unsafe_impl_from_ID3D11UnorderedAccessView( + ID3D11UnorderedAccessView *iface) DECLSPEC_HIDDEN; + +/* ID3D11InputLayout, ID3D10InputLayout */ +struct d3d_input_layout +{ + ID3D11InputLayout ID3D11InputLayout_iface; + ID3D10InputLayout ID3D10InputLayout_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_vertex_declaration *wined3d_decl; + ID3D11Device2 *device; +}; + +HRESULT d3d_input_layout_create(struct d3d_device *device, + const D3D11_INPUT_ELEMENT_DESC *element_descs, UINT element_count, + const void *shader_byte_code, SIZE_T shader_byte_code_length, + struct d3d_input_layout **layout) DECLSPEC_HIDDEN; +struct d3d_input_layout *unsafe_impl_from_ID3D11InputLayout(ID3D11InputLayout *iface) DECLSPEC_HIDDEN; +struct d3d_input_layout *unsafe_impl_from_ID3D10InputLayout(ID3D10InputLayout *iface) DECLSPEC_HIDDEN; + +/* ID3D11VertexShader, ID3D10VertexShader */ +struct d3d_vertex_shader +{ + ID3D11VertexShader ID3D11VertexShader_iface; + ID3D10VertexShader ID3D10VertexShader_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader *wined3d_shader; + ID3D11Device2 *device; +}; + +HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d_vertex_shader **shader) DECLSPEC_HIDDEN; +struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface) DECLSPEC_HIDDEN; +struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface) DECLSPEC_HIDDEN; + +/* ID3D11HullShader */ +struct d3d11_hull_shader +{ + ID3D11HullShader ID3D11HullShader_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader *wined3d_shader; + ID3D11Device2 *device; +}; + +HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d11_hull_shader **shader) DECLSPEC_HIDDEN; +struct d3d11_hull_shader *unsafe_impl_from_ID3D11HullShader(ID3D11HullShader *iface) DECLSPEC_HIDDEN; + +/* ID3D11DomainShader */ +struct d3d11_domain_shader +{ + ID3D11DomainShader ID3D11DomainShader_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader *wined3d_shader; + ID3D11Device2 *device; +}; + +HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d11_domain_shader **shader) DECLSPEC_HIDDEN; +struct d3d11_domain_shader *unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader *iface) DECLSPEC_HIDDEN; + +/* ID3D11GeometryShader, ID3D10GeometryShader */ +struct d3d_geometry_shader +{ + ID3D11GeometryShader ID3D11GeometryShader_iface; + ID3D10GeometryShader ID3D10GeometryShader_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader *wined3d_shader; + ID3D11Device2 *device; +}; + +HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count, + const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream, + struct d3d_geometry_shader **shader) DECLSPEC_HIDDEN; +struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface) DECLSPEC_HIDDEN; +struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface) DECLSPEC_HIDDEN; + +/* ID3D11PixelShader, ID3D10PixelShader */ +struct d3d_pixel_shader +{ + ID3D11PixelShader ID3D11PixelShader_iface; + ID3D10PixelShader ID3D10PixelShader_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader *wined3d_shader; + ID3D11Device2 *device; +}; + +HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d_pixel_shader **shader) DECLSPEC_HIDDEN; +struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface) DECLSPEC_HIDDEN; +struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface) DECLSPEC_HIDDEN; + +/* ID3D11ComputeShader */ +struct d3d11_compute_shader +{ + ID3D11ComputeShader ID3D11ComputeShader_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_shader *wined3d_shader; + ID3D11Device2 *device; +}; + +HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d11_compute_shader **shader) DECLSPEC_HIDDEN; +struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface) DECLSPEC_HIDDEN; + +/* ID3D11ClassLinkage */ +struct d3d11_class_linkage +{ + ID3D11ClassLinkage ID3D11ClassLinkage_iface; + LONG refcount; + + struct wined3d_private_store private_store; + ID3D11Device2 *device; +}; + +HRESULT d3d11_class_linkage_create(struct d3d_device *device, + struct d3d11_class_linkage **class_linkage) DECLSPEC_HIDDEN; + +/* ID3D11BlendState, ID3D10BlendState1 */ +struct d3d_blend_state +{ + ID3D11BlendState ID3D11BlendState_iface; + ID3D10BlendState1 ID3D10BlendState1_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_blend_state *wined3d_state; + D3D11_BLEND_DESC desc; + struct wine_rb_entry entry; + ID3D11Device2 *device; +}; + +static inline struct d3d_blend_state *impl_from_ID3D11BlendState(ID3D11BlendState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_blend_state, ID3D11BlendState_iface); +} + +HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC *desc, + struct d3d_blend_state **state) DECLSPEC_HIDDEN; +struct d3d_blend_state *unsafe_impl_from_ID3D11BlendState(ID3D11BlendState *iface) DECLSPEC_HIDDEN; +struct d3d_blend_state *unsafe_impl_from_ID3D10BlendState(ID3D10BlendState *iface) DECLSPEC_HIDDEN; + +/* ID3D11DepthStencilState, ID3D10DepthStencilState */ +struct d3d_depthstencil_state +{ + ID3D11DepthStencilState ID3D11DepthStencilState_iface; + ID3D10DepthStencilState ID3D10DepthStencilState_iface; + LONG refcount; + + struct wined3d_private_store private_store; + D3D11_DEPTH_STENCIL_DESC desc; + struct wine_rb_entry entry; + ID3D11Device2 *device; +}; + +static inline struct d3d_depthstencil_state *impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_depthstencil_state, ID3D11DepthStencilState_iface); +} + +HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEPTH_STENCIL_DESC *desc, + struct d3d_depthstencil_state **state) DECLSPEC_HIDDEN; +struct d3d_depthstencil_state *unsafe_impl_from_ID3D11DepthStencilState( + ID3D11DepthStencilState *iface) DECLSPEC_HIDDEN; +struct d3d_depthstencil_state *unsafe_impl_from_ID3D10DepthStencilState( + ID3D10DepthStencilState *iface) DECLSPEC_HIDDEN; + +/* ID3D11RasterizerState, ID3D10RasterizerState */ +struct d3d_rasterizer_state +{ + ID3D11RasterizerState ID3D11RasterizerState_iface; + ID3D10RasterizerState ID3D10RasterizerState_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_rasterizer_state *wined3d_state; + D3D11_RASTERIZER_DESC desc; + struct wine_rb_entry entry; + ID3D11Device2 *device; +}; + +HRESULT d3d_rasterizer_state_create(struct d3d_device *device, const D3D11_RASTERIZER_DESC *desc, + struct d3d_rasterizer_state **state) DECLSPEC_HIDDEN; +struct d3d_rasterizer_state *unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState *iface) DECLSPEC_HIDDEN; +struct d3d_rasterizer_state *unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface) DECLSPEC_HIDDEN; + +/* ID3D11SamplerState, ID3D10SamplerState */ +struct d3d_sampler_state +{ + ID3D11SamplerState ID3D11SamplerState_iface; + ID3D10SamplerState ID3D10SamplerState_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_sampler *wined3d_sampler; + D3D11_SAMPLER_DESC desc; + struct wine_rb_entry entry; + ID3D11Device2 *device; +}; + +HRESULT d3d_sampler_state_create(struct d3d_device *device, const D3D11_SAMPLER_DESC *desc, + struct d3d_sampler_state **state) DECLSPEC_HIDDEN; +struct d3d_sampler_state *unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState *iface) DECLSPEC_HIDDEN; +struct d3d_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface) DECLSPEC_HIDDEN; + +/* ID3D11Query, ID3D10Query */ +struct d3d_query +{ + ID3D11Query ID3D11Query_iface; + ID3D10Query ID3D10Query_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct wined3d_query *wined3d_query; + BOOL predicate; + D3D11_QUERY_DESC desc; + ID3D11Device2 *device; +}; + +HRESULT d3d_query_create(struct d3d_device *device, const D3D11_QUERY_DESC *desc, BOOL predicate, + struct d3d_query **query) DECLSPEC_HIDDEN; +struct d3d_query *unsafe_impl_from_ID3D11Query(ID3D11Query *iface) DECLSPEC_HIDDEN; +struct d3d_query *unsafe_impl_from_ID3D10Query(ID3D10Query *iface) DECLSPEC_HIDDEN; +struct d3d_query *unsafe_impl_from_ID3D11Asynchronous(ID3D11Asynchronous *iface) DECLSPEC_HIDDEN; + +/* ID3D11DeviceContext - immediate context */ +struct d3d11_immediate_context +{ + ID3D11DeviceContext1 ID3D11DeviceContext1_iface; + ID3D11Multithread ID3D11Multithread_iface; + LONG refcount; + + struct wined3d_private_store private_store; +}; + +/* ID3D11Device, ID3D10Device1 */ +struct d3d_device +{ + IUnknown IUnknown_inner; + ID3D11Device2 ID3D11Device2_iface; + ID3D10Device1 ID3D10Device1_iface; + ID3D10Multithread ID3D10Multithread_iface; + IWineDXGIDeviceParent IWineDXGIDeviceParent_iface; + IUnknown *outer_unk; + LONG refcount; + + D3D_FEATURE_LEVEL feature_level; + + struct d3d11_immediate_context immediate_context; + + struct wined3d_device_parent device_parent; + struct wined3d_device *wined3d_device; + + struct wine_rb_tree blend_states; + struct wine_rb_tree depthstencil_states; + struct wine_rb_tree rasterizer_states; + struct wine_rb_tree sampler_states; + + struct d3d_depthstencil_state *depth_stencil_state; + UINT stencil_ref; +}; + +static inline struct d3d_device *impl_from_ID3D11Device2(ID3D11Device2 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device, ID3D11Device2_iface); +} + +static inline struct d3d_device *impl_from_ID3D10Device(ID3D10Device1 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device, ID3D10Device1_iface); +} + +void d3d_device_init(struct d3d_device *device, void *outer_unknown) DECLSPEC_HIDDEN; + +/* Layered device */ +enum dxgi_device_layer_id +{ + DXGI_DEVICE_LAYER_DEBUG1 = 0x8, + DXGI_DEVICE_LAYER_THREAD_SAFE = 0x10, + DXGI_DEVICE_LAYER_DEBUG2 = 0x20, + DXGI_DEVICE_LAYER_SWITCH_TO_REF = 0x30, + DXGI_DEVICE_LAYER_D3D10_DEVICE = 0xffffffff, +}; + +struct layer_get_size_args +{ + DWORD unknown0; + DWORD unknown1; + DWORD *unknown2; + DWORD *unknown3; + IDXGIAdapter *adapter; + WORD interface_major; + WORD interface_minor; + WORD version_build; + WORD version_revision; +}; + +struct dxgi_device_layer +{ + enum dxgi_device_layer_id id; + HRESULT (WINAPI *init)(enum dxgi_device_layer_id id, DWORD *count, DWORD *values); + UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0); + HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0, + void *device_object, REFIID riid, void **device_layer); +}; + +HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter, + unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count, void **device); +HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count); + +#endif /* __WINE_D3D11_PRIVATE_H */ diff --git a/dll/directx/wine/d3d11/device.c b/dll/directx/wine/d3d11/device.c new file mode 100644 index 00000000000..212881a9b71 --- /dev/null +++ b/dll/directx/wine/d3d11/device.c @@ -0,0 +1,6278 @@ +/* + * Copyright 2008-2012 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#define NONAMELESSUNION +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +static void STDMETHODCALLTYPE d3d_null_wined3d_object_destroyed(void *parent) {} + +static const struct wined3d_parent_ops d3d_null_wined3d_parent_ops = +{ + d3d_null_wined3d_object_destroyed, +}; + +/* ID3D11DeviceContext - immediate context methods */ + +static inline struct d3d11_immediate_context *impl_from_ID3D11DeviceContext1(ID3D11DeviceContext1 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_immediate_context, ID3D11DeviceContext1_iface); +} + +static inline struct d3d_device *device_from_immediate_ID3D11DeviceContext1(ID3D11DeviceContext1 *iface) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + return CONTAINING_RECORD(context, struct d3d_device, immediate_context); +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_QueryInterface(ID3D11DeviceContext1 *iface, + REFIID iid, void **out) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID3D11DeviceContext1) + || IsEqualGUID(iid, &IID_ID3D11DeviceContext) + || IsEqualGUID(iid, &IID_ID3D11DeviceChild) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = &context->ID3D11DeviceContext1_iface; + } + else if (IsEqualGUID(iid, &IID_ID3D11Multithread)) + { + *out = &context->ID3D11Multithread_iface; + } + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; + } + + ID3D11DeviceContext1_AddRef(iface); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE d3d11_immediate_context_AddRef(ID3D11DeviceContext1 *iface) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + ULONG refcount = InterlockedIncrement(&context->refcount); + + TRACE("%p increasing refcount to %u.\n", context, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(&device->ID3D11Device2_iface); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_immediate_context_Release(ID3D11DeviceContext1 *iface) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + ULONG refcount = InterlockedDecrement(&context->refcount); + + TRACE("%p decreasing refcount to %u.\n", context, refcount); + + if (!refcount) + { + ID3D11Device2_Release(&device->ID3D11Device2_iface); + } + + return refcount; +} + +static void d3d11_immediate_context_get_constant_buffers(ID3D11DeviceContext1 *iface, + enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct wined3d_buffer *wined3d_buffer; + struct d3d_buffer *buffer_impl; + + if (!(wined3d_buffer = wined3d_device_get_constant_buffer(device->wined3d_device, + type, start_slot + i))) + { + buffers[i] = NULL; + continue; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffers[i] = &buffer_impl->ID3D11Buffer_iface; + ID3D11Buffer_AddRef(buffers[i]); + } + wined3d_mutex_unlock(); +} + +static void d3d11_immediate_context_set_constant_buffers(ID3D11DeviceContext1 *iface, + enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); + + wined3d_device_set_constant_buffer(device->wined3d_device, type, start_slot + i, + buffer ? buffer->wined3d_buffer : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GetDevice(ID3D11DeviceContext1 *iface, ID3D11Device **device) +{ + struct d3d_device *device_object = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)&device_object->ID3D11Device2_iface; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_GetPrivateData(ID3D11DeviceContext1 *iface, REFGUID guid, + UINT *data_size, void *data) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&context->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_SetPrivateData(ID3D11DeviceContext1 *iface, REFGUID guid, + UINT data_size, const void *data) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&context->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_SetPrivateDataInterface(ID3D11DeviceContext1 *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&context->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSSetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSSetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_device_set_ps_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSSetShader(ID3D11DeviceContext1 *iface, + ID3D11PixelShader *shader, ID3D11ClassInstance *const *class_instances, UINT class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_pixel_shader *ps = unsafe_impl_from_ID3D11PixelShader(shader); + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %u.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances) + FIXME("Dynamic linking is not implemented yet.\n"); + + wined3d_mutex_lock(); + wined3d_device_set_pixel_shader(device->wined3d_device, ps ? ps->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSSetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_device_set_ps_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSSetShader(ID3D11DeviceContext1 *iface, + ID3D11VertexShader *shader, ID3D11ClassInstance *const *class_instances, UINT class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_vertex_shader *vs = unsafe_impl_from_ID3D11VertexShader(shader); + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %u.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances) + FIXME("Dynamic linking is not implemented yet.\n"); + + wined3d_mutex_lock(); + wined3d_device_set_vertex_shader(device->wined3d_device, vs ? vs->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexed(ID3D11DeviceContext1 *iface, + UINT index_count, UINT start_index_location, INT base_vertex_location) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, index_count %u, start_index_location %u, base_vertex_location %d.\n", + iface, index_count, start_index_location, base_vertex_location); + + wined3d_mutex_lock(); + wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); + wined3d_device_draw_indexed_primitive(device->wined3d_device, start_index_location, index_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_Draw(ID3D11DeviceContext1 *iface, + UINT vertex_count, UINT start_vertex_location) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, vertex_count %u, start_vertex_location %u.\n", + iface, vertex_count, start_vertex_location); + + wined3d_mutex_lock(); + wined3d_device_draw_primitive(device->wined3d_device, start_vertex_location, vertex_count); + wined3d_mutex_unlock(); +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_Map(ID3D11DeviceContext1 *iface, ID3D11Resource *resource, + UINT subresource_idx, D3D11_MAP map_type, UINT map_flags, D3D11_MAPPED_SUBRESOURCE *mapped_subresource) +{ + struct wined3d_resource *wined3d_resource; + struct wined3d_map_desc map_desc; + HRESULT hr; + + TRACE("iface %p, resource %p, subresource_idx %u, map_type %u, map_flags %#x, mapped_subresource %p.\n", + iface, resource, subresource_idx, map_type, map_flags, mapped_subresource); + + if (map_flags) + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_resource = wined3d_resource_from_d3d11_resource(resource); + + wined3d_mutex_lock(); + hr = wined3d_resource_map(wined3d_resource, subresource_idx, + &map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)); + wined3d_mutex_unlock(); + + mapped_subresource->pData = map_desc.data; + mapped_subresource->RowPitch = map_desc.row_pitch; + mapped_subresource->DepthPitch = map_desc.slice_pitch; + + return hr; +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_Unmap(ID3D11DeviceContext1 *iface, ID3D11Resource *resource, + UINT subresource_idx) +{ + struct wined3d_resource *wined3d_resource; + + TRACE("iface %p, resource %p, subresource_idx %u.\n", iface, resource, subresource_idx); + + wined3d_resource = wined3d_resource_from_d3d11_resource(resource); + + wined3d_mutex_lock(); + wined3d_resource_unmap(wined3d_resource, subresource_idx); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSSetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IASetInputLayout(ID3D11DeviceContext1 *iface, + ID3D11InputLayout *input_layout) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_input_layout *layout = unsafe_impl_from_ID3D11InputLayout(input_layout); + + TRACE("iface %p, input_layout %p.\n", iface, input_layout); + + wined3d_mutex_lock(); + wined3d_device_set_vertex_declaration(device->wined3d_device, layout ? layout->wined3d_decl : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IASetVertexBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers, const UINT *strides, const UINT *offsets) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p.\n", + iface, start_slot, buffer_count, buffers, strides, offsets); + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); + + wined3d_device_set_stream_source(device->wined3d_device, start_slot + i, + buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IASetIndexBuffer(ID3D11DeviceContext1 *iface, + ID3D11Buffer *buffer, DXGI_FORMAT format, UINT offset) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_buffer *buffer_impl = unsafe_impl_from_ID3D11Buffer(buffer); + + TRACE("iface %p, buffer %p, format %s, offset %u.\n", + iface, buffer, debug_dxgi_format(format), offset); + + wined3d_mutex_lock(); + wined3d_device_set_index_buffer(device->wined3d_device, + buffer_impl ? buffer_impl->wined3d_buffer : NULL, + wined3dformat_from_dxgi_format(format), offset); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexedInstanced(ID3D11DeviceContext1 *iface, + UINT instance_index_count, UINT instance_count, UINT start_index_location, INT base_vertex_location, + UINT start_instance_location) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, instance_index_count %u, instance_count %u, start_index_location %u, " + "base_vertex_location %d, start_instance_location %u.\n", + iface, instance_index_count, instance_count, start_index_location, + base_vertex_location, start_instance_location); + + wined3d_mutex_lock(); + wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); + wined3d_device_draw_indexed_primitive_instanced(device->wined3d_device, start_index_location, + instance_index_count, start_instance_location, instance_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DrawInstanced(ID3D11DeviceContext1 *iface, + UINT instance_vertex_count, UINT instance_count, UINT start_vertex_location, UINT start_instance_location) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, instance_vertex_count %u, instance_count %u, start_vertex_location %u, " + "start_instance_location %u.\n", + iface, instance_vertex_count, instance_count, start_vertex_location, + start_instance_location); + + wined3d_mutex_lock(); + wined3d_device_draw_primitive_instanced(device->wined3d_device, start_vertex_location, + instance_vertex_count, start_instance_location, instance_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSSetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSSetShader(ID3D11DeviceContext1 *iface, + ID3D11GeometryShader *shader, ID3D11ClassInstance *const *class_instances, UINT class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_geometry_shader *gs = unsafe_impl_from_ID3D11GeometryShader(shader); + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %u.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances) + FIXME("Dynamic linking is not implemented yet.\n"); + + wined3d_mutex_lock(); + wined3d_device_set_geometry_shader(device->wined3d_device, gs ? gs->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IASetPrimitiveTopology(ID3D11DeviceContext1 *iface, + D3D11_PRIMITIVE_TOPOLOGY topology) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + enum wined3d_primitive_type primitive_type; + unsigned int patch_vertex_count; + + TRACE("iface %p, topology %#x.\n", iface, topology); + + wined3d_primitive_type_from_d3d11_primitive_topology(topology, &primitive_type, &patch_vertex_count); + + wined3d_mutex_lock(); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, patch_vertex_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSSetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_device_set_vs_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSSetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_device_set_vs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_Begin(ID3D11DeviceContext1 *iface, + ID3D11Asynchronous *asynchronous) +{ + struct d3d_query *query = unsafe_impl_from_ID3D11Asynchronous(asynchronous); + HRESULT hr; + + TRACE("iface %p, asynchronous %p.\n", iface, asynchronous); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_query_issue(query->wined3d_query, WINED3DISSUE_BEGIN))) + ERR("Failed to issue query, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_End(ID3D11DeviceContext1 *iface, + ID3D11Asynchronous *asynchronous) +{ + struct d3d_query *query = unsafe_impl_from_ID3D11Asynchronous(asynchronous); + HRESULT hr; + + TRACE("iface %p, asynchronous %p.\n", iface, asynchronous); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_query_issue(query->wined3d_query, WINED3DISSUE_END))) + ERR("Failed to issue query, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_GetData(ID3D11DeviceContext1 *iface, + ID3D11Asynchronous *asynchronous, void *data, UINT data_size, UINT data_flags) +{ + struct d3d_query *query = unsafe_impl_from_ID3D11Asynchronous(asynchronous); + unsigned int wined3d_flags; + HRESULT hr; + + TRACE("iface %p, asynchronous %p, data %p, data_size %u, data_flags %#x.\n", + iface, asynchronous, data, data_size, data_flags); + + if (!data && data_size) + return E_INVALIDARG; + + wined3d_flags = wined3d_getdata_flags_from_d3d11_async_getdata_flags(data_flags); + + wined3d_mutex_lock(); + if (!data_size || wined3d_query_get_data_size(query->wined3d_query) == data_size) + { + hr = wined3d_query_get_data(query->wined3d_query, data, data_size, wined3d_flags); + if (hr == WINED3DERR_INVALIDCALL) + hr = DXGI_ERROR_INVALID_CALL; + } + else + { + WARN("Invalid data size %u.\n", data_size); + hr = E_INVALIDARG; + } + wined3d_mutex_unlock(); + + return hr; +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_SetPredication(ID3D11DeviceContext1 *iface, + ID3D11Predicate *predicate, BOOL value) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_query *query; + + TRACE("iface %p, predicate %p, value %#x.\n", iface, predicate, value); + + query = unsafe_impl_from_ID3D11Query((ID3D11Query *)predicate); + + wined3d_mutex_lock(); + wined3d_device_set_predication(device->wined3d_device, query ? query->wined3d_query : NULL, value); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSSetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_device_set_gs_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSSetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_device_set_gs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetRenderTargets(ID3D11DeviceContext1 *iface, + UINT render_target_view_count, ID3D11RenderTargetView *const *render_target_views, + ID3D11DepthStencilView *depth_stencil_view) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_depthstencil_view *dsv; + unsigned int i; + + TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", + iface, render_target_view_count, render_target_views, depth_stencil_view); + + wined3d_mutex_lock(); + for (i = 0; i < render_target_view_count; ++i) + { + struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D11RenderTargetView(render_target_views[i]); + wined3d_device_set_rendertarget_view(device->wined3d_device, i, rtv ? rtv->wined3d_view : NULL, FALSE); + } + for (; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + wined3d_device_set_rendertarget_view(device->wined3d_device, i, NULL, FALSE); + } + + dsv = unsafe_impl_from_ID3D11DepthStencilView(depth_stencil_view); + wined3d_device_set_depth_stencil_view(device->wined3d_device, dsv ? dsv->wined3d_view : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetRenderTargetsAndUnorderedAccessViews( + ID3D11DeviceContext1 *iface, UINT render_target_view_count, + ID3D11RenderTargetView *const *render_target_views, ID3D11DepthStencilView *depth_stencil_view, + UINT unordered_access_view_start_slot, UINT unordered_access_view_count, + ID3D11UnorderedAccessView *const *unordered_access_views, const UINT *initial_counts) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p, " + "unordered_access_view_start_slot %u, unordered_access_view_count %u, unordered_access_views %p, " + "initial_counts %p.\n", + iface, render_target_view_count, render_target_views, depth_stencil_view, + unordered_access_view_start_slot, unordered_access_view_count, unordered_access_views, + initial_counts); + + if (render_target_view_count != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + { + d3d11_immediate_context_OMSetRenderTargets(iface, render_target_view_count, render_target_views, + depth_stencil_view); + } + + if (unordered_access_view_count != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + { + wined3d_mutex_lock(); + for (i = 0; i < unordered_access_view_start_slot; ++i) + { + wined3d_device_set_unordered_access_view(device->wined3d_device, i, NULL, ~0u); + } + for (i = 0; i < unordered_access_view_count; ++i) + { + struct d3d11_unordered_access_view *view + = unsafe_impl_from_ID3D11UnorderedAccessView(unordered_access_views[i]); + + wined3d_device_set_unordered_access_view(device->wined3d_device, + unordered_access_view_start_slot + i, + view ? view->wined3d_view : NULL, initial_counts ? initial_counts[i] : ~0u); + } + for (; unordered_access_view_start_slot + i < D3D11_PS_CS_UAV_REGISTER_COUNT; ++i) + { + wined3d_device_set_unordered_access_view(device->wined3d_device, + unordered_access_view_start_slot + i, NULL, ~0u); + } + wined3d_mutex_unlock(); + } +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11DeviceContext1 *iface, + ID3D11BlendState *blend_state, const float blend_factor[4], UINT sample_mask) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + static const float default_blend_factor[] = {1.0f, 1.0f, 1.0f, 1.0f}; + struct d3d_blend_state *blend_state_impl; + const D3D11_BLEND_DESC *desc; + + TRACE("iface %p, blend_state %p, blend_factor %s, sample_mask 0x%08x.\n", + iface, blend_state, debug_float4(blend_factor), sample_mask); + + if (!blend_factor) + blend_factor = default_blend_factor; + + wined3d_mutex_lock(); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEMASK, sample_mask); + if (!(blend_state_impl = unsafe_impl_from_ID3D11BlendState(blend_state))) + { + wined3d_device_set_blend_state(device->wined3d_device, NULL, + (const struct wined3d_color *)blend_factor); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ALPHABLENDENABLE, FALSE); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE, D3D11_COLOR_WRITE_ENABLE_ALL); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE1, D3D11_COLOR_WRITE_ENABLE_ALL); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE2, D3D11_COLOR_WRITE_ENABLE_ALL); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE3, D3D11_COLOR_WRITE_ENABLE_ALL); + wined3d_mutex_unlock(); + return; + } + + wined3d_device_set_blend_state(device->wined3d_device, blend_state_impl->wined3d_state, + (const struct wined3d_color *)blend_factor); + desc = &blend_state_impl->desc; + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ALPHABLENDENABLE, + desc->RenderTarget[0].BlendEnable); + if (desc->RenderTarget[0].BlendEnable) + { + const D3D11_RENDER_TARGET_BLEND_DESC *d = &desc->RenderTarget[0]; + + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SRCBLEND, d->SrcBlend); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DESTBLEND, d->DestBlend); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BLENDOP, d->BlendOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SEPARATEALPHABLENDENABLE, TRUE); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SRCBLENDALPHA, d->SrcBlendAlpha); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DESTBLENDALPHA, d->DestBlendAlpha); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BLENDOPALPHA, d->BlendOpAlpha); + } + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE, desc->RenderTarget[0].RenderTargetWriteMask); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE1, desc->RenderTarget[1].RenderTargetWriteMask); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE2, desc->RenderTarget[2].RenderTargetWriteMask); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_COLORWRITEENABLE3, desc->RenderTarget[3].RenderTargetWriteMask); + wined3d_mutex_unlock(); +} + +static void set_default_depth_stencil_state(struct wined3d_device *wined3d_device) +{ + wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZENABLE, TRUE); + wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZWRITEENABLE, D3D11_DEPTH_WRITE_MASK_ALL); + wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZFUNC, WINED3D_CMP_LESS); + wined3d_device_set_render_state(wined3d_device, WINED3D_RS_STENCILENABLE, FALSE); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3D11DeviceContext1 *iface, + ID3D11DepthStencilState *depth_stencil_state, UINT stencil_ref) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + const D3D11_DEPTH_STENCILOP_DESC *front, *back; + const D3D11_DEPTH_STENCIL_DESC *desc; + + TRACE("iface %p, depth_stencil_state %p, stencil_ref %u.\n", + iface, depth_stencil_state, stencil_ref); + + wined3d_mutex_lock(); + device->stencil_ref = stencil_ref; + if (!(device->depth_stencil_state = unsafe_impl_from_ID3D11DepthStencilState(depth_stencil_state))) + { + set_default_depth_stencil_state(device->wined3d_device); + wined3d_mutex_unlock(); + return; + } + + desc = &device->depth_stencil_state->desc; + + front = &desc->FrontFace; + back = &desc->BackFace; + + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, desc->DepthEnable); + if (desc->DepthEnable) + { + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZWRITEENABLE, desc->DepthWriteMask); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZFUNC, desc->DepthFunc); + } + + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILENABLE, desc->StencilEnable); + if (desc->StencilEnable) + { + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILMASK, desc->StencilReadMask); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILWRITEMASK, desc->StencilWriteMask); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILREF, stencil_ref); + + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILFAIL, front->StencilFailOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILZFAIL, front->StencilDepthFailOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILPASS, front->StencilPassOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_STENCILFUNC, front->StencilFunc); + if (front->StencilFailOp != back->StencilFailOp + || front->StencilDepthFailOp != back->StencilDepthFailOp + || front->StencilPassOp != back->StencilPassOp + || front->StencilFunc != back->StencilFunc) + { + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_TWOSIDEDSTENCILMODE, TRUE); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILFAIL, back->StencilFailOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILZFAIL, + back->StencilDepthFailOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILPASS, back->StencilPassOp); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BACK_STENCILFUNC, back->StencilFunc); + } + else + { + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_TWOSIDEDSTENCILMODE, FALSE); + } + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_SOSetTargets(ID3D11DeviceContext1 *iface, UINT buffer_count, + ID3D11Buffer *const *buffers, const UINT *offsets) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int count, i; + + TRACE("iface %p, buffer_count %u, buffers %p, offsets %p.\n", iface, buffer_count, buffers, offsets); + + count = min(buffer_count, D3D11_SO_BUFFER_SLOT_COUNT); + wined3d_mutex_lock(); + for (i = 0; i < count; ++i) + { + struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); + + wined3d_device_set_stream_output(device->wined3d_device, i, + buffer ? buffer->wined3d_buffer : NULL, offsets ? offsets[i] : 0); + } + for (; i < D3D11_SO_BUFFER_SLOT_COUNT; ++i) + { + wined3d_device_set_stream_output(device->wined3d_device, i, NULL, 0); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DrawAuto(ID3D11DeviceContext1 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexedInstancedIndirect(ID3D11DeviceContext1 *iface, + ID3D11Buffer *buffer, UINT offset) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_buffer *d3d_buffer; + + TRACE("iface %p, buffer %p, offset %u.\n", iface, buffer, offset); + + d3d_buffer = unsafe_impl_from_ID3D11Buffer(buffer); + + wined3d_mutex_lock(); + wined3d_device_draw_indexed_primitive_instanced_indirect(device->wined3d_device, + d3d_buffer->wined3d_buffer, offset); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DrawInstancedIndirect(ID3D11DeviceContext1 *iface, + ID3D11Buffer *buffer, UINT offset) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_buffer *d3d_buffer; + + TRACE("iface %p, buffer %p, offset %u.\n", iface, buffer, offset); + + d3d_buffer = unsafe_impl_from_ID3D11Buffer(buffer); + + wined3d_mutex_lock(); + wined3d_device_draw_primitive_instanced_indirect(device->wined3d_device, + d3d_buffer->wined3d_buffer, offset); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_Dispatch(ID3D11DeviceContext1 *iface, + UINT thread_group_count_x, UINT thread_group_count_y, UINT thread_group_count_z) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, thread_group_count_x %u, thread_group_count_y %u, thread_group_count_z %u.\n", + iface, thread_group_count_x, thread_group_count_y, thread_group_count_z); + + wined3d_mutex_lock(); + wined3d_device_dispatch_compute(device->wined3d_device, + thread_group_count_x, thread_group_count_y, thread_group_count_z); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DispatchIndirect(ID3D11DeviceContext1 *iface, + ID3D11Buffer *buffer, UINT offset) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_buffer *buffer_impl; + + TRACE("iface %p, buffer %p, offset %u.\n", iface, buffer, offset); + + buffer_impl = unsafe_impl_from_ID3D11Buffer(buffer); + + wined3d_mutex_lock(); + wined3d_device_dispatch_compute_indirect(device->wined3d_device, + buffer_impl->wined3d_buffer, offset); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetState(ID3D11DeviceContext1 *iface, + ID3D11RasterizerState *rasterizer_state) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_rasterizer_state *rasterizer_state_impl; + const D3D11_RASTERIZER_DESC *desc; + union + { + DWORD d; + float f; + } scale_bias, const_bias; + + TRACE("iface %p, rasterizer_state %p.\n", iface, rasterizer_state); + + wined3d_mutex_lock(); + if (!(rasterizer_state_impl = unsafe_impl_from_ID3D11RasterizerState(rasterizer_state))) + { + wined3d_device_set_rasterizer_state(device->wined3d_device, NULL); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_FILLMODE, WINED3D_FILL_SOLID); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_CULLMODE, WINED3D_CULL_BACK); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SLOPESCALEDEPTHBIAS, 0); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, 0); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SCISSORTESTENABLE, FALSE); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEANTIALIAS, FALSE); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ANTIALIASEDLINEENABLE, FALSE); + wined3d_mutex_unlock(); + return; + } + + wined3d_device_set_rasterizer_state(device->wined3d_device, rasterizer_state_impl->wined3d_state); + + desc = &rasterizer_state_impl->desc; + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_FILLMODE, desc->FillMode); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_CULLMODE, desc->CullMode); + scale_bias.f = desc->SlopeScaledDepthBias; + const_bias.f = desc->DepthBias; + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SLOPESCALEDEPTHBIAS, scale_bias.d); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, const_bias.d); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SCISSORTESTENABLE, desc->ScissorEnable); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEANTIALIAS, desc->MultisampleEnable); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_ANTIALIASEDLINEENABLE, desc->AntialiasedLineEnable); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetViewports(ID3D11DeviceContext1 *iface, + UINT viewport_count, const D3D11_VIEWPORT *viewports) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_viewport wined3d_vp[WINED3D_MAX_VIEWPORTS]; + unsigned int i; + + TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports); + + if (viewport_count > ARRAY_SIZE(wined3d_vp)) + return; + + for (i = 0; i < viewport_count; ++i) + { + wined3d_vp[i].x = viewports[i].TopLeftX; + wined3d_vp[i].y = viewports[i].TopLeftY; + wined3d_vp[i].width = viewports[i].Width; + wined3d_vp[i].height = viewports[i].Height; + wined3d_vp[i].min_z = viewports[i].MinDepth; + wined3d_vp[i].max_z = viewports[i].MaxDepth; + } + + wined3d_mutex_lock(); + wined3d_device_set_viewports(device->wined3d_device, viewport_count, wined3d_vp); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetScissorRects(ID3D11DeviceContext1 *iface, + UINT rect_count, const D3D11_RECT *rects) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, rect_count %u, rects %p.\n", iface, rect_count, rects); + + if (rect_count > WINED3D_MAX_VIEWPORTS) + return; + + wined3d_mutex_lock(); + wined3d_device_set_scissor_rects(device->wined3d_device, rect_count, rects); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CopySubresourceRegion(ID3D11DeviceContext1 *iface, + ID3D11Resource *dst_resource, UINT dst_subresource_idx, UINT dst_x, UINT dst_y, UINT dst_z, + ID3D11Resource *src_resource, UINT src_subresource_idx, const D3D11_BOX *src_box) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct wined3d_box wined3d_src_box; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, dst_x %u, dst_y %u, dst_z %u, " + "src_resource %p, src_subresource_idx %u, src_box %p.\n", + iface, dst_resource, dst_subresource_idx, dst_x, dst_y, dst_z, + src_resource, src_subresource_idx, src_box); + + if (src_box) + wined3d_box_set(&wined3d_src_box, src_box->left, src_box->top, + src_box->right, src_box->bottom, src_box->front, src_box->back); + + wined3d_dst_resource = wined3d_resource_from_d3d11_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d11_resource(src_resource); + wined3d_mutex_lock(); + wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_dst_resource, dst_subresource_idx, + dst_x, dst_y, dst_z, wined3d_src_resource, src_subresource_idx, src_box ? &wined3d_src_box : NULL, 0); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CopyResource(ID3D11DeviceContext1 *iface, + ID3D11Resource *dst_resource, ID3D11Resource *src_resource) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + + TRACE("iface %p, dst_resource %p, src_resource %p.\n", iface, dst_resource, src_resource); + + wined3d_dst_resource = wined3d_resource_from_d3d11_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d11_resource(src_resource); + wined3d_mutex_lock(); + wined3d_device_copy_resource(device->wined3d_device, wined3d_dst_resource, wined3d_src_resource); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_UpdateSubresource(ID3D11DeviceContext1 *iface, + ID3D11Resource *resource, UINT subresource_idx, const D3D11_BOX *box, + const void *data, UINT row_pitch, UINT depth_pitch) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_resource *wined3d_resource; + struct wined3d_box wined3d_box; + + TRACE("iface %p, resource %p, subresource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u.\n", + iface, resource, subresource_idx, box, data, row_pitch, depth_pitch); + + if (box) + wined3d_box_set(&wined3d_box, box->left, box->top, box->right, box->bottom, box->front, box->back); + + wined3d_resource = wined3d_resource_from_d3d11_resource(resource); + wined3d_mutex_lock(); + wined3d_device_update_sub_resource(device->wined3d_device, wined3d_resource, + subresource_idx, box ? &wined3d_box : NULL, data, row_pitch, depth_pitch, 0); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CopyStructureCount(ID3D11DeviceContext1 *iface, + ID3D11Buffer *dst_buffer, UINT dst_offset, ID3D11UnorderedAccessView *src_view) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_unordered_access_view *uav; + struct d3d_buffer *buffer_impl; + + TRACE("iface %p, dst_buffer %p, dst_offset %u, src_view %p.\n", + iface, dst_buffer, dst_offset, src_view); + + buffer_impl = unsafe_impl_from_ID3D11Buffer(dst_buffer); + uav = unsafe_impl_from_ID3D11UnorderedAccessView(src_view); + + wined3d_mutex_lock(); + wined3d_device_copy_uav_counter(device->wined3d_device, + buffer_impl->wined3d_buffer, dst_offset, uav->wined3d_view); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ClearRenderTargetView(ID3D11DeviceContext1 *iface, + ID3D11RenderTargetView *render_target_view, const float color_rgba[4]) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_rendertarget_view *view = unsafe_impl_from_ID3D11RenderTargetView(render_target_view); + const struct wined3d_color color = {color_rgba[0], color_rgba[1], color_rgba[2], color_rgba[3]}; + HRESULT hr; + + TRACE("iface %p, render_target_view %p, color_rgba %s.\n", + iface, render_target_view, debug_float4(color_rgba)); + + if (!view) + return; + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, view->wined3d_view, NULL, + WINED3DCLEAR_TARGET, &color, 0.0f, 0))) + ERR("Failed to clear view, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ClearUnorderedAccessViewUint(ID3D11DeviceContext1 *iface, + ID3D11UnorderedAccessView *unordered_access_view, const UINT values[4]) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_unordered_access_view *view; + + TRACE("iface %p, unordered_access_view %p, values {%u, %u, %u, %u}.\n", + iface, unordered_access_view, values[0], values[1], values[2], values[3]); + + view = unsafe_impl_from_ID3D11UnorderedAccessView(unordered_access_view); + wined3d_mutex_lock(); + wined3d_device_clear_unordered_access_view_uint(device->wined3d_device, + view->wined3d_view, (const struct wined3d_uvec4 *)values); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ClearUnorderedAccessViewFloat(ID3D11DeviceContext1 *iface, + ID3D11UnorderedAccessView *unordered_access_view, const float values[4]) +{ + FIXME("iface %p, unordered_access_view %p, values %s stub!\n", + iface, unordered_access_view, debug_float4(values)); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ClearDepthStencilView(ID3D11DeviceContext1 *iface, + ID3D11DepthStencilView *depth_stencil_view, UINT flags, FLOAT depth, UINT8 stencil) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_depthstencil_view *view = unsafe_impl_from_ID3D11DepthStencilView(depth_stencil_view); + DWORD wined3d_flags; + HRESULT hr; + + TRACE("iface %p, depth_stencil_view %p, flags %#x, depth %.8e, stencil %u.\n", + iface, depth_stencil_view, flags, depth, stencil); + + if (!view) + return; + + wined3d_flags = wined3d_clear_flags_from_d3d11_clear_flags(flags); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, view->wined3d_view, NULL, + wined3d_flags, NULL, depth, stencil))) + ERR("Failed to clear view, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GenerateMips(ID3D11DeviceContext1 *iface, + ID3D11ShaderResourceView *view) +{ + struct d3d_shader_resource_view *srv = unsafe_impl_from_ID3D11ShaderResourceView(view); + + TRACE("iface %p, view %p.\n", iface, view); + + wined3d_mutex_lock(); + wined3d_shader_resource_view_generate_mipmaps(srv->wined3d_view); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_SetResourceMinLOD(ID3D11DeviceContext1 *iface, + ID3D11Resource *resource, FLOAT min_lod) +{ + FIXME("iface %p, resource %p, min_lod %f stub!\n", iface, resource, min_lod); +} + +static FLOAT STDMETHODCALLTYPE d3d11_immediate_context_GetResourceMinLOD(ID3D11DeviceContext1 *iface, + ID3D11Resource *resource) +{ + FIXME("iface %p, resource %p stub!\n", iface, resource); + + return 0.0f; +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ResolveSubresource(ID3D11DeviceContext1 *iface, + ID3D11Resource *dst_resource, UINT dst_subresource_idx, + ID3D11Resource *src_resource, UINT src_subresource_idx, + DXGI_FORMAT format) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + enum wined3d_format_id wined3d_format; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, " + "src_resource %p, src_subresource_idx %u, format %s.\n", + iface, dst_resource, dst_subresource_idx, + src_resource, src_subresource_idx, debug_dxgi_format(format)); + + wined3d_dst_resource = wined3d_resource_from_d3d11_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d11_resource(src_resource); + wined3d_format = wined3dformat_from_dxgi_format(format); + wined3d_mutex_lock(); + wined3d_device_resolve_sub_resource(device->wined3d_device, + wined3d_dst_resource, dst_subresource_idx, + wined3d_src_resource, src_subresource_idx, wined3d_format); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ExecuteCommandList(ID3D11DeviceContext1 *iface, + ID3D11CommandList *command_list, BOOL restore_state) +{ + FIXME("iface %p, command_list %p, restore_state %#x stub!\n", iface, command_list, restore_state); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSSetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_device_set_hs_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSSetShader(ID3D11DeviceContext1 *iface, + ID3D11HullShader *shader, ID3D11ClassInstance *const *class_instances, UINT class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_hull_shader *hs = unsafe_impl_from_ID3D11HullShader(shader); + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %u.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances) + FIXME("Dynamic linking is not implemented yet.\n"); + + wined3d_mutex_lock(); + wined3d_device_set_hull_shader(device->wined3d_device, hs ? hs->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSSetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_device_set_hs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSSetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSSetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_device_set_ds_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSSetShader(ID3D11DeviceContext1 *iface, + ID3D11DomainShader *shader, ID3D11ClassInstance *const *class_instances, UINT class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_domain_shader *ds = unsafe_impl_from_ID3D11DomainShader(shader); + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %u.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances) + FIXME("Dynamic linking is not implemented yet.\n"); + + wined3d_mutex_lock(); + wined3d_device_set_domain_shader(device->wined3d_device, ds ? ds->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSSetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_device_set_ds_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSSetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_device_set_cs_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetUnorderedAccessViews(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11UnorderedAccessView *const *views, const UINT *initial_counts) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p, initial_counts %p.\n", + iface, start_slot, view_count, views, initial_counts); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d11_unordered_access_view *view = unsafe_impl_from_ID3D11UnorderedAccessView(views[i]); + + wined3d_device_set_cs_uav(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL, initial_counts ? initial_counts[i] : ~0u); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetShader(ID3D11DeviceContext1 *iface, + ID3D11ComputeShader *shader, ID3D11ClassInstance *const *class_instances, UINT class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_compute_shader *cs = unsafe_impl_from_ID3D11ComputeShader(shader); + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %u.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances) + FIXME("Dynamic linking is not implemented yet.\n"); + + wined3d_mutex_lock(); + wined3d_device_set_compute_shader(device->wined3d_device, cs ? cs->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_device_set_cs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSGetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSGetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_ps_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + views[i] = &view_impl->ID3D11ShaderResourceView_iface; + ID3D11ShaderResourceView_AddRef(views[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSGetShader(ID3D11DeviceContext1 *iface, + ID3D11PixelShader **shader, ID3D11ClassInstance **class_instances, UINT *class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_shader *wined3d_shader; + struct d3d_pixel_shader *shader_impl; + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %p.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances || class_instance_count) + FIXME("Dynamic linking not implemented yet.\n"); + if (class_instance_count) + *class_instance_count = 0; + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_pixel_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + *shader = &shader_impl->ID3D11PixelShader_iface; + ID3D11PixelShader_AddRef(*shader); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSGetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState **samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct wined3d_sampler *wined3d_sampler; + struct d3d_sampler_state *sampler_impl; + + if (!(wined3d_sampler = wined3d_device_get_ps_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + samplers[i] = &sampler_impl->ID3D11SamplerState_iface; + ID3D11SamplerState_AddRef(samplers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSGetShader(ID3D11DeviceContext1 *iface, + ID3D11VertexShader **shader, ID3D11ClassInstance **class_instances, UINT *class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_vertex_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %p.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances || class_instance_count) + FIXME("Dynamic linking not implemented yet.\n"); + if (class_instance_count) + *class_instance_count = 0; + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_vertex_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + *shader = &shader_impl->ID3D11VertexShader_iface; + ID3D11VertexShader_AddRef(*shader); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSGetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IAGetInputLayout(ID3D11DeviceContext1 *iface, + ID3D11InputLayout **input_layout) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_vertex_declaration *wined3d_declaration; + struct d3d_input_layout *input_layout_impl; + + TRACE("iface %p, input_layout %p.\n", iface, input_layout); + + wined3d_mutex_lock(); + if (!(wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *input_layout = NULL; + return; + } + + input_layout_impl = wined3d_vertex_declaration_get_parent(wined3d_declaration); + wined3d_mutex_unlock(); + *input_layout = &input_layout_impl->ID3D11InputLayout_iface; + ID3D11InputLayout_AddRef(*input_layout); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IAGetVertexBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *strides, UINT *offsets) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p.\n", + iface, start_slot, buffer_count, buffers, strides, offsets); + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct wined3d_buffer *wined3d_buffer = NULL; + struct d3d_buffer *buffer_impl; + + if (FAILED(wined3d_device_get_stream_source(device->wined3d_device, start_slot + i, + &wined3d_buffer, &offsets[i], &strides[i]))) + { + FIXME("Failed to get vertex buffer %u.\n", start_slot + i); + if (strides) + strides[i] = 0; + if (offsets) + offsets[i] = 0; + } + + if (!wined3d_buffer) + { + buffers[i] = NULL; + continue; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + ID3D11Buffer_AddRef(buffers[i] = &buffer_impl->ID3D11Buffer_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IAGetIndexBuffer(ID3D11DeviceContext1 *iface, + ID3D11Buffer **buffer, DXGI_FORMAT *format, UINT *offset) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + enum wined3d_format_id wined3d_format; + struct wined3d_buffer *wined3d_buffer; + struct d3d_buffer *buffer_impl; + + TRACE("iface %p, buffer %p, format %p, offset %p.\n", iface, buffer, format, offset); + + wined3d_mutex_lock(); + wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format, offset); + *format = dxgi_format_from_wined3dformat(wined3d_format); + if (!wined3d_buffer) + { + wined3d_mutex_unlock(); + *buffer = NULL; + return; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + wined3d_mutex_unlock(); + ID3D11Buffer_AddRef(*buffer = &buffer_impl->ID3D11Buffer_iface); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSGetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSGetShader(ID3D11DeviceContext1 *iface, + ID3D11GeometryShader **shader, ID3D11ClassInstance **class_instances, UINT *class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_geometry_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %p.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances || class_instance_count) + FIXME("Dynamic linking not implemented yet.\n"); + if (class_instance_count) + *class_instance_count = 0; + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_geometry_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + *shader = &shader_impl->ID3D11GeometryShader_iface; + ID3D11GeometryShader_AddRef(*shader); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_IAGetPrimitiveTopology(ID3D11DeviceContext1 *iface, + D3D11_PRIMITIVE_TOPOLOGY *topology) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + enum wined3d_primitive_type primitive_type; + unsigned int patch_vertex_count; + + TRACE("iface %p, topology %p.\n", iface, topology); + + wined3d_mutex_lock(); + wined3d_device_get_primitive_type(device->wined3d_device, &primitive_type, &patch_vertex_count); + wined3d_mutex_unlock(); + + d3d11_primitive_topology_from_wined3d_primitive_type(primitive_type, patch_vertex_count, topology); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSGetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_vs_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + views[i] = &view_impl->ID3D11ShaderResourceView_iface; + ID3D11ShaderResourceView_AddRef(views[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSGetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState **samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct wined3d_sampler *wined3d_sampler; + struct d3d_sampler_state *sampler_impl; + + if (!(wined3d_sampler = wined3d_device_get_vs_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + samplers[i] = &sampler_impl->ID3D11SamplerState_iface; + ID3D11SamplerState_AddRef(samplers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GetPredication(ID3D11DeviceContext1 *iface, + ID3D11Predicate **predicate, BOOL *value) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_query *wined3d_predicate; + struct d3d_query *predicate_impl; + + TRACE("iface %p, predicate %p, value %p.\n", iface, predicate, value); + + wined3d_mutex_lock(); + if (!(wined3d_predicate = wined3d_device_get_predication(device->wined3d_device, value))) + { + wined3d_mutex_unlock(); + *predicate = NULL; + return; + } + + predicate_impl = wined3d_query_get_parent(wined3d_predicate); + wined3d_mutex_unlock(); + *predicate = (ID3D11Predicate *)&predicate_impl->ID3D11Query_iface; + ID3D11Predicate_AddRef(*predicate); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSGetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_gs_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + views[i] = &view_impl->ID3D11ShaderResourceView_iface; + ID3D11ShaderResourceView_AddRef(views[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSGetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState **samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler_impl; + struct wined3d_sampler *wined3d_sampler; + + if (!(wined3d_sampler = wined3d_device_get_gs_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + samplers[i] = &sampler_impl->ID3D11SamplerState_iface; + ID3D11SamplerState_AddRef(samplers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetRenderTargets(ID3D11DeviceContext1 *iface, + UINT render_target_view_count, ID3D11RenderTargetView **render_target_views, + ID3D11DepthStencilView **depth_stencil_view) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_rendertarget_view *wined3d_view; + + TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", + iface, render_target_view_count, render_target_views, depth_stencil_view); + + wined3d_mutex_lock(); + if (render_target_views) + { + struct d3d_rendertarget_view *view_impl; + unsigned int i; + + for (i = 0; i < render_target_view_count; ++i) + { + if (!(wined3d_view = wined3d_device_get_rendertarget_view(device->wined3d_device, i)) + || !(view_impl = wined3d_rendertarget_view_get_parent(wined3d_view))) + { + render_target_views[i] = NULL; + continue; + } + + render_target_views[i] = &view_impl->ID3D11RenderTargetView_iface; + ID3D11RenderTargetView_AddRef(render_target_views[i]); + } + } + + if (depth_stencil_view) + { + struct d3d_depthstencil_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_depth_stencil_view(device->wined3d_device)) + || !(view_impl = wined3d_rendertarget_view_get_parent(wined3d_view))) + { + *depth_stencil_view = NULL; + } + else + { + *depth_stencil_view = &view_impl->ID3D11DepthStencilView_iface; + ID3D11DepthStencilView_AddRef(*depth_stencil_view); + } + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetRenderTargetsAndUnorderedAccessViews( + ID3D11DeviceContext1 *iface, + UINT render_target_view_count, ID3D11RenderTargetView **render_target_views, + ID3D11DepthStencilView **depth_stencil_view, + UINT unordered_access_view_start_slot, UINT unordered_access_view_count, + ID3D11UnorderedAccessView **unordered_access_views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_unordered_access_view *wined3d_view; + struct d3d11_unordered_access_view *view_impl; + unsigned int i; + + TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p, " + "unordered_access_view_start_slot %u, unordered_access_view_count %u, " + "unordered_access_views %p.\n", + iface, render_target_view_count, render_target_views, depth_stencil_view, + unordered_access_view_start_slot, unordered_access_view_count, unordered_access_views); + + if (render_target_views || depth_stencil_view) + d3d11_immediate_context_OMGetRenderTargets(iface, render_target_view_count, + render_target_views, depth_stencil_view); + + if (unordered_access_views) + { + wined3d_mutex_lock(); + for (i = 0; i < unordered_access_view_count; ++i) + { + if (!(wined3d_view = wined3d_device_get_unordered_access_view(device->wined3d_device, + unordered_access_view_start_slot + i))) + { + unordered_access_views[i] = NULL; + continue; + } + + view_impl = wined3d_unordered_access_view_get_parent(wined3d_view); + unordered_access_views[i] = &view_impl->ID3D11UnorderedAccessView_iface; + ID3D11UnorderedAccessView_AddRef(unordered_access_views[i]); + } + wined3d_mutex_unlock(); + } +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetBlendState(ID3D11DeviceContext1 *iface, + ID3D11BlendState **blend_state, FLOAT blend_factor[4], UINT *sample_mask) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_blend_state *wined3d_state; + struct d3d_blend_state *blend_state_impl; + + TRACE("iface %p, blend_state %p, blend_factor %p, sample_mask %p.\n", + iface, blend_state, blend_factor, sample_mask); + + wined3d_mutex_lock(); + if ((wined3d_state = wined3d_device_get_blend_state(device->wined3d_device, + (struct wined3d_color *)blend_factor))) + { + blend_state_impl = wined3d_blend_state_get_parent(wined3d_state); + ID3D11BlendState_AddRef(*blend_state = &blend_state_impl->ID3D11BlendState_iface); + } + else + { + *blend_state = NULL; + } + *sample_mask = wined3d_device_get_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEMASK); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetDepthStencilState(ID3D11DeviceContext1 *iface, + ID3D11DepthStencilState **depth_stencil_state, UINT *stencil_ref) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + TRACE("iface %p, depth_stencil_state %p, stencil_ref %p.\n", + iface, depth_stencil_state, stencil_ref); + + if ((*depth_stencil_state = device->depth_stencil_state + ? &device->depth_stencil_state->ID3D11DepthStencilState_iface : NULL)) + ID3D11DepthStencilState_AddRef(*depth_stencil_state); + *stencil_ref = device->stencil_ref; +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_SOGetTargets(ID3D11DeviceContext1 *iface, + UINT buffer_count, ID3D11Buffer **buffers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, buffer_count %u, buffers %p.\n", iface, buffer_count, buffers); + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct wined3d_buffer *wined3d_buffer; + struct d3d_buffer *buffer_impl; + + if (!(wined3d_buffer = wined3d_device_get_stream_output(device->wined3d_device, i, NULL))) + { + buffers[i] = NULL; + continue; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffers[i] = &buffer_impl->ID3D11Buffer_iface; + ID3D11Buffer_AddRef(buffers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_RSGetState(ID3D11DeviceContext1 *iface, + ID3D11RasterizerState **rasterizer_state) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d_rasterizer_state *rasterizer_state_impl; + struct wined3d_rasterizer_state *wined3d_state; + + TRACE("iface %p, rasterizer_state %p.\n", iface, rasterizer_state); + + wined3d_mutex_lock(); + if ((wined3d_state = wined3d_device_get_rasterizer_state(device->wined3d_device))) + { + rasterizer_state_impl = wined3d_rasterizer_state_get_parent(wined3d_state); + ID3D11RasterizerState_AddRef(*rasterizer_state = &rasterizer_state_impl->ID3D11RasterizerState_iface); + } + else + { + *rasterizer_state = NULL; + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_RSGetViewports(ID3D11DeviceContext1 *iface, + UINT *viewport_count, D3D11_VIEWPORT *viewports) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_viewport wined3d_vp[WINED3D_MAX_VIEWPORTS]; + unsigned int actual_count = ARRAY_SIZE(wined3d_vp), i; + + TRACE("iface %p, viewport_count %p, viewports %p.\n", iface, viewport_count, viewports); + + if (!viewport_count) + return; + + wined3d_mutex_lock(); + wined3d_device_get_viewports(device->wined3d_device, &actual_count, viewports ? wined3d_vp : NULL); + wined3d_mutex_unlock(); + + if (!viewports) + { + *viewport_count = actual_count; + return; + } + + if (*viewport_count > actual_count) + memset(&viewports[actual_count], 0, (*viewport_count - actual_count) * sizeof(*viewports)); + + *viewport_count = min(actual_count, *viewport_count); + for (i = 0; i < *viewport_count; ++i) + { + viewports[i].TopLeftX = wined3d_vp[i].x; + viewports[i].TopLeftY = wined3d_vp[i].y; + viewports[i].Width = wined3d_vp[i].width; + viewports[i].Height = wined3d_vp[i].height; + viewports[i].MinDepth = wined3d_vp[i].min_z; + viewports[i].MaxDepth = wined3d_vp[i].max_z; + } +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_RSGetScissorRects(ID3D11DeviceContext1 *iface, + UINT *rect_count, D3D11_RECT *rects) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int actual_count; + + TRACE("iface %p, rect_count %p, rects %p.\n", iface, rect_count, rects); + + if (!rect_count) + return; + + actual_count = *rect_count; + + wined3d_mutex_lock(); + wined3d_device_get_scissor_rects(device->wined3d_device, &actual_count, rects); + wined3d_mutex_unlock(); + + if (!rects) + { + *rect_count = actual_count; + return; + } + + if (*rect_count > actual_count) + memset(&rects[actual_count], 0, (*rect_count - actual_count) * sizeof(*rects)); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSGetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_hs_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + ID3D11ShaderResourceView_AddRef(views[i] = &view_impl->ID3D11ShaderResourceView_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSGetShader(ID3D11DeviceContext1 *iface, + ID3D11HullShader **shader, ID3D11ClassInstance **class_instances, UINT *class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_hull_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %p.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances || class_instance_count) + FIXME("Dynamic linking not implemented yet.\n"); + if (class_instance_count) + *class_instance_count = 0; + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_hull_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + ID3D11HullShader_AddRef(*shader = &shader_impl->ID3D11HullShader_iface); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSGetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState **samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct wined3d_sampler *wined3d_sampler; + struct d3d_sampler_state *sampler_impl; + + if (!(wined3d_sampler = wined3d_device_get_hs_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + ID3D11SamplerState_AddRef(samplers[i] = &sampler_impl->ID3D11SamplerState_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSGetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSGetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_ds_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + ID3D11ShaderResourceView_AddRef(views[i] = &view_impl->ID3D11ShaderResourceView_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSGetShader(ID3D11DeviceContext1 *iface, + ID3D11DomainShader **shader, ID3D11ClassInstance **class_instances, UINT *class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_domain_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %p.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances || class_instance_count) + FIXME("Dynamic linking not implemented yet.\n"); + if (class_instance_count) + *class_instance_count = 0; + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_domain_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + ID3D11DomainShader_AddRef(*shader = &shader_impl->ID3D11DomainShader_iface); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSGetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState **samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct wined3d_sampler *wined3d_sampler; + struct d3d_sampler_state *sampler_impl; + + if (!(wined3d_sampler = wined3d_device_get_ds_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + ID3D11SamplerState_AddRef(samplers[i] = &sampler_impl->ID3D11SamplerState_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSGetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetShaderResources(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11ShaderResourceView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_cs_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + ID3D11ShaderResourceView_AddRef(views[i] = &view_impl->ID3D11ShaderResourceView_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetUnorderedAccessViews(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT view_count, ID3D11UnorderedAccessView **views) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_unordered_access_view *wined3d_view; + struct d3d11_unordered_access_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_cs_uav(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_unordered_access_view_get_parent(wined3d_view); + ID3D11UnorderedAccessView_AddRef(views[i] = &view_impl->ID3D11UnorderedAccessView_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetShader(ID3D11DeviceContext1 *iface, + ID3D11ComputeShader **shader, ID3D11ClassInstance **class_instances, UINT *class_instance_count) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_compute_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p, class_instances %p, class_instance_count %p.\n", + iface, shader, class_instances, class_instance_count); + + if (class_instances || class_instance_count) + FIXME("Dynamic linking not implemented yet.\n"); + if (class_instance_count) + *class_instance_count = 0; + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_compute_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + ID3D11ComputeShader_AddRef(*shader = &shader_impl->ID3D11ComputeShader_iface); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetSamplers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT sampler_count, ID3D11SamplerState **samplers) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct wined3d_sampler *wined3d_sampler; + struct d3d_sampler_state *sampler_impl; + + if (!(wined3d_sampler = wined3d_device_get_cs_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + ID3D11SamplerState_AddRef(samplers[i] = &sampler_impl->ID3D11SamplerState_iface); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetConstantBuffers(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d11_immediate_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ClearState(ID3D11DeviceContext1 *iface) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + static const float blend_factor[] = {1.0f, 1.0f, 1.0f, 1.0f}; + unsigned int i, j; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + wined3d_device_set_vertex_shader(device->wined3d_device, NULL); + wined3d_device_set_hull_shader(device->wined3d_device, NULL); + wined3d_device_set_domain_shader(device->wined3d_device, NULL); + wined3d_device_set_geometry_shader(device->wined3d_device, NULL); + wined3d_device_set_pixel_shader(device->wined3d_device, NULL); + wined3d_device_set_compute_shader(device->wined3d_device, NULL); + for (i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + wined3d_device_set_vs_sampler(device->wined3d_device, i, NULL); + wined3d_device_set_hs_sampler(device->wined3d_device, i, NULL); + wined3d_device_set_ds_sampler(device->wined3d_device, i, NULL); + wined3d_device_set_gs_sampler(device->wined3d_device, i, NULL); + wined3d_device_set_ps_sampler(device->wined3d_device, i, NULL); + wined3d_device_set_cs_sampler(device->wined3d_device, i, NULL); + } + for (i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + wined3d_device_set_vs_resource_view(device->wined3d_device, i, NULL); + wined3d_device_set_hs_resource_view(device->wined3d_device, i, NULL); + wined3d_device_set_ds_resource_view(device->wined3d_device, i, NULL); + wined3d_device_set_gs_resource_view(device->wined3d_device, i, NULL); + wined3d_device_set_ps_resource_view(device->wined3d_device, i, NULL); + wined3d_device_set_cs_resource_view(device->wined3d_device, i, NULL); + } + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + for (j = 0; j < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++j) + wined3d_device_set_constant_buffer(device->wined3d_device, i, j, NULL); + } + for (i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i) + { + wined3d_device_set_stream_source(device->wined3d_device, i, NULL, 0, 0); + } + wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); + wined3d_device_set_vertex_declaration(device->wined3d_device, NULL); + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_UNDEFINED, 0); + for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + wined3d_device_set_rendertarget_view(device->wined3d_device, i, NULL, FALSE); + } + wined3d_device_set_depth_stencil_view(device->wined3d_device, NULL); + for (i = 0; i < D3D11_PS_CS_UAV_REGISTER_COUNT; ++i) + { + wined3d_device_set_unordered_access_view(device->wined3d_device, i, NULL, ~0u); + wined3d_device_set_cs_uav(device->wined3d_device, i, NULL, ~0u); + } + ID3D11DeviceContext1_OMSetDepthStencilState(iface, NULL, 0); + ID3D11DeviceContext1_OMSetBlendState(iface, NULL, blend_factor, D3D11_DEFAULT_SAMPLE_MASK); + ID3D11DeviceContext1_RSSetViewports(iface, 0, NULL); + ID3D11DeviceContext1_RSSetScissorRects(iface, 0, NULL); + ID3D11DeviceContext1_RSSetState(iface, NULL); + for (i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; ++i) + { + wined3d_device_set_stream_output(device->wined3d_device, i, NULL, 0); + } + wined3d_device_set_predication(device->wined3d_device, NULL, FALSE); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_Flush(ID3D11DeviceContext1 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE d3d11_immediate_context_GetType(ID3D11DeviceContext1 *iface) +{ + TRACE("iface %p.\n", iface); + + return D3D11_DEVICE_CONTEXT_IMMEDIATE; +} + +static UINT STDMETHODCALLTYPE d3d11_immediate_context_GetContextFlags(ID3D11DeviceContext1 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_FinishCommandList(ID3D11DeviceContext1 *iface, + BOOL restore, ID3D11CommandList **command_list) +{ + FIXME("iface %p, restore %#x, command_list %p stub!\n", iface, restore, command_list); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CopySubresourceRegion1(ID3D11DeviceContext1 *iface, + ID3D11Resource *dst_resource, UINT dst_subresource_idx, UINT dst_x, UINT dst_y, UINT dst_z, + ID3D11Resource *src_resource, UINT src_subresource_idx, const D3D11_BOX *src_box, UINT flags) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct wined3d_box wined3d_src_box; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, dst_x %u, dst_y %u, dst_z %u, " + "src_resource %p, src_subresource_idx %u, src_box %p, flags %#x.\n", + iface, dst_resource, dst_subresource_idx, dst_x, dst_y, dst_z, + src_resource, src_subresource_idx, src_box, flags); + + if (src_box) + wined3d_box_set(&wined3d_src_box, src_box->left, src_box->top, + src_box->right, src_box->bottom, src_box->front, src_box->back); + + wined3d_dst_resource = wined3d_resource_from_d3d11_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d11_resource(src_resource); + wined3d_mutex_lock(); + wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_dst_resource, dst_subresource_idx, + dst_x, dst_y, dst_z, wined3d_src_resource, src_subresource_idx, src_box ? &wined3d_src_box : NULL, flags); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_UpdateSubresource1(ID3D11DeviceContext1 *iface, + ID3D11Resource *resource, UINT subresource_idx, const D3D11_BOX *box, const void *data, + UINT row_pitch, UINT depth_pitch, UINT flags) +{ + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_resource *wined3d_resource; + struct wined3d_box wined3d_box; + + TRACE("iface %p, resource %p, subresource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u, flags %#x.\n", + iface, resource, subresource_idx, box, data, row_pitch, depth_pitch, flags); + + if (box) + wined3d_box_set(&wined3d_box, box->left, box->top, box->right, box->bottom, + box->front, box->back); + + wined3d_resource = wined3d_resource_from_d3d11_resource(resource); + wined3d_mutex_lock(); + wined3d_device_update_sub_resource(device->wined3d_device, wined3d_resource, subresource_idx, + box ? &wined3d_box : NULL, data, row_pitch, depth_pitch, flags); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DiscardResource(ID3D11DeviceContext1 *iface, + ID3D11Resource *resource) +{ + FIXME("iface %p, resource %p stub!\n", iface, resource); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DiscardView(ID3D11DeviceContext1 *iface, ID3D11View *view) +{ + FIXME("iface %p, view %p stub!\n", iface, view); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSSetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, + const UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSSetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, + const UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSSetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, + const UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSSetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, + const UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSSetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, + const UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, + const UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_VSGetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_HSGetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DSGetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_GSGetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_PSGetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetConstantBuffers1(ID3D11DeviceContext1 *iface, + UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) +{ + FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + iface, start_slot, buffer_count, buffers, first_constant, num_constants); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3D11DeviceContext1 *iface, + ID3DDeviceContextState *state, ID3DDeviceContextState **prev_state) +{ + FIXME("iface %p, state %p, prev_state %p stub!\n", iface, state, prev_state); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_ClearView(ID3D11DeviceContext1 *iface, ID3D11View *view, + const FLOAT color[4], const D3D11_RECT *rect, UINT num_rects) +{ + FIXME("iface %p, view %p, color %p, rect %p, num_rects %u stub!\n", iface, view, color, rect, num_rects); +} + +static void STDMETHODCALLTYPE d3d11_immediate_context_DiscardView1(ID3D11DeviceContext1 *iface, ID3D11View *view, + const D3D11_RECT *rects, UINT num_rects) +{ + FIXME("iface %p, view %p, rects %p, num_rects %u stub!\n", iface, view, rects, num_rects); +} + +static const struct ID3D11DeviceContext1Vtbl d3d11_immediate_context_vtbl = +{ + /* IUnknown methods */ + d3d11_immediate_context_QueryInterface, + d3d11_immediate_context_AddRef, + d3d11_immediate_context_Release, + /* ID3D11DeviceChild methods */ + d3d11_immediate_context_GetDevice, + d3d11_immediate_context_GetPrivateData, + d3d11_immediate_context_SetPrivateData, + d3d11_immediate_context_SetPrivateDataInterface, + /* ID3D11DeviceContext methods */ + d3d11_immediate_context_VSSetConstantBuffers, + d3d11_immediate_context_PSSetShaderResources, + d3d11_immediate_context_PSSetShader, + d3d11_immediate_context_PSSetSamplers, + d3d11_immediate_context_VSSetShader, + d3d11_immediate_context_DrawIndexed, + d3d11_immediate_context_Draw, + d3d11_immediate_context_Map, + d3d11_immediate_context_Unmap, + d3d11_immediate_context_PSSetConstantBuffers, + d3d11_immediate_context_IASetInputLayout, + d3d11_immediate_context_IASetVertexBuffers, + d3d11_immediate_context_IASetIndexBuffer, + d3d11_immediate_context_DrawIndexedInstanced, + d3d11_immediate_context_DrawInstanced, + d3d11_immediate_context_GSSetConstantBuffers, + d3d11_immediate_context_GSSetShader, + d3d11_immediate_context_IASetPrimitiveTopology, + d3d11_immediate_context_VSSetShaderResources, + d3d11_immediate_context_VSSetSamplers, + d3d11_immediate_context_Begin, + d3d11_immediate_context_End, + d3d11_immediate_context_GetData, + d3d11_immediate_context_SetPredication, + d3d11_immediate_context_GSSetShaderResources, + d3d11_immediate_context_GSSetSamplers, + d3d11_immediate_context_OMSetRenderTargets, + d3d11_immediate_context_OMSetRenderTargetsAndUnorderedAccessViews, + d3d11_immediate_context_OMSetBlendState, + d3d11_immediate_context_OMSetDepthStencilState, + d3d11_immediate_context_SOSetTargets, + d3d11_immediate_context_DrawAuto, + d3d11_immediate_context_DrawIndexedInstancedIndirect, + d3d11_immediate_context_DrawInstancedIndirect, + d3d11_immediate_context_Dispatch, + d3d11_immediate_context_DispatchIndirect, + d3d11_immediate_context_RSSetState, + d3d11_immediate_context_RSSetViewports, + d3d11_immediate_context_RSSetScissorRects, + d3d11_immediate_context_CopySubresourceRegion, + d3d11_immediate_context_CopyResource, + d3d11_immediate_context_UpdateSubresource, + d3d11_immediate_context_CopyStructureCount, + d3d11_immediate_context_ClearRenderTargetView, + d3d11_immediate_context_ClearUnorderedAccessViewUint, + d3d11_immediate_context_ClearUnorderedAccessViewFloat, + d3d11_immediate_context_ClearDepthStencilView, + d3d11_immediate_context_GenerateMips, + d3d11_immediate_context_SetResourceMinLOD, + d3d11_immediate_context_GetResourceMinLOD, + d3d11_immediate_context_ResolveSubresource, + d3d11_immediate_context_ExecuteCommandList, + d3d11_immediate_context_HSSetShaderResources, + d3d11_immediate_context_HSSetShader, + d3d11_immediate_context_HSSetSamplers, + d3d11_immediate_context_HSSetConstantBuffers, + d3d11_immediate_context_DSSetShaderResources, + d3d11_immediate_context_DSSetShader, + d3d11_immediate_context_DSSetSamplers, + d3d11_immediate_context_DSSetConstantBuffers, + d3d11_immediate_context_CSSetShaderResources, + d3d11_immediate_context_CSSetUnorderedAccessViews, + d3d11_immediate_context_CSSetShader, + d3d11_immediate_context_CSSetSamplers, + d3d11_immediate_context_CSSetConstantBuffers, + d3d11_immediate_context_VSGetConstantBuffers, + d3d11_immediate_context_PSGetShaderResources, + d3d11_immediate_context_PSGetShader, + d3d11_immediate_context_PSGetSamplers, + d3d11_immediate_context_VSGetShader, + d3d11_immediate_context_PSGetConstantBuffers, + d3d11_immediate_context_IAGetInputLayout, + d3d11_immediate_context_IAGetVertexBuffers, + d3d11_immediate_context_IAGetIndexBuffer, + d3d11_immediate_context_GSGetConstantBuffers, + d3d11_immediate_context_GSGetShader, + d3d11_immediate_context_IAGetPrimitiveTopology, + d3d11_immediate_context_VSGetShaderResources, + d3d11_immediate_context_VSGetSamplers, + d3d11_immediate_context_GetPredication, + d3d11_immediate_context_GSGetShaderResources, + d3d11_immediate_context_GSGetSamplers, + d3d11_immediate_context_OMGetRenderTargets, + d3d11_immediate_context_OMGetRenderTargetsAndUnorderedAccessViews, + d3d11_immediate_context_OMGetBlendState, + d3d11_immediate_context_OMGetDepthStencilState, + d3d11_immediate_context_SOGetTargets, + d3d11_immediate_context_RSGetState, + d3d11_immediate_context_RSGetViewports, + d3d11_immediate_context_RSGetScissorRects, + d3d11_immediate_context_HSGetShaderResources, + d3d11_immediate_context_HSGetShader, + d3d11_immediate_context_HSGetSamplers, + d3d11_immediate_context_HSGetConstantBuffers, + d3d11_immediate_context_DSGetShaderResources, + d3d11_immediate_context_DSGetShader, + d3d11_immediate_context_DSGetSamplers, + d3d11_immediate_context_DSGetConstantBuffers, + d3d11_immediate_context_CSGetShaderResources, + d3d11_immediate_context_CSGetUnorderedAccessViews, + d3d11_immediate_context_CSGetShader, + d3d11_immediate_context_CSGetSamplers, + d3d11_immediate_context_CSGetConstantBuffers, + d3d11_immediate_context_ClearState, + d3d11_immediate_context_Flush, + d3d11_immediate_context_GetType, + d3d11_immediate_context_GetContextFlags, + d3d11_immediate_context_FinishCommandList, + /* ID3D11DeviceContext1 methods */ + d3d11_immediate_context_CopySubresourceRegion1, + d3d11_immediate_context_UpdateSubresource1, + d3d11_immediate_context_DiscardResource, + d3d11_immediate_context_DiscardView, + d3d11_immediate_context_VSSetConstantBuffers1, + d3d11_immediate_context_HSSetConstantBuffers1, + d3d11_immediate_context_DSSetConstantBuffers1, + d3d11_immediate_context_GSSetConstantBuffers1, + d3d11_immediate_context_PSSetConstantBuffers1, + d3d11_immediate_context_CSSetConstantBuffers1, + d3d11_immediate_context_VSGetConstantBuffers1, + d3d11_immediate_context_HSGetConstantBuffers1, + d3d11_immediate_context_DSGetConstantBuffers1, + d3d11_immediate_context_GSGetConstantBuffers1, + d3d11_immediate_context_PSGetConstantBuffers1, + d3d11_immediate_context_CSGetConstantBuffers1, + d3d11_immediate_context_SwapDeviceContextState, + d3d11_immediate_context_ClearView, + d3d11_immediate_context_DiscardView1, +}; + +/* ID3D11Multithread methods */ + +static inline struct d3d11_immediate_context *impl_from_ID3D11Multithread(ID3D11Multithread *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_immediate_context, ID3D11Multithread_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_multithread_QueryInterface(ID3D11Multithread *iface, + REFIID iid, void **out) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11Multithread(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return d3d11_immediate_context_QueryInterface(&context->ID3D11DeviceContext1_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE d3d11_multithread_AddRef(ID3D11Multithread *iface) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11Multithread(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_immediate_context_AddRef(&context->ID3D11DeviceContext1_iface); +} + +static ULONG STDMETHODCALLTYPE d3d11_multithread_Release(ID3D11Multithread *iface) +{ + struct d3d11_immediate_context *context = impl_from_ID3D11Multithread(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_immediate_context_Release(&context->ID3D11DeviceContext1_iface); +} + +static void STDMETHODCALLTYPE d3d11_multithread_Enter(ID3D11Multithread *iface) +{ + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); +} + +static void STDMETHODCALLTYPE d3d11_multithread_Leave(ID3D11Multithread *iface) +{ + TRACE("iface %p.\n", iface); + + wined3d_mutex_unlock(); +} + +static BOOL STDMETHODCALLTYPE d3d11_multithread_SetMultithreadProtected( + ID3D11Multithread *iface, BOOL enable) +{ + FIXME("iface %p, enable %#x stub!\n", iface, enable); + + return TRUE; +} + +static BOOL STDMETHODCALLTYPE d3d11_multithread_GetMultithreadProtected(ID3D11Multithread *iface) +{ + FIXME("iface %p stub!\n", iface); + + return TRUE; +} + +static const struct ID3D11MultithreadVtbl d3d11_multithread_vtbl = +{ + d3d11_multithread_QueryInterface, + d3d11_multithread_AddRef, + d3d11_multithread_Release, + d3d11_multithread_Enter, + d3d11_multithread_Leave, + d3d11_multithread_SetMultithreadProtected, + d3d11_multithread_GetMultithreadProtected, +}; + +static void d3d11_immediate_context_init(struct d3d11_immediate_context *context, struct d3d_device *device) +{ + context->ID3D11DeviceContext1_iface.lpVtbl = &d3d11_immediate_context_vtbl; + context->ID3D11Multithread_iface.lpVtbl = &d3d11_multithread_vtbl; + context->refcount = 1; + + ID3D11Device2_AddRef(&device->ID3D11Device2_iface); + + wined3d_private_store_init(&context->private_store); +} + +static void d3d11_immediate_context_destroy(struct d3d11_immediate_context *context) +{ + wined3d_private_store_cleanup(&context->private_store); +} + +/* ID3D11Device methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_device_QueryInterface(ID3D11Device2 *iface, REFIID iid, void **out) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + return IUnknown_QueryInterface(device->outer_unk, iid, out); +} + +static ULONG STDMETHODCALLTYPE d3d11_device_AddRef(ID3D11Device2 *iface) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + return IUnknown_AddRef(device->outer_unk); +} + +static ULONG STDMETHODCALLTYPE d3d11_device_Release(ID3D11Device2 *iface) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + return IUnknown_Release(device->outer_unk); +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBuffer(ID3D11Device2 *iface, const D3D11_BUFFER_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, ID3D11Buffer **buffer) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_buffer *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, buffer %p.\n", iface, desc, data, buffer); + + if (FAILED(hr = d3d_buffer_create(device, desc, data, &object))) + return hr; + + *buffer = &object->ID3D11Buffer_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture1D(ID3D11Device2 *iface, + const D3D11_TEXTURE1D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data, ID3D11Texture1D **texture) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_texture1d *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + if (FAILED(hr = d3d_texture1d_create(device, desc, data, &object))) + return hr; + + *texture = &object->ID3D11Texture1D_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture2D(ID3D11Device2 *iface, + const D3D11_TEXTURE2D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data, ID3D11Texture2D **texture) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_texture2d *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + if (FAILED(hr = d3d_texture2d_create(device, desc, data, &object))) + return hr; + + *texture = &object->ID3D11Texture2D_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture3D(ID3D11Device2 *iface, + const D3D11_TEXTURE3D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data, ID3D11Texture3D **texture) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_texture3d *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + if (FAILED(hr = d3d_texture3d_create(device, desc, data, &object))) + return hr; + + *texture = &object->ID3D11Texture3D_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateShaderResourceView(ID3D11Device2 *iface, + ID3D11Resource *resource, const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11ShaderResourceView **view) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_shader_resource_view *object; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (!resource) + return E_INVALIDARG; + + if (FAILED(hr = d3d_shader_resource_view_create(device, resource, desc, &object))) + return hr; + + *view = &object->ID3D11ShaderResourceView_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateUnorderedAccessView(ID3D11Device2 *iface, + ID3D11Resource *resource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11UnorderedAccessView **view) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_unordered_access_view *object; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (FAILED(hr = d3d11_unordered_access_view_create(device, resource, desc, &object))) + return hr; + + *view = &object->ID3D11UnorderedAccessView_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateRenderTargetView(ID3D11Device2 *iface, + ID3D11Resource *resource, const D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11RenderTargetView **view) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_rendertarget_view *object; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (!resource) + return E_INVALIDARG; + + if (FAILED(hr = d3d_rendertarget_view_create(device, resource, desc, &object))) + return hr; + + *view = &object->ID3D11RenderTargetView_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDepthStencilView(ID3D11Device2 *iface, + ID3D11Resource *resource, const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11DepthStencilView **view) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_depthstencil_view *object; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (FAILED(hr = d3d_depthstencil_view_create(device, resource, desc, &object))) + return hr; + + *view = &object->ID3D11DepthStencilView_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateInputLayout(ID3D11Device2 *iface, + const D3D11_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code, + SIZE_T shader_byte_code_length, ID3D11InputLayout **input_layout) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_input_layout *object; + HRESULT hr; + + TRACE("iface %p, element_descs %p, element_count %u, shader_byte_code %p, shader_byte_code_length %lu, " + "input_layout %p.\n", iface, element_descs, element_count, shader_byte_code, + shader_byte_code_length, input_layout); + + if (FAILED(hr = d3d_input_layout_create(device, element_descs, element_count, + shader_byte_code, shader_byte_code_length, &object))) + return hr; + + *input_layout = &object->ID3D11InputLayout_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateVertexShader(ID3D11Device2 *iface, const void *byte_code, + SIZE_T byte_code_length, ID3D11ClassLinkage *class_linkage, ID3D11VertexShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_vertex_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d_vertex_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D11VertexShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateGeometryShader(ID3D11Device2 *iface, const void *byte_code, + SIZE_T byte_code_length, ID3D11ClassLinkage *class_linkage, ID3D11GeometryShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_geometry_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length, + NULL, 0, NULL, 0, 0, &object))) + return hr; + + *shader = &object->ID3D11GeometryShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateGeometryShaderWithStreamOutput(ID3D11Device2 *iface, + const void *byte_code, SIZE_T byte_code_length, const D3D11_SO_DECLARATION_ENTRY *so_entries, + UINT entry_count, const UINT *buffer_strides, UINT strides_count, UINT rasterizer_stream, + ID3D11ClassLinkage *class_linkage, ID3D11GeometryShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_geometry_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, so_entries %p, entry_count %u, " + "buffer_strides %p, strides_count %u, rasterizer_stream %u, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, so_entries, entry_count, buffer_strides, strides_count, + rasterizer_stream, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length, + so_entries, entry_count, buffer_strides, strides_count, rasterizer_stream, &object))) + { + *shader = NULL; + return hr; + } + + *shader = &object->ID3D11GeometryShader_iface; + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreatePixelShader(ID3D11Device2 *iface, const void *byte_code, + SIZE_T byte_code_length, ID3D11ClassLinkage *class_linkage, ID3D11PixelShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_pixel_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d_pixel_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D11PixelShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateHullShader(ID3D11Device2 *iface, const void *byte_code, + SIZE_T byte_code_length, ID3D11ClassLinkage *class_linkage, ID3D11HullShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_hull_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d11_hull_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D11HullShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDomainShader(ID3D11Device2 *iface, const void *byte_code, + SIZE_T byte_code_length, ID3D11ClassLinkage *class_linkage, ID3D11DomainShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_domain_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d11_domain_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D11DomainShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateComputeShader(ID3D11Device2 *iface, const void *byte_code, + SIZE_T byte_code_length, ID3D11ClassLinkage *class_linkage, ID3D11ComputeShader **shader) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_compute_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n", + iface, byte_code, byte_code_length, class_linkage, shader); + + if (class_linkage) + FIXME("Class linkage is not implemented yet.\n"); + + if (FAILED(hr = d3d11_compute_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D11ComputeShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateClassLinkage(ID3D11Device2 *iface, + ID3D11ClassLinkage **class_linkage) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_class_linkage *object; + HRESULT hr; + + TRACE("iface %p, class_linkage %p.\n", iface, class_linkage); + + if (FAILED(hr = d3d11_class_linkage_create(device, &object))) + return hr; + + *class_linkage = &object->ID3D11ClassLinkage_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState(ID3D11Device2 *iface, + const D3D11_BLEND_DESC *desc, ID3D11BlendState **blend_state) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_blend_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state); + + if (FAILED(hr = d3d_blend_state_create(device, desc, &object))) + return hr; + + *blend_state = &object->ID3D11BlendState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDepthStencilState(ID3D11Device2 *iface, + const D3D11_DEPTH_STENCIL_DESC *desc, ID3D11DepthStencilState **depth_stencil_state) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_depthstencil_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, depth_stencil_state %p.\n", iface, desc, depth_stencil_state); + + if (FAILED(hr = d3d_depthstencil_state_create(device, desc, &object))) + return hr; + + *depth_stencil_state = &object->ID3D11DepthStencilState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateRasterizerState(ID3D11Device2 *iface, + const D3D11_RASTERIZER_DESC *desc, ID3D11RasterizerState **rasterizer_state) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_rasterizer_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, rasterizer_state %p.\n", iface, desc, rasterizer_state); + + if (FAILED(hr = d3d_rasterizer_state_create(device, desc, &object))) + return hr; + + *rasterizer_state = &object->ID3D11RasterizerState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateSamplerState(ID3D11Device2 *iface, + const D3D11_SAMPLER_DESC *desc, ID3D11SamplerState **sampler_state) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_sampler_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, sampler_state %p.\n", iface, desc, sampler_state); + + if (FAILED(hr = d3d_sampler_state_create(device, desc, &object))) + return hr; + + *sampler_state = &object->ID3D11SamplerState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateQuery(ID3D11Device2 *iface, + const D3D11_QUERY_DESC *desc, ID3D11Query **query) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_query *object; + HRESULT hr; + + TRACE("iface %p, desc %p, query %p.\n", iface, desc, query); + + if (FAILED(hr = d3d_query_create(device, desc, FALSE, &object))) + return hr; + + if (query) + { + *query = &object->ID3D11Query_iface; + return S_OK; + } + + ID3D11Query_Release(&object->ID3D11Query_iface); + return S_FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreatePredicate(ID3D11Device2 *iface, const D3D11_QUERY_DESC *desc, + ID3D11Predicate **predicate) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_query *object; + HRESULT hr; + + TRACE("iface %p, desc %p, predicate %p.\n", iface, desc, predicate); + + if (FAILED(hr = d3d_query_create(device, desc, TRUE, &object))) + return hr; + + if (predicate) + { + *predicate = (ID3D11Predicate *)&object->ID3D11Query_iface; + return S_OK; + } + + ID3D11Query_Release(&object->ID3D11Query_iface); + return S_FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateCounter(ID3D11Device2 *iface, const D3D11_COUNTER_DESC *desc, + ID3D11Counter **counter) +{ + FIXME("iface %p, desc %p, counter %p stub!\n", iface, desc, counter); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeferredContext(ID3D11Device2 *iface, UINT flags, + ID3D11DeviceContext **context) +{ + FIXME("iface %p, flags %#x, context %p stub!\n", iface, flags, context); + + *context = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_OpenSharedResource(ID3D11Device2 *iface, HANDLE resource, REFIID iid, + void **out) +{ + FIXME("iface %p, resource %p, iid %s, out %p stub!\n", iface, resource, debugstr_guid(iid), out); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFormatSupport(ID3D11Device2 *iface, DXGI_FORMAT format, + UINT *format_support) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct wined3d_device_creation_parameters params; + enum wined3d_format_id wined3d_format; + D3D_FEATURE_LEVEL feature_level; + struct wined3d *wined3d; + unsigned int i; + + static const struct + { + enum wined3d_resource_type rtype; + unsigned int bind_flags; + D3D11_FORMAT_SUPPORT flag; + } + flag_mapping[] = + { + {WINED3D_RTYPE_TEXTURE_1D, WINED3D_BIND_SHADER_RESOURCE, D3D11_FORMAT_SUPPORT_TEXTURE1D}, + {WINED3D_RTYPE_TEXTURE_2D, WINED3D_BIND_SHADER_RESOURCE, D3D11_FORMAT_SUPPORT_TEXTURE2D}, + {WINED3D_RTYPE_TEXTURE_3D, WINED3D_BIND_SHADER_RESOURCE, D3D11_FORMAT_SUPPORT_TEXTURE3D}, + {WINED3D_RTYPE_NONE, WINED3D_BIND_RENDER_TARGET, D3D11_FORMAT_SUPPORT_RENDER_TARGET}, + {WINED3D_RTYPE_NONE, WINED3D_BIND_DEPTH_STENCIL, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL}, + }; + HRESULT hr; + + FIXME("iface %p, format %u, format_support %p partial-stub!\n", iface, format, format_support); + + wined3d_format = wined3dformat_from_dxgi_format(format); + if (format && !wined3d_format) + { + WARN("Invalid format %#x.\n", format); + *format_support = 0; + return E_FAIL; + } + + *format_support = 0; + + wined3d_mutex_lock(); + feature_level = device->feature_level; + wined3d = wined3d_device_get_wined3d(device->wined3d_device); + wined3d_device_get_creation_parameters(device->wined3d_device, ¶ms); + for (i = 0; i < ARRAY_SIZE(flag_mapping); ++i) + { + hr = wined3d_check_device_format(wined3d, params.adapter_idx, params.device_type, + WINED3DFMT_UNKNOWN, 0, flag_mapping[i].bind_flags, flag_mapping[i].rtype, wined3d_format); + if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DOK_NOMIPGEN) + continue; + if (hr != WINED3D_OK) + { + WARN("Failed to check device format support, hr %#x.\n", hr); + wined3d_mutex_unlock(); + return E_FAIL; + } + + *format_support |= flag_mapping[i].flag; + } + wined3d_mutex_unlock(); + + if (*format_support & (D3D11_FORMAT_SUPPORT_TEXTURE1D + | D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D)) + { + *format_support |= D3D11_FORMAT_SUPPORT_SHADER_LOAD; + *format_support |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; + + if (feature_level >= D3D_FEATURE_LEVEL_10_1) + *format_support |= D3D11_FORMAT_SUPPORT_SHADER_GATHER; + + if (*format_support & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) + { + if (feature_level >= D3D_FEATURE_LEVEL_10_0) + *format_support |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON; + + if (feature_level >= D3D_FEATURE_LEVEL_10_1) + *format_support |= D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON; + } + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CheckMultisampleQualityLevels(ID3D11Device2 *iface, + DXGI_FORMAT format, UINT sample_count, UINT *quality_level_count) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct wined3d_device_creation_parameters params; + struct wined3d *wined3d; + HRESULT hr; + + TRACE("iface %p, format %s, sample_count %u, quality_level_count %p.\n", + iface, debug_dxgi_format(format), sample_count, quality_level_count); + + if (!quality_level_count) + return E_INVALIDARG; + + *quality_level_count = 0; + + if (!sample_count) + return E_FAIL; + if (sample_count == 1) + { + *quality_level_count = 1; + return S_OK; + } + if (sample_count > D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT) + return E_FAIL; + + wined3d_mutex_lock(); + wined3d = wined3d_device_get_wined3d(device->wined3d_device); + wined3d_device_get_creation_parameters(device->wined3d_device, ¶ms); + hr = wined3d_check_device_multisample_type(wined3d, params.adapter_idx, params.device_type, + wined3dformat_from_dxgi_format(format), TRUE, sample_count, quality_level_count); + wined3d_mutex_unlock(); + + if (hr == WINED3DERR_INVALIDCALL) + return E_INVALIDARG; + if (hr == WINED3DERR_NOTAVAILABLE) + return S_OK; + return hr; +} + +static void STDMETHODCALLTYPE d3d11_device_CheckCounterInfo(ID3D11Device2 *iface, D3D11_COUNTER_INFO *info) +{ + FIXME("iface %p, info %p stub!\n", iface, info); +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CheckCounter(ID3D11Device2 *iface, const D3D11_COUNTER_DESC *desc, + D3D11_COUNTER_TYPE *type, UINT *active_counter_count, char *name, UINT *name_length, + char *units, UINT *units_length, char *description, UINT *description_length) +{ + FIXME("iface %p, desc %p, type %p, active_counter_count %p, name %p, name_length %p, " + "units %p, units_length %p, description %p, description_length %p stub!\n", + iface, desc, type, active_counter_count, name, name_length, + units, units_length, description, description_length); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFeatureSupport(ID3D11Device2 *iface, D3D11_FEATURE feature, + void *feature_support_data, UINT feature_support_data_size) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct wined3d_caps wined3d_caps; + HRESULT hr; + + TRACE("iface %p, feature %u, feature_support_data %p, feature_support_data_size %u.\n", + iface, feature, feature_support_data, feature_support_data_size); + + switch (feature) + { + case D3D11_FEATURE_THREADING: + { + D3D11_FEATURE_DATA_THREADING *threading_data = feature_support_data; + if (feature_support_data_size != sizeof(*threading_data)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + /* We lie about the threading support to make Tomb Raider 2013 and + * Deus Ex: Human Revolution happy. */ + FIXME("Returning fake threading support data.\n"); + threading_data->DriverConcurrentCreates = TRUE; + threading_data->DriverCommandLists = TRUE; + return S_OK; + } + + case D3D11_FEATURE_DOUBLES: + { + D3D11_FEATURE_DATA_DOUBLES *doubles_data = feature_support_data; + if (feature_support_data_size != sizeof(*doubles_data)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to get device caps, hr %#x.\n", hr); + return hr; + } + + doubles_data->DoublePrecisionFloatShaderOps = wined3d_caps.shader_double_precision; + return S_OK; + } + + case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS: + { + D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS *options = feature_support_data; + if (feature_support_data_size != sizeof(*options)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + options->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = FALSE; + return S_OK; + } + + case D3D11_FEATURE_D3D11_OPTIONS: + { + D3D11_FEATURE_DATA_D3D11_OPTIONS *options = feature_support_data; + if (feature_support_data_size != sizeof(*options)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + FIXME("Returning fake Options support data.\n"); + options->OutputMergerLogicOp = FALSE; + options->UAVOnlyRenderingForcedSampleCount = FALSE; + options->DiscardAPIsSeenByDriver = FALSE; + options->FlagsForUpdateAndCopySeenByDriver = FALSE; + options->ClearView = FALSE; + options->CopyWithOverlap = FALSE; + options->ConstantBufferPartialUpdate = FALSE; + options->ConstantBufferOffsetting = FALSE; + options->MapNoOverwriteOnDynamicConstantBuffer = FALSE; + options->MapNoOverwriteOnDynamicBufferSRV = FALSE; + options->MultisampleRTVWithForcedSampleCountOne = FALSE; + options->SAD4ShaderInstructions = FALSE; + options->ExtendedDoublesShaderInstructions = FALSE; + options->ExtendedResourceSharing = FALSE; + return S_OK; + } + + case D3D11_FEATURE_D3D11_OPTIONS1: + { + D3D11_FEATURE_DATA_D3D11_OPTIONS1 *options = feature_support_data; + if (feature_support_data_size != sizeof(*options)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + FIXME("Returning fake Options1 support data.\n"); + options->TiledResourcesTier = D3D11_TILED_RESOURCES_NOT_SUPPORTED; + options->MinMaxFiltering = FALSE; + options->ClearViewAlsoSupportsDepthOnlyFormats = FALSE; + options->MapOnDefaultBuffers = FALSE; + return S_OK; + } + + case D3D11_FEATURE_D3D11_OPTIONS3: + { + D3D11_FEATURE_DATA_D3D11_OPTIONS3 *options = feature_support_data; + if (feature_support_data_size != sizeof(*options)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to get device caps, hr %#x.\n", hr); + return hr; + } + + options->VPAndRTArrayIndexFromAnyShaderFeedingRasterizer + = wined3d_caps.viewport_array_index_any_shader; + return S_OK; + } + + case D3D11_FEATURE_ARCHITECTURE_INFO: + { + D3D11_FEATURE_DATA_ARCHITECTURE_INFO *options = feature_support_data; + if (feature_support_data_size != sizeof(*options)) + { + WARN("Invalid data size.\n"); + return E_INVALIDARG; + } + + FIXME("Returning fake data architecture info.\n"); + options->TileBasedDeferredRenderer = FALSE; + return S_OK; + } + + default: + FIXME("Unhandled feature %#x.\n", feature); + return E_NOTIMPL; + } +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_GetPrivateData(ID3D11Device2 *iface, REFGUID guid, + UINT *data_size, void *data) +{ + IDXGIDevice *dxgi_device; + HRESULT hr; + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + if (FAILED(hr = ID3D11Device2_QueryInterface(iface, &IID_IDXGIDevice, (void **)&dxgi_device))) + return hr; + hr = IDXGIDevice_GetPrivateData(dxgi_device, guid, data_size, data); + IDXGIDevice_Release(dxgi_device); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_SetPrivateData(ID3D11Device2 *iface, REFGUID guid, + UINT data_size, const void *data) +{ + IDXGIDevice *dxgi_device; + HRESULT hr; + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + if (FAILED(hr = ID3D11Device2_QueryInterface(iface, &IID_IDXGIDevice, (void **)&dxgi_device))) + return hr; + hr = IDXGIDevice_SetPrivateData(dxgi_device, guid, data_size, data); + IDXGIDevice_Release(dxgi_device); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_SetPrivateDataInterface(ID3D11Device2 *iface, REFGUID guid, + const IUnknown *data) +{ + IDXGIDevice *dxgi_device; + HRESULT hr; + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + if (FAILED(hr = ID3D11Device2_QueryInterface(iface, &IID_IDXGIDevice, (void **)&dxgi_device))) + return hr; + hr = IDXGIDevice_SetPrivateDataInterface(dxgi_device, guid, data); + IDXGIDevice_Release(dxgi_device); + + return hr; +} + +static D3D_FEATURE_LEVEL STDMETHODCALLTYPE d3d11_device_GetFeatureLevel(ID3D11Device2 *iface) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + + TRACE("iface %p.\n", iface); + + return device->feature_level; +} + +static UINT STDMETHODCALLTYPE d3d11_device_GetCreationFlags(ID3D11Device2 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_GetDeviceRemovedReason(ID3D11Device2 *iface) +{ + WARN("iface %p stub!\n", iface); + + return S_OK; +} + +static void STDMETHODCALLTYPE d3d11_device_GetImmediateContext(ID3D11Device2 *iface, + ID3D11DeviceContext **immediate_context) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + + TRACE("iface %p, immediate_context %p.\n", iface, immediate_context); + + *immediate_context = (ID3D11DeviceContext *)&device->immediate_context.ID3D11DeviceContext1_iface; + ID3D11DeviceContext_AddRef(*immediate_context); +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_SetExceptionMode(ID3D11Device2 *iface, UINT flags) +{ + FIXME("iface %p, flags %#x stub!\n", iface, flags); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE d3d11_device_GetExceptionMode(ID3D11Device2 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d3d11_device_GetImmediateContext1(ID3D11Device2 *iface, + ID3D11DeviceContext1 **immediate_context) +{ + struct d3d_device *device = impl_from_ID3D11Device2(iface); + + TRACE("iface %p, immediate_context %p.\n", iface, immediate_context); + + *immediate_context = &device->immediate_context.ID3D11DeviceContext1_iface; + ID3D11DeviceContext1_AddRef(*immediate_context); +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeferredContext1(ID3D11Device2 *iface, UINT flags, + ID3D11DeviceContext1 **context) +{ + FIXME("iface %p, flags %#x, context %p stub!\n", iface, flags, context); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState1(ID3D11Device2 *iface, + const D3D11_BLEND_DESC1 *desc, ID3D11BlendState1 **state) +{ + FIXME("iface %p, desc %p, state %p stub!\n", iface, desc, state); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateRasterizerState1(ID3D11Device2 *iface, + const D3D11_RASTERIZER_DESC1 *desc, ID3D11RasterizerState1 **state) +{ + FIXME("iface %p, desc %p, state %p stub!\n", iface, desc, state); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeviceContextState(ID3D11Device2 *iface, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT feature_levels_count, UINT sdk_version, + REFIID emulated_interface, D3D_FEATURE_LEVEL *chosen_feature_level, ID3DDeviceContextState **state) +{ + FIXME("iface %p, flags %#x, feature_levels %p, feature_level_count %u, sdk_version %u, " + "emulated_interface %s, chosen_feature_level %p, state %p stub!\n", iface, flags, feature_levels, + feature_levels_count, sdk_version, debugstr_guid(emulated_interface), chosen_feature_level, state); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_OpenSharedResource1(ID3D11Device2 *iface, HANDLE handle, + REFIID iid, void **resource) +{ + FIXME("iface %p, handle %p, iid %s, resource %p stub!\n", iface, handle, debugstr_guid(iid), resource); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_OpenSharedResourceByName(ID3D11Device2 *iface, const WCHAR *name, + DWORD access, REFIID iid, void **resource) +{ + FIXME("iface %p, name %s, access %#x, iid %s, resource %p stub!\n", iface, debugstr_w(name), access, + debugstr_guid(iid), resource); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d11_device_GetImmediateContext2(ID3D11Device2 *iface, + ID3D11DeviceContext2 **context) +{ + FIXME("iface %p, context %p stub!\n", iface, context); +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeferredContext2(ID3D11Device2 *iface, + UINT flags, ID3D11DeviceContext2 **context) +{ + FIXME("iface %p, flags %#x, context %p stub!\n", iface, flags, context); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d11_device_GetResourceTiling(ID3D11Device2 *iface, + ID3D11Resource *resource, UINT *tile_count, D3D11_PACKED_MIP_DESC *mip_desc, + D3D11_TILE_SHAPE *tile_shape, UINT *subresource_tiling_count, UINT first_subresource_tiling, + D3D11_SUBRESOURCE_TILING *subresource_tiling) +{ + FIXME("iface %p, resource %p, tile_count %p, mip_desc %p, tile_shape %p, " + "subresource_tiling_count %p, first_subresource_tiling %u, subresource_tiling %p stub!\n", + iface, resource, tile_count, mip_desc, tile_shape, + subresource_tiling_count, first_subresource_tiling, subresource_tiling); +} + +static HRESULT STDMETHODCALLTYPE d3d11_device_CheckMultisampleQualityLevels1(ID3D11Device2 *iface, + DXGI_FORMAT format, UINT sample_count, UINT flags, UINT *quality_level_count) +{ + FIXME("iface %p, format %#x, sample_count %u, flags %#x, quality_level_count %p stub!\n", + iface, format, sample_count, flags, quality_level_count); + + return E_NOTIMPL; +} + +static const struct ID3D11Device2Vtbl d3d11_device_vtbl = +{ + /* IUnknown methods */ + d3d11_device_QueryInterface, + d3d11_device_AddRef, + d3d11_device_Release, + /* ID3D11Device methods */ + d3d11_device_CreateBuffer, + d3d11_device_CreateTexture1D, + d3d11_device_CreateTexture2D, + d3d11_device_CreateTexture3D, + d3d11_device_CreateShaderResourceView, + d3d11_device_CreateUnorderedAccessView, + d3d11_device_CreateRenderTargetView, + d3d11_device_CreateDepthStencilView, + d3d11_device_CreateInputLayout, + d3d11_device_CreateVertexShader, + d3d11_device_CreateGeometryShader, + d3d11_device_CreateGeometryShaderWithStreamOutput, + d3d11_device_CreatePixelShader, + d3d11_device_CreateHullShader, + d3d11_device_CreateDomainShader, + d3d11_device_CreateComputeShader, + d3d11_device_CreateClassLinkage, + d3d11_device_CreateBlendState, + d3d11_device_CreateDepthStencilState, + d3d11_device_CreateRasterizerState, + d3d11_device_CreateSamplerState, + d3d11_device_CreateQuery, + d3d11_device_CreatePredicate, + d3d11_device_CreateCounter, + d3d11_device_CreateDeferredContext, + d3d11_device_OpenSharedResource, + d3d11_device_CheckFormatSupport, + d3d11_device_CheckMultisampleQualityLevels, + d3d11_device_CheckCounterInfo, + d3d11_device_CheckCounter, + d3d11_device_CheckFeatureSupport, + d3d11_device_GetPrivateData, + d3d11_device_SetPrivateData, + d3d11_device_SetPrivateDataInterface, + d3d11_device_GetFeatureLevel, + d3d11_device_GetCreationFlags, + d3d11_device_GetDeviceRemovedReason, + d3d11_device_GetImmediateContext, + d3d11_device_SetExceptionMode, + d3d11_device_GetExceptionMode, + /* ID3D11Device1 methods */ + d3d11_device_GetImmediateContext1, + d3d11_device_CreateDeferredContext1, + d3d11_device_CreateBlendState1, + d3d11_device_CreateRasterizerState1, + d3d11_device_CreateDeviceContextState, + d3d11_device_OpenSharedResource1, + d3d11_device_OpenSharedResourceByName, + /* ID3D11Device2 methods */ + d3d11_device_GetImmediateContext2, + d3d11_device_CreateDeferredContext2, + d3d11_device_GetResourceTiling, + d3d11_device_CheckMultisampleQualityLevels1, +}; + +/* Inner IUnknown methods */ + +static inline struct d3d_device *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device, IUnknown_inner); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out) +{ + struct d3d_device *device = impl_from_IUnknown(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_ID3D11Device2) + || IsEqualGUID(riid, &IID_ID3D11Device1) + || IsEqualGUID(riid, &IID_ID3D11Device) + || IsEqualGUID(riid, &IID_IUnknown)) + { + *out = &device->ID3D11Device2_iface; + } + else if (IsEqualGUID(riid, &IID_ID3D10Device1) + || IsEqualGUID(riid, &IID_ID3D10Device)) + { + *out = &device->ID3D10Device1_iface; + } + else if (IsEqualGUID(riid, &IID_ID3D10Multithread)) + { + *out = &device->ID3D10Multithread_iface; + } + else if (IsEqualGUID(riid, &IID_IWineDXGIDeviceParent)) + { + *out = &device->IWineDXGIDeviceParent_iface; + } + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE d3d_device_inner_AddRef(IUnknown *iface) +{ + struct d3d_device *device = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&device->refcount); + + TRACE("%p increasing refcount to %u.\n", device, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d_device_inner_Release(IUnknown *iface) +{ + struct d3d_device *device = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&device->refcount); + + TRACE("%p decreasing refcount to %u.\n", device, refcount); + + if (!refcount) + { + d3d11_immediate_context_destroy(&device->immediate_context); + if (device->wined3d_device) + { + wined3d_mutex_lock(); + wined3d_device_decref(device->wined3d_device); + wined3d_mutex_unlock(); + } + wine_rb_destroy(&device->sampler_states, NULL, NULL); + wine_rb_destroy(&device->rasterizer_states, NULL, NULL); + wine_rb_destroy(&device->depthstencil_states, NULL, NULL); + wine_rb_destroy(&device->blend_states, NULL, NULL); + } + + return refcount; +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_device_QueryInterface(ID3D10Device1 *iface, REFIID iid, + void **out) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + return IUnknown_QueryInterface(device->outer_unk, iid, out); +} + +static ULONG STDMETHODCALLTYPE d3d10_device_AddRef(ID3D10Device1 *iface) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + return IUnknown_AddRef(device->outer_unk); +} + +static ULONG STDMETHODCALLTYPE d3d10_device_Release(ID3D10Device1 *iface) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + return IUnknown_Release(device->outer_unk); +} + +/* ID3D10Device methods */ + +static void d3d10_device_get_constant_buffers(ID3D10Device1 *iface, + enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D10Buffer **buffers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct wined3d_buffer *wined3d_buffer; + struct d3d_buffer *buffer_impl; + + if (!(wined3d_buffer = wined3d_device_get_constant_buffer(device->wined3d_device, + type, start_slot + i))) + { + buffers[i] = NULL; + continue; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffers[i] = &buffer_impl->ID3D10Buffer_iface; + ID3D10Buffer_AddRef(buffers[i]); + } + wined3d_mutex_unlock(); +} + +static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, + enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); + + wined3d_device_set_constant_buffer(device->wined3d_device, type, start_slot + i, + buffer ? buffer->wined3d_buffer : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSSetConstantBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d10_device_set_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d10_device_PSSetShaderResources(ID3D10Device1 *iface, + UINT start_slot, UINT view_count, ID3D10ShaderResourceView *const *views) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); + + wined3d_device_set_ps_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_PSSetShader(ID3D10Device1 *iface, + ID3D10PixelShader *shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_pixel_shader *ps = unsafe_impl_from_ID3D10PixelShader(shader); + + TRACE("iface %p, shader %p\n", iface, shader); + + wined3d_mutex_lock(); + wined3d_device_set_pixel_shader(device->wined3d_device, ps ? ps->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_PSSetSamplers(ID3D10Device1 *iface, + UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); + + wined3d_device_set_ps_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSSetShader(ID3D10Device1 *iface, + ID3D10VertexShader *shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_vertex_shader *vs = unsafe_impl_from_ID3D10VertexShader(shader); + + TRACE("iface %p, shader %p\n", iface, shader); + + wined3d_mutex_lock(); + wined3d_device_set_vertex_shader(device->wined3d_device, vs ? vs->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_DrawIndexed(ID3D10Device1 *iface, UINT index_count, + UINT start_index_location, INT base_vertex_location) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, index_count %u, start_index_location %u, base_vertex_location %d.\n", + iface, index_count, start_index_location, base_vertex_location); + + wined3d_mutex_lock(); + wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); + wined3d_device_draw_indexed_primitive(device->wined3d_device, start_index_location, index_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_Draw(ID3D10Device1 *iface, UINT vertex_count, + UINT start_vertex_location) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, vertex_count %u, start_vertex_location %u\n", + iface, vertex_count, start_vertex_location); + + wined3d_mutex_lock(); + wined3d_device_draw_primitive(device->wined3d_device, start_vertex_location, vertex_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_PSSetConstantBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d10_device_set_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d10_device_IASetInputLayout(ID3D10Device1 *iface, + ID3D10InputLayout *input_layout) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_input_layout *layout = unsafe_impl_from_ID3D10InputLayout(input_layout); + + TRACE("iface %p, input_layout %p\n", iface, input_layout); + + wined3d_mutex_lock(); + wined3d_device_set_vertex_declaration(device->wined3d_device, + layout ? layout->wined3d_decl : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_IASetVertexBuffers(ID3D10Device1 *iface, UINT start_slot, + UINT buffer_count, ID3D10Buffer *const *buffers, const UINT *strides, const UINT *offsets) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p\n", + iface, start_slot, buffer_count, buffers, strides, offsets); + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); + + wined3d_device_set_stream_source(device->wined3d_device, start_slot + i, + buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_IASetIndexBuffer(ID3D10Device1 *iface, + ID3D10Buffer *buffer, DXGI_FORMAT format, UINT offset) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_buffer *buffer_impl = unsafe_impl_from_ID3D10Buffer(buffer); + + TRACE("iface %p, buffer %p, format %s, offset %u.\n", + iface, buffer, debug_dxgi_format(format), offset); + + wined3d_mutex_lock(); + wined3d_device_set_index_buffer(device->wined3d_device, + buffer_impl ? buffer_impl->wined3d_buffer : NULL, + wined3dformat_from_dxgi_format(format), offset); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_DrawIndexedInstanced(ID3D10Device1 *iface, + UINT instance_index_count, UINT instance_count, UINT start_index_location, + INT base_vertex_location, UINT start_instance_location) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, instance_index_count %u, instance_count %u, start_index_location %u, " + "base_vertex_location %d, start_instance_location %u.\n", + iface, instance_index_count, instance_count, start_index_location, + base_vertex_location, start_instance_location); + + wined3d_mutex_lock(); + wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); + wined3d_device_draw_indexed_primitive_instanced(device->wined3d_device, start_index_location, + instance_index_count, start_instance_location, instance_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_DrawInstanced(ID3D10Device1 *iface, + UINT instance_vertex_count, UINT instance_count, + UINT start_vertex_location, UINT start_instance_location) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, instance_vertex_count %u, instance_count %u, start_vertex_location %u, " + "start_instance_location %u.\n", iface, instance_vertex_count, instance_count, + start_vertex_location, start_instance_location); + + wined3d_mutex_lock(); + wined3d_device_draw_primitive_instanced(device->wined3d_device, start_vertex_location, + instance_vertex_count, start_instance_location, instance_count); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_GSSetConstantBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d10_device_set_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, + buffer_count, buffers); +} + +static void STDMETHODCALLTYPE d3d10_device_GSSetShader(ID3D10Device1 *iface, ID3D10GeometryShader *shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_geometry_shader *gs = unsafe_impl_from_ID3D10GeometryShader(shader); + + TRACE("iface %p, shader %p.\n", iface, shader); + + wined3d_mutex_lock(); + wined3d_device_set_geometry_shader(device->wined3d_device, gs ? gs->wined3d_shader : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_IASetPrimitiveTopology(ID3D10Device1 *iface, + D3D10_PRIMITIVE_TOPOLOGY topology) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, topology %s.\n", iface, debug_d3d10_primitive_topology(topology)); + + wined3d_mutex_lock(); + wined3d_device_set_primitive_type(device->wined3d_device, (enum wined3d_primitive_type)topology, 0); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSSetShaderResources(ID3D10Device1 *iface, + UINT start_slot, UINT view_count, ID3D10ShaderResourceView *const *views) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); + + wined3d_device_set_vs_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSSetSamplers(ID3D10Device1 *iface, + UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); + + wined3d_device_set_vs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_SetPredication(ID3D10Device1 *iface, ID3D10Predicate *predicate, BOOL value) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_query *query; + + TRACE("iface %p, predicate %p, value %#x.\n", iface, predicate, value); + + query = unsafe_impl_from_ID3D10Query((ID3D10Query *)predicate); + wined3d_mutex_lock(); + wined3d_device_set_predication(device->wined3d_device, query ? query->wined3d_query : NULL, value); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_GSSetShaderResources(ID3D10Device1 *iface, + UINT start_slot, UINT view_count, ID3D10ShaderResourceView *const *views) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); + + wined3d_device_set_gs_resource_view(device->wined3d_device, start_slot + i, + view ? view->wined3d_view : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_GSSetSamplers(ID3D10Device1 *iface, + UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); + + wined3d_device_set_gs_sampler(device->wined3d_device, start_slot + i, + sampler ? sampler->wined3d_sampler : NULL); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_OMSetRenderTargets(ID3D10Device1 *iface, + UINT render_target_view_count, ID3D10RenderTargetView *const *render_target_views, + ID3D10DepthStencilView *depth_stencil_view) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_depthstencil_view *dsv; + unsigned int i; + + TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", + iface, render_target_view_count, render_target_views, depth_stencil_view); + + wined3d_mutex_lock(); + for (i = 0; i < render_target_view_count; ++i) + { + struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D10RenderTargetView(render_target_views[i]); + + wined3d_device_set_rendertarget_view(device->wined3d_device, i, + rtv ? rtv->wined3d_view : NULL, FALSE); + } + for (; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + wined3d_device_set_rendertarget_view(device->wined3d_device, i, NULL, FALSE); + } + + dsv = unsafe_impl_from_ID3D10DepthStencilView(depth_stencil_view); + wined3d_device_set_depth_stencil_view(device->wined3d_device, + dsv ? dsv->wined3d_view : NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_OMSetBlendState(ID3D10Device1 *iface, + ID3D10BlendState *blend_state, const float blend_factor[4], UINT sample_mask) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_blend_state *blend_state_object; + + TRACE("iface %p, blend_state %p, blend_factor %s, sample_mask 0x%08x.\n", + iface, blend_state, debug_float4(blend_factor), sample_mask); + + blend_state_object = unsafe_impl_from_ID3D10BlendState(blend_state); + d3d11_immediate_context_OMSetBlendState(&device->immediate_context.ID3D11DeviceContext1_iface, + blend_state_object ? &blend_state_object->ID3D11BlendState_iface : NULL, blend_factor, sample_mask); +} + +static void STDMETHODCALLTYPE d3d10_device_OMSetDepthStencilState(ID3D10Device1 *iface, + ID3D10DepthStencilState *depth_stencil_state, UINT stencil_ref) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_depthstencil_state *ds_state_object; + + TRACE("iface %p, depth_stencil_state %p, stencil_ref %u.\n", + iface, depth_stencil_state, stencil_ref); + + ds_state_object = unsafe_impl_from_ID3D10DepthStencilState(depth_stencil_state); + d3d11_immediate_context_OMSetDepthStencilState(&device->immediate_context.ID3D11DeviceContext1_iface, + ds_state_object ? &ds_state_object->ID3D11DepthStencilState_iface : NULL, stencil_ref); +} + +static void STDMETHODCALLTYPE d3d10_device_SOSetTargets(ID3D10Device1 *iface, + UINT target_count, ID3D10Buffer *const *targets, const UINT *offsets) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int count, i; + + TRACE("iface %p, target_count %u, targets %p, offsets %p.\n", iface, target_count, targets, offsets); + + count = min(target_count, D3D10_SO_BUFFER_SLOT_COUNT); + wined3d_mutex_lock(); + for (i = 0; i < count; ++i) + { + struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(targets[i]); + + wined3d_device_set_stream_output(device->wined3d_device, i, + buffer ? buffer->wined3d_buffer : NULL, offsets[i]); + } + + for (i = count; i < D3D10_SO_BUFFER_SLOT_COUNT; ++i) + { + wined3d_device_set_stream_output(device->wined3d_device, i, NULL, 0); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_DrawAuto(ID3D10Device1 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static void STDMETHODCALLTYPE d3d10_device_RSSetState(ID3D10Device1 *iface, ID3D10RasterizerState *rasterizer_state) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_rasterizer_state *rasterizer_state_object; + + TRACE("iface %p, rasterizer_state %p.\n", iface, rasterizer_state); + + rasterizer_state_object = unsafe_impl_from_ID3D10RasterizerState(rasterizer_state); + d3d11_immediate_context_RSSetState(&device->immediate_context.ID3D11DeviceContext1_iface, + rasterizer_state_object ? &rasterizer_state_object->ID3D11RasterizerState_iface : NULL); +} + +static void STDMETHODCALLTYPE d3d10_device_RSSetViewports(ID3D10Device1 *iface, + UINT viewport_count, const D3D10_VIEWPORT *viewports) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct wined3d_viewport wined3d_vp[WINED3D_MAX_VIEWPORTS]; + unsigned int i; + + TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports); + + if (viewport_count > ARRAY_SIZE(wined3d_vp)) + return; + + for (i = 0; i < viewport_count; ++i) + { + wined3d_vp[i].x = viewports[i].TopLeftX; + wined3d_vp[i].y = viewports[i].TopLeftY; + wined3d_vp[i].width = viewports[i].Width; + wined3d_vp[i].height = viewports[i].Height; + wined3d_vp[i].min_z = viewports[i].MinDepth; + wined3d_vp[i].max_z = viewports[i].MaxDepth; + } + + wined3d_mutex_lock(); + wined3d_device_set_viewports(device->wined3d_device, viewport_count, wined3d_vp); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_RSSetScissorRects(ID3D10Device1 *iface, + UINT rect_count, const D3D10_RECT *rects) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, rect_count %u, rects %p.\n", iface, rect_count, rects); + + if (rect_count > WINED3D_MAX_VIEWPORTS) + return; + + wined3d_mutex_lock(); + wined3d_device_set_scissor_rects(device->wined3d_device, rect_count, rects); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_CopySubresourceRegion(ID3D10Device1 *iface, + ID3D10Resource *dst_resource, UINT dst_subresource_idx, UINT dst_x, UINT dst_y, UINT dst_z, + ID3D10Resource *src_resource, UINT src_subresource_idx, const D3D10_BOX *src_box) +{ + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct wined3d_box wined3d_src_box; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, dst_x %u, dst_y %u, dst_z %u, " + "src_resource %p, src_subresource_idx %u, src_box %p.\n", + iface, dst_resource, dst_subresource_idx, dst_x, dst_y, dst_z, + src_resource, src_subresource_idx, src_box); + + if (src_box) + wined3d_box_set(&wined3d_src_box, src_box->left, src_box->top, + src_box->right, src_box->bottom, src_box->front, src_box->back); + + wined3d_dst_resource = wined3d_resource_from_d3d10_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d10_resource(src_resource); + wined3d_mutex_lock(); + wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_dst_resource, dst_subresource_idx, + dst_x, dst_y, dst_z, wined3d_src_resource, src_subresource_idx, src_box ? &wined3d_src_box : NULL, 0); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_CopyResource(ID3D10Device1 *iface, + ID3D10Resource *dst_resource, ID3D10Resource *src_resource) +{ + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, dst_resource %p, src_resource %p.\n", iface, dst_resource, src_resource); + + wined3d_dst_resource = wined3d_resource_from_d3d10_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d10_resource(src_resource); + wined3d_mutex_lock(); + wined3d_device_copy_resource(device->wined3d_device, wined3d_dst_resource, wined3d_src_resource); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_UpdateSubresource(ID3D10Device1 *iface, + ID3D10Resource *resource, UINT subresource_idx, const D3D10_BOX *box, + const void *data, UINT row_pitch, UINT depth_pitch) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + ID3D11Resource *d3d11_resource; + + TRACE("iface %p, resource %p, subresource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u.\n", + iface, resource, subresource_idx, box, data, row_pitch, depth_pitch); + + ID3D10Resource_QueryInterface(resource, &IID_ID3D11Resource, (void **)&d3d11_resource); + d3d11_immediate_context_UpdateSubresource(&device->immediate_context.ID3D11DeviceContext1_iface, + d3d11_resource, subresource_idx, (const D3D11_BOX *)box, data, row_pitch, depth_pitch); + ID3D11Resource_Release(d3d11_resource); +} + +static void STDMETHODCALLTYPE d3d10_device_ClearRenderTargetView(ID3D10Device1 *iface, + ID3D10RenderTargetView *render_target_view, const float color_rgba[4]) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_rendertarget_view *view = unsafe_impl_from_ID3D10RenderTargetView(render_target_view); + const struct wined3d_color color = {color_rgba[0], color_rgba[1], color_rgba[2], color_rgba[3]}; + HRESULT hr; + + TRACE("iface %p, render_target_view %p, color_rgba %s.\n", + iface, render_target_view, debug_float4(color_rgba)); + + if (!view) + return; + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, view->wined3d_view, NULL, + WINED3DCLEAR_TARGET, &color, 0.0f, 0))) + ERR("Failed to clear view, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_ClearDepthStencilView(ID3D10Device1 *iface, + ID3D10DepthStencilView *depth_stencil_view, UINT flags, FLOAT depth, UINT8 stencil) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_depthstencil_view *view = unsafe_impl_from_ID3D10DepthStencilView(depth_stencil_view); + DWORD wined3d_flags; + HRESULT hr; + + TRACE("iface %p, depth_stencil_view %p, flags %#x, depth %.8e, stencil %u.\n", + iface, depth_stencil_view, flags, depth, stencil); + + if (!view) + return; + + wined3d_flags = wined3d_clear_flags_from_d3d11_clear_flags(flags); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, view->wined3d_view, NULL, + wined3d_flags, NULL, depth, stencil))) + ERR("Failed to clear view, hr %#x.\n", hr); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_GenerateMips(ID3D10Device1 *iface, + ID3D10ShaderResourceView *view) +{ + struct d3d_shader_resource_view *srv = unsafe_impl_from_ID3D10ShaderResourceView(view); + + TRACE("iface %p, view %p.\n", iface, view); + + wined3d_mutex_lock(); + wined3d_shader_resource_view_generate_mipmaps(srv->wined3d_view); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_ResolveSubresource(ID3D10Device1 *iface, + ID3D10Resource *dst_resource, UINT dst_subresource_idx, + ID3D10Resource *src_resource, UINT src_subresource_idx, DXGI_FORMAT format) +{ + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct d3d_device *device = impl_from_ID3D10Device(iface); + enum wined3d_format_id wined3d_format; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, " + "src_resource %p, src_subresource_idx %u, format %s.\n", + iface, dst_resource, dst_subresource_idx, + src_resource, src_subresource_idx, debug_dxgi_format(format)); + + wined3d_dst_resource = wined3d_resource_from_d3d10_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d10_resource(src_resource); + wined3d_format = wined3dformat_from_dxgi_format(format); + wined3d_mutex_lock(); + wined3d_device_resolve_sub_resource(device->wined3d_device, + wined3d_dst_resource, dst_subresource_idx, + wined3d_src_resource, src_subresource_idx, wined3d_format); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSGetConstantBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d10_device_get_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, buffer_count, + buffers); +} + +static void STDMETHODCALLTYPE d3d10_device_PSGetShaderResources(ID3D10Device1 *iface, + UINT start_slot, UINT view_count, ID3D10ShaderResourceView **views) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_ps_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + views[i] = (ID3D10ShaderResourceView *)&view_impl->ID3D10ShaderResourceView1_iface; + ID3D10ShaderResourceView_AddRef(views[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_PSGetShader(ID3D10Device1 *iface, ID3D10PixelShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_pixel_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p.\n", iface, shader); + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_pixel_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + *shader = &shader_impl->ID3D10PixelShader_iface; + ID3D10PixelShader_AddRef(*shader); +} + +static void STDMETHODCALLTYPE d3d10_device_PSGetSamplers(ID3D10Device1 *iface, + UINT start_slot, UINT sampler_count, ID3D10SamplerState **samplers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler_impl; + struct wined3d_sampler *wined3d_sampler; + + if (!(wined3d_sampler = wined3d_device_get_ps_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + samplers[i] = &sampler_impl->ID3D10SamplerState_iface; + ID3D10SamplerState_AddRef(samplers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSGetShader(ID3D10Device1 *iface, ID3D10VertexShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_vertex_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p.\n", iface, shader); + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_vertex_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + *shader = &shader_impl->ID3D10VertexShader_iface; + ID3D10VertexShader_AddRef(*shader); +} + +static void STDMETHODCALLTYPE d3d10_device_PSGetConstantBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d10_device_get_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, buffer_count, + buffers); +} + +static void STDMETHODCALLTYPE d3d10_device_IAGetInputLayout(ID3D10Device1 *iface, ID3D10InputLayout **input_layout) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct wined3d_vertex_declaration *wined3d_declaration; + struct d3d_input_layout *input_layout_impl; + + TRACE("iface %p, input_layout %p.\n", iface, input_layout); + + wined3d_mutex_lock(); + if (!(wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *input_layout = NULL; + return; + } + + input_layout_impl = wined3d_vertex_declaration_get_parent(wined3d_declaration); + wined3d_mutex_unlock(); + *input_layout = &input_layout_impl->ID3D10InputLayout_iface; + ID3D10InputLayout_AddRef(*input_layout); +} + +static void STDMETHODCALLTYPE d3d10_device_IAGetVertexBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer **buffers, UINT *strides, UINT *offsets) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p.\n", + iface, start_slot, buffer_count, buffers, strides, offsets); + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct wined3d_buffer *wined3d_buffer = NULL; + struct d3d_buffer *buffer_impl; + + if (FAILED(wined3d_device_get_stream_source(device->wined3d_device, start_slot + i, + &wined3d_buffer, &offsets[i], &strides[i]))) + ERR("Failed to get vertex buffer.\n"); + + if (!wined3d_buffer) + { + buffers[i] = NULL; + continue; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffers[i] = &buffer_impl->ID3D10Buffer_iface; + ID3D10Buffer_AddRef(buffers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_IAGetIndexBuffer(ID3D10Device1 *iface, + ID3D10Buffer **buffer, DXGI_FORMAT *format, UINT *offset) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + enum wined3d_format_id wined3d_format; + struct wined3d_buffer *wined3d_buffer; + struct d3d_buffer *buffer_impl; + + TRACE("iface %p, buffer %p, format %p, offset %p.\n", iface, buffer, format, offset); + + wined3d_mutex_lock(); + wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format, offset); + *format = dxgi_format_from_wined3dformat(wined3d_format); + if (!wined3d_buffer) + { + wined3d_mutex_unlock(); + *buffer = NULL; + return; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + wined3d_mutex_unlock(); + *buffer = &buffer_impl->ID3D10Buffer_iface; + ID3D10Buffer_AddRef(*buffer); +} + +static void STDMETHODCALLTYPE d3d10_device_GSGetConstantBuffers(ID3D10Device1 *iface, + UINT start_slot, UINT buffer_count, ID3D10Buffer **buffers) +{ + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p.\n", + iface, start_slot, buffer_count, buffers); + + d3d10_device_get_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, buffer_count, + buffers); +} + +static void STDMETHODCALLTYPE d3d10_device_GSGetShader(ID3D10Device1 *iface, ID3D10GeometryShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_geometry_shader *shader_impl; + struct wined3d_shader *wined3d_shader; + + TRACE("iface %p, shader %p.\n", iface, shader); + + wined3d_mutex_lock(); + if (!(wined3d_shader = wined3d_device_get_geometry_shader(device->wined3d_device))) + { + wined3d_mutex_unlock(); + *shader = NULL; + return; + } + + shader_impl = wined3d_shader_get_parent(wined3d_shader); + wined3d_mutex_unlock(); + *shader = &shader_impl->ID3D10GeometryShader_iface; + ID3D10GeometryShader_AddRef(*shader); +} + +static void STDMETHODCALLTYPE d3d10_device_IAGetPrimitiveTopology(ID3D10Device1 *iface, + D3D10_PRIMITIVE_TOPOLOGY *topology) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, topology %p.\n", iface, topology); + + wined3d_mutex_lock(); + wined3d_device_get_primitive_type(device->wined3d_device, (enum wined3d_primitive_type *)topology, NULL); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSGetShaderResources(ID3D10Device1 *iface, + UINT start_slot, UINT view_count, ID3D10ShaderResourceView **views) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_vs_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + views[i] = (ID3D10ShaderResourceView *)&view_impl->ID3D10ShaderResourceView1_iface; + ID3D10ShaderResourceView_AddRef(views[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_VSGetSamplers(ID3D10Device1 *iface, + UINT start_slot, UINT sampler_count, ID3D10SamplerState **samplers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler_impl; + struct wined3d_sampler *wined3d_sampler; + + if (!(wined3d_sampler = wined3d_device_get_vs_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + samplers[i] = &sampler_impl->ID3D10SamplerState_iface; + ID3D10SamplerState_AddRef(samplers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_GetPredication(ID3D10Device1 *iface, + ID3D10Predicate **predicate, BOOL *value) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct wined3d_query *wined3d_predicate; + struct d3d_query *predicate_impl; + + TRACE("iface %p, predicate %p, value %p.\n", iface, predicate, value); + + wined3d_mutex_lock(); + if (!(wined3d_predicate = wined3d_device_get_predication(device->wined3d_device, value))) + { + wined3d_mutex_unlock(); + *predicate = NULL; + return; + } + + predicate_impl = wined3d_query_get_parent(wined3d_predicate); + wined3d_mutex_unlock(); + *predicate = (ID3D10Predicate *)&predicate_impl->ID3D10Query_iface; + ID3D10Predicate_AddRef(*predicate); +} + +static void STDMETHODCALLTYPE d3d10_device_GSGetShaderResources(ID3D10Device1 *iface, + UINT start_slot, UINT view_count, ID3D10ShaderResourceView **views) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", + iface, start_slot, view_count, views); + + wined3d_mutex_lock(); + for (i = 0; i < view_count; ++i) + { + struct wined3d_shader_resource_view *wined3d_view; + struct d3d_shader_resource_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_gs_resource_view(device->wined3d_device, start_slot + i))) + { + views[i] = NULL; + continue; + } + + view_impl = wined3d_shader_resource_view_get_parent(wined3d_view); + views[i] = (ID3D10ShaderResourceView *)&view_impl->ID3D10ShaderResourceView1_iface; + ID3D10ShaderResourceView_AddRef(views[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_GSGetSamplers(ID3D10Device1 *iface, + UINT start_slot, UINT sampler_count, ID3D10SamplerState **samplers) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", + iface, start_slot, sampler_count, samplers); + + wined3d_mutex_lock(); + for (i = 0; i < sampler_count; ++i) + { + struct d3d_sampler_state *sampler_impl; + struct wined3d_sampler *wined3d_sampler; + + if (!(wined3d_sampler = wined3d_device_get_gs_sampler(device->wined3d_device, start_slot + i))) + { + samplers[i] = NULL; + continue; + } + + sampler_impl = wined3d_sampler_get_parent(wined3d_sampler); + samplers[i] = &sampler_impl->ID3D10SamplerState_iface; + ID3D10SamplerState_AddRef(samplers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_OMGetRenderTargets(ID3D10Device1 *iface, + UINT view_count, ID3D10RenderTargetView **render_target_views, ID3D10DepthStencilView **depth_stencil_view) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct wined3d_rendertarget_view *wined3d_view; + + TRACE("iface %p, view_count %u, render_target_views %p, depth_stencil_view %p.\n", + iface, view_count, render_target_views, depth_stencil_view); + + wined3d_mutex_lock(); + if (render_target_views) + { + struct d3d_rendertarget_view *view_impl; + unsigned int i; + + for (i = 0; i < view_count; ++i) + { + if (!(wined3d_view = wined3d_device_get_rendertarget_view(device->wined3d_device, i)) + || !(view_impl = wined3d_rendertarget_view_get_parent(wined3d_view))) + { + render_target_views[i] = NULL; + continue; + } + + render_target_views[i] = &view_impl->ID3D10RenderTargetView_iface; + ID3D10RenderTargetView_AddRef(render_target_views[i]); + } + } + + if (depth_stencil_view) + { + struct d3d_depthstencil_view *view_impl; + + if (!(wined3d_view = wined3d_device_get_depth_stencil_view(device->wined3d_device)) + || !(view_impl = wined3d_rendertarget_view_get_parent(wined3d_view))) + { + *depth_stencil_view = NULL; + } + else + { + *depth_stencil_view = &view_impl->ID3D10DepthStencilView_iface; + ID3D10DepthStencilView_AddRef(*depth_stencil_view); + } + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_OMGetBlendState(ID3D10Device1 *iface, + ID3D10BlendState **blend_state, FLOAT blend_factor[4], UINT *sample_mask) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + ID3D11BlendState *d3d11_blend_state; + + TRACE("iface %p, blend_state %p, blend_factor %p, sample_mask %p.\n", + iface, blend_state, blend_factor, sample_mask); + + d3d11_immediate_context_OMGetBlendState(&device->immediate_context.ID3D11DeviceContext1_iface, + &d3d11_blend_state, blend_factor, sample_mask); + + if (d3d11_blend_state) + *blend_state = (ID3D10BlendState *)&impl_from_ID3D11BlendState(d3d11_blend_state)->ID3D10BlendState1_iface; + else + *blend_state = NULL; +} + +static void STDMETHODCALLTYPE d3d10_device_OMGetDepthStencilState(ID3D10Device1 *iface, + ID3D10DepthStencilState **depth_stencil_state, UINT *stencil_ref) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + ID3D11DepthStencilState *d3d11_iface; + + TRACE("iface %p, depth_stencil_state %p, stencil_ref %p.\n", + iface, depth_stencil_state, stencil_ref); + + d3d11_immediate_context_OMGetDepthStencilState(&device->immediate_context.ID3D11DeviceContext1_iface, + &d3d11_iface, stencil_ref); + + if (d3d11_iface) + *depth_stencil_state = &impl_from_ID3D11DepthStencilState(d3d11_iface)->ID3D10DepthStencilState_iface; + else + *depth_stencil_state = NULL; +} + +static void STDMETHODCALLTYPE d3d10_device_SOGetTargets(ID3D10Device1 *iface, + UINT buffer_count, ID3D10Buffer **buffers, UINT *offsets) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + TRACE("iface %p, buffer_count %u, buffers %p, offsets %p.\n", + iface, buffer_count, buffers, offsets); + + wined3d_mutex_lock(); + for (i = 0; i < buffer_count; ++i) + { + struct wined3d_buffer *wined3d_buffer; + struct d3d_buffer *buffer_impl; + + if (!(wined3d_buffer = wined3d_device_get_stream_output(device->wined3d_device, i, &offsets[i]))) + { + buffers[i] = NULL; + continue; + } + + buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffers[i] = &buffer_impl->ID3D10Buffer_iface; + ID3D10Buffer_AddRef(buffers[i]); + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_RSGetState(ID3D10Device1 *iface, ID3D10RasterizerState **rasterizer_state) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_rasterizer_state *rasterizer_state_impl; + struct wined3d_rasterizer_state *wined3d_state; + + TRACE("iface %p, rasterizer_state %p.\n", iface, rasterizer_state); + + wined3d_mutex_lock(); + if ((wined3d_state = wined3d_device_get_rasterizer_state(device->wined3d_device))) + { + rasterizer_state_impl = wined3d_rasterizer_state_get_parent(wined3d_state); + ID3D10RasterizerState_AddRef(*rasterizer_state = &rasterizer_state_impl->ID3D10RasterizerState_iface); + } + else + { + *rasterizer_state = NULL; + } + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_device_RSGetViewports(ID3D10Device1 *iface, + UINT *viewport_count, D3D10_VIEWPORT *viewports) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct wined3d_viewport wined3d_vp[WINED3D_MAX_VIEWPORTS]; + unsigned int actual_count = ARRAY_SIZE(wined3d_vp), i; + + TRACE("iface %p, viewport_count %p, viewports %p.\n", iface, viewport_count, viewports); + + if (!viewport_count) + return; + + wined3d_mutex_lock(); + wined3d_device_get_viewports(device->wined3d_device, &actual_count, viewports ? wined3d_vp : NULL); + wined3d_mutex_unlock(); + + if (!viewports) + { + *viewport_count = actual_count; + return; + } + + if (*viewport_count > actual_count) + memset(&viewports[actual_count], 0, (*viewport_count - actual_count) * sizeof(*viewports)); + + *viewport_count = min(actual_count, *viewport_count); + for (i = 0; i < *viewport_count; ++i) + { + viewports[i].TopLeftX = wined3d_vp[i].x; + viewports[i].TopLeftY = wined3d_vp[i].y; + viewports[i].Width = wined3d_vp[i].width; + viewports[i].Height = wined3d_vp[i].height; + viewports[i].MinDepth = wined3d_vp[i].min_z; + viewports[i].MaxDepth = wined3d_vp[i].max_z; + } +} + +static void STDMETHODCALLTYPE d3d10_device_RSGetScissorRects(ID3D10Device1 *iface, UINT *rect_count, D3D10_RECT *rects) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int actual_count; + + TRACE("iface %p, rect_count %p, rects %p.\n", iface, rect_count, rects); + + if (!rect_count) + return; + + actual_count = *rect_count; + + wined3d_mutex_lock(); + wined3d_device_get_scissor_rects(device->wined3d_device, &actual_count, rects); + wined3d_mutex_unlock(); + + if (!rects) + { + *rect_count = actual_count; + return; + } + + if (*rect_count > actual_count) + memset(&rects[actual_count], 0, (*rect_count - actual_count) * sizeof(*rects)); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_GetDeviceRemovedReason(ID3D10Device1 *iface) +{ + TRACE("iface %p.\n", iface); + + /* In the current implementation the device is never removed, so we can + * just return S_OK here. */ + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_SetExceptionMode(ID3D10Device1 *iface, UINT flags) +{ + FIXME("iface %p, flags %#x stub!\n", iface, flags); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE d3d10_device_GetExceptionMode(ID3D10Device1 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_GetPrivateData(ID3D10Device1 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_device_GetPrivateData(&device->ID3D11Device2_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_SetPrivateData(ID3D10Device1 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_device_SetPrivateData(&device->ID3D11Device2_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_SetPrivateDataInterface(ID3D10Device1 *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d11_device_SetPrivateDataInterface(&device->ID3D11Device2_iface, guid, data); +} + +static void STDMETHODCALLTYPE d3d10_device_ClearState(ID3D10Device1 *iface) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p.\n", iface); + + d3d11_immediate_context_ClearState(&device->immediate_context.ID3D11DeviceContext1_iface); +} + +static void STDMETHODCALLTYPE d3d10_device_Flush(ID3D10Device1 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBuffer(ID3D10Device1 *iface, + const D3D10_BUFFER_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, ID3D10Buffer **buffer) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + D3D11_BUFFER_DESC d3d11_desc; + struct d3d_buffer *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, buffer %p.\n", iface, desc, data, buffer); + + d3d11_desc.ByteWidth = desc->ByteWidth; + d3d11_desc.Usage = d3d11_usage_from_d3d10_usage(desc->Usage); + d3d11_desc.BindFlags = d3d11_bind_flags_from_d3d10_bind_flags(desc->BindFlags); + d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags); + d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags); + d3d11_desc.StructureByteStride = 0; + + if (FAILED(hr = d3d_buffer_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object))) + return hr; + + *buffer = &object->ID3D10Buffer_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture1D(ID3D10Device1 *iface, + const D3D10_TEXTURE1D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, ID3D10Texture1D **texture) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + D3D11_TEXTURE1D_DESC d3d11_desc; + struct d3d_texture1d *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + d3d11_desc.Width = desc->Width; + d3d11_desc.MipLevels = desc->MipLevels; + d3d11_desc.ArraySize = desc->ArraySize; + d3d11_desc.Format = desc->Format; + d3d11_desc.Usage = d3d11_usage_from_d3d10_usage(desc->Usage); + d3d11_desc.BindFlags = d3d11_bind_flags_from_d3d10_bind_flags(desc->BindFlags); + d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags); + d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags); + + if (FAILED(hr = d3d_texture1d_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object))) + return hr; + + *texture = &object->ID3D10Texture1D_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device1 *iface, + const D3D10_TEXTURE2D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, + ID3D10Texture2D **texture) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + D3D11_TEXTURE2D_DESC d3d11_desc; + struct d3d_texture2d *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + d3d11_desc.Width = desc->Width; + d3d11_desc.Height = desc->Height; + d3d11_desc.MipLevels = desc->MipLevels; + d3d11_desc.ArraySize = desc->ArraySize; + d3d11_desc.Format = desc->Format; + d3d11_desc.SampleDesc = desc->SampleDesc; + d3d11_desc.Usage = d3d11_usage_from_d3d10_usage(desc->Usage); + d3d11_desc.BindFlags = d3d11_bind_flags_from_d3d10_bind_flags(desc->BindFlags); + d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags); + d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags); + + if (FAILED(hr = d3d_texture2d_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object))) + return hr; + + *texture = &object->ID3D10Texture2D_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture3D(ID3D10Device1 *iface, + const D3D10_TEXTURE3D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, + ID3D10Texture3D **texture) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + D3D11_TEXTURE3D_DESC d3d11_desc; + struct d3d_texture3d *object; + HRESULT hr; + + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + d3d11_desc.Width = desc->Width; + d3d11_desc.Height = desc->Height; + d3d11_desc.Depth = desc->Depth; + d3d11_desc.MipLevels = desc->MipLevels; + d3d11_desc.Format = desc->Format; + d3d11_desc.Usage = d3d11_usage_from_d3d10_usage(desc->Usage); + d3d11_desc.BindFlags = d3d11_bind_flags_from_d3d10_bind_flags(desc->BindFlags); + d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags); + d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags); + + if (FAILED(hr = d3d_texture3d_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object))) + return hr; + + *texture = &object->ID3D10Texture3D_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateShaderResourceView1(ID3D10Device1 *iface, + ID3D10Resource *resource, const D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc, ID3D10ShaderResourceView1 **view) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_shader_resource_view *object; + ID3D11Resource *d3d11_resource; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (!resource) + return E_INVALIDARG; + + if (FAILED(hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D11Resource, (void **)&d3d11_resource))) + { + ERR("Resource does not implement ID3D11Resource.\n"); + return E_FAIL; + } + + hr = d3d_shader_resource_view_create(device, d3d11_resource, (const D3D11_SHADER_RESOURCE_VIEW_DESC *)desc, + &object); + ID3D11Resource_Release(d3d11_resource); + if (FAILED(hr)) + return hr; + + *view = &object->ID3D10ShaderResourceView1_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateShaderResourceView(ID3D10Device1 *iface, + ID3D10Resource *resource, const D3D10_SHADER_RESOURCE_VIEW_DESC *desc, ID3D10ShaderResourceView **view) +{ + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + return d3d10_device_CreateShaderResourceView1(iface, resource, + (const D3D10_SHADER_RESOURCE_VIEW_DESC1 *)desc, (ID3D10ShaderResourceView1 **)view); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateRenderTargetView(ID3D10Device1 *iface, + ID3D10Resource *resource, const D3D10_RENDER_TARGET_VIEW_DESC *desc, ID3D10RenderTargetView **view) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_rendertarget_view *object; + ID3D11Resource *d3d11_resource; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (!resource) + return E_INVALIDARG; + + if (FAILED(hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D11Resource, (void **)&d3d11_resource))) + { + ERR("Resource does not implement ID3D11Resource.\n"); + return E_FAIL; + } + + hr = d3d_rendertarget_view_create(device, d3d11_resource, (const D3D11_RENDER_TARGET_VIEW_DESC *)desc, &object); + ID3D11Resource_Release(d3d11_resource); + if (FAILED(hr)) + return hr; + + *view = &object->ID3D10RenderTargetView_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateDepthStencilView(ID3D10Device1 *iface, + ID3D10Resource *resource, const D3D10_DEPTH_STENCIL_VIEW_DESC *desc, ID3D10DepthStencilView **view) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + D3D11_DEPTH_STENCIL_VIEW_DESC d3d11_desc; + struct d3d_depthstencil_view *object; + ID3D11Resource *d3d11_resource; + HRESULT hr; + + TRACE("iface %p, resource %p, desc %p, view %p.\n", iface, resource, desc, view); + + if (desc) + { + d3d11_desc.Format = desc->Format; + d3d11_desc.ViewDimension = desc->ViewDimension; + d3d11_desc.Flags = 0; + memcpy(&d3d11_desc.u, &desc->u, sizeof(d3d11_desc.u)); + } + + if (FAILED(hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D11Resource, (void **)&d3d11_resource))) + { + ERR("Resource does not implement ID3D11Resource.\n"); + return E_FAIL; + } + + hr = d3d_depthstencil_view_create(device, d3d11_resource, desc ? &d3d11_desc : NULL, &object); + ID3D11Resource_Release(d3d11_resource); + if (FAILED(hr)) + return hr; + + *view = &object->ID3D10DepthStencilView_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateInputLayout(ID3D10Device1 *iface, + const D3D10_INPUT_ELEMENT_DESC *element_descs, UINT element_count, + const void *shader_byte_code, SIZE_T shader_byte_code_length, + ID3D10InputLayout **input_layout) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_input_layout *object; + HRESULT hr; + + TRACE("iface %p, element_descs %p, element_count %u, shader_byte_code %p, " + "shader_byte_code_length %lu, input_layout %p\n", + iface, element_descs, element_count, shader_byte_code, + shader_byte_code_length, input_layout); + + if (FAILED(hr = d3d_input_layout_create(device, (const D3D11_INPUT_ELEMENT_DESC *)element_descs, element_count, + shader_byte_code, shader_byte_code_length, &object))) + return hr; + + *input_layout = &object->ID3D10InputLayout_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateVertexShader(ID3D10Device1 *iface, + const void *byte_code, SIZE_T byte_code_length, ID3D10VertexShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_vertex_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p.\n", + iface, byte_code, byte_code_length, shader); + + if (FAILED(hr = d3d_vertex_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D10VertexShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShader(ID3D10Device1 *iface, + const void *byte_code, SIZE_T byte_code_length, ID3D10GeometryShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_geometry_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p.\n", + iface, byte_code, byte_code_length, shader); + + if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length, + NULL, 0, NULL, 0, 0, &object))) + return hr; + + *shader = &object->ID3D10GeometryShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShaderWithStreamOutput(ID3D10Device1 *iface, + const void *byte_code, SIZE_T byte_code_length, const D3D10_SO_DECLARATION_ENTRY *output_stream_decls, + UINT output_stream_decl_count, UINT output_stream_stride, ID3D10GeometryShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + D3D11_SO_DECLARATION_ENTRY *so_entries = NULL; + struct d3d_geometry_shader *object; + unsigned int i, stride_count = 1; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, output_stream_decls %p, " + "output_stream_decl_count %u, output_stream_stride %u, shader %p.\n", + iface, byte_code, byte_code_length, output_stream_decls, + output_stream_decl_count, output_stream_stride, shader); + + if (!output_stream_decl_count && output_stream_stride) + { + WARN("Stride must be 0 when declaration entry count is 0.\n"); + *shader = NULL; + return E_INVALIDARG; + } + + if (output_stream_decl_count + && !(so_entries = heap_calloc(output_stream_decl_count, sizeof(*so_entries)))) + { + ERR("Failed to allocate D3D11 SO declaration array memory.\n"); + *shader = NULL; + return E_OUTOFMEMORY; + } + + for (i = 0; i < output_stream_decl_count; ++i) + { + so_entries[i].Stream = 0; + so_entries[i].SemanticName = output_stream_decls[i].SemanticName; + so_entries[i].SemanticIndex = output_stream_decls[i].SemanticIndex; + so_entries[i].StartComponent = output_stream_decls[i].StartComponent; + so_entries[i].ComponentCount = output_stream_decls[i].ComponentCount; + so_entries[i].OutputSlot = output_stream_decls[i].OutputSlot; + + if (output_stream_decls[i].OutputSlot) + { + stride_count = 0; + if (output_stream_stride) + { + WARN("Stride must be 0 when multiple output slots are used.\n"); + heap_free(so_entries); + *shader = NULL; + return E_INVALIDARG; + } + } + } + + hr = d3d_geometry_shader_create(device, byte_code, byte_code_length, + so_entries, output_stream_decl_count, &output_stream_stride, stride_count, 0, &object); + heap_free(so_entries); + if (FAILED(hr)) + { + *shader = NULL; + return hr; + } + + *shader = &object->ID3D10GeometryShader_iface; + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device1 *iface, + const void *byte_code, SIZE_T byte_code_length, ID3D10PixelShader **shader) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_pixel_shader *object; + HRESULT hr; + + TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p.\n", + iface, byte_code, byte_code_length, shader); + + if (FAILED(hr = d3d_pixel_shader_create(device, byte_code, byte_code_length, &object))) + return hr; + + *shader = &object->ID3D10PixelShader_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBlendState1(ID3D10Device1 *iface, + const D3D10_BLEND_DESC1 *desc, ID3D10BlendState1 **blend_state) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_blend_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state); + + if (FAILED(hr = d3d_blend_state_create(device, (const D3D11_BLEND_DESC *)desc, &object))) + return hr; + + *blend_state = &object->ID3D10BlendState1_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBlendState(ID3D10Device1 *iface, + const D3D10_BLEND_DESC *desc, ID3D10BlendState **blend_state) +{ + D3D10_BLEND_DESC1 d3d10_1_desc; + unsigned int i; + + TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state); + + if (!desc) + return E_INVALIDARG; + + d3d10_1_desc.AlphaToCoverageEnable = desc->AlphaToCoverageEnable; + d3d10_1_desc.IndependentBlendEnable = FALSE; + for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT - 1; ++i) + { + if (desc->BlendEnable[i] != desc->BlendEnable[i + 1] + || desc->RenderTargetWriteMask[i] != desc->RenderTargetWriteMask[i + 1]) + d3d10_1_desc.IndependentBlendEnable = TRUE; + } + + for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + d3d10_1_desc.RenderTarget[i].BlendEnable = desc->BlendEnable[i]; + d3d10_1_desc.RenderTarget[i].SrcBlend = desc->SrcBlend; + d3d10_1_desc.RenderTarget[i].DestBlend = desc->DestBlend; + d3d10_1_desc.RenderTarget[i].BlendOp = desc->BlendOp; + d3d10_1_desc.RenderTarget[i].SrcBlendAlpha = desc->SrcBlendAlpha; + d3d10_1_desc.RenderTarget[i].DestBlendAlpha = desc->DestBlendAlpha; + d3d10_1_desc.RenderTarget[i].BlendOpAlpha = desc->BlendOpAlpha; + d3d10_1_desc.RenderTarget[i].RenderTargetWriteMask = desc->RenderTargetWriteMask[i]; + } + + return d3d10_device_CreateBlendState1(iface, &d3d10_1_desc, (ID3D10BlendState1 **)blend_state); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateDepthStencilState(ID3D10Device1 *iface, + const D3D10_DEPTH_STENCIL_DESC *desc, ID3D10DepthStencilState **depth_stencil_state) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_depthstencil_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, depth_stencil_state %p.\n", iface, desc, depth_stencil_state); + + if (FAILED(hr = d3d_depthstencil_state_create(device, (const D3D11_DEPTH_STENCIL_DESC *)desc, &object))) + return hr; + + *depth_stencil_state = &object->ID3D10DepthStencilState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateRasterizerState(ID3D10Device1 *iface, + const D3D10_RASTERIZER_DESC *desc, ID3D10RasterizerState **rasterizer_state) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_rasterizer_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, rasterizer_state %p.\n", iface, desc, rasterizer_state); + + if (FAILED(hr = d3d_rasterizer_state_create(device, (const D3D11_RASTERIZER_DESC *)desc, &object))) + return hr; + + *rasterizer_state = &object->ID3D10RasterizerState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateSamplerState(ID3D10Device1 *iface, + const D3D10_SAMPLER_DESC *desc, ID3D10SamplerState **sampler_state) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_sampler_state *object; + HRESULT hr; + + TRACE("iface %p, desc %p, sampler_state %p.\n", iface, desc, sampler_state); + + if (FAILED(hr = d3d_sampler_state_create(device, (const D3D11_SAMPLER_DESC *)desc, &object))) + return hr; + + *sampler_state = &object->ID3D10SamplerState_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateQuery(ID3D10Device1 *iface, + const D3D10_QUERY_DESC *desc, ID3D10Query **query) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_query *object; + HRESULT hr; + + TRACE("iface %p, desc %p, query %p.\n", iface, desc, query); + + if (FAILED(hr = d3d_query_create(device, (const D3D11_QUERY_DESC *)desc, FALSE, &object))) + return hr; + + if (query) + { + *query = &object->ID3D10Query_iface; + return S_OK; + } + + ID3D10Query_Release(&object->ID3D10Query_iface); + return S_FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePredicate(ID3D10Device1 *iface, + const D3D10_QUERY_DESC *desc, ID3D10Predicate **predicate) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + struct d3d_query *object; + HRESULT hr; + + TRACE("iface %p, desc %p, predicate %p.\n", iface, desc, predicate); + + if (FAILED(hr = d3d_query_create(device, (const D3D11_QUERY_DESC *)desc, TRUE, &object))) + return hr; + + if (predicate) + { + *predicate = (ID3D10Predicate *)&object->ID3D10Query_iface; + return S_OK; + } + + ID3D10Query_Release(&object->ID3D10Query_iface); + return S_FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CreateCounter(ID3D10Device1 *iface, + const D3D10_COUNTER_DESC *desc, ID3D10Counter **counter) +{ + FIXME("iface %p, desc %p, counter %p stub!\n", iface, desc, counter); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CheckFormatSupport(ID3D10Device1 *iface, + DXGI_FORMAT format, UINT *format_support) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, format %s, format_support %p.\n", + iface, debug_dxgi_format(format), format_support); + + return d3d11_device_CheckFormatSupport(&device->ID3D11Device2_iface, format, format_support); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CheckMultisampleQualityLevels(ID3D10Device1 *iface, + DXGI_FORMAT format, UINT sample_count, UINT *quality_level_count) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, format %s, sample_count %u, quality_level_count %p.\n", + iface, debug_dxgi_format(format), sample_count, quality_level_count); + + return d3d11_device_CheckMultisampleQualityLevels(&device->ID3D11Device2_iface, format, + sample_count, quality_level_count); +} + +static void STDMETHODCALLTYPE d3d10_device_CheckCounterInfo(ID3D10Device1 *iface, D3D10_COUNTER_INFO *counter_info) +{ + FIXME("iface %p, counter_info %p stub!\n", iface, counter_info); +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_CheckCounter(ID3D10Device1 *iface, + const D3D10_COUNTER_DESC *desc, D3D10_COUNTER_TYPE *type, UINT *active_counters, char *name, + UINT *name_length, char *units, UINT *units_length, char *description, UINT *description_length) +{ + FIXME("iface %p, desc %p, type %p, active_counters %p, name %p, name_length %p, " + "units %p, units_length %p, description %p, description_length %p stub!\n", + iface, desc, type, active_counters, name, name_length, + units, units_length, description, description_length); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE d3d10_device_GetCreationFlags(ID3D10Device1 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3d10_device_OpenSharedResource(ID3D10Device1 *iface, + HANDLE resource_handle, REFIID guid, void **resource) +{ + FIXME("iface %p, resource_handle %p, guid %s, resource %p stub!\n", + iface, resource_handle, debugstr_guid(guid), resource); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d10_device_SetTextFilterSize(ID3D10Device1 *iface, UINT width, UINT height) +{ + FIXME("iface %p, width %u, height %u stub!\n", iface, width, height); +} + +static void STDMETHODCALLTYPE d3d10_device_GetTextFilterSize(ID3D10Device1 *iface, UINT *width, UINT *height) +{ + FIXME("iface %p, width %p, height %p stub!\n", iface, width, height); +} + +static D3D10_FEATURE_LEVEL1 STDMETHODCALLTYPE d3d10_device_GetFeatureLevel(ID3D10Device1 *iface) +{ + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p.\n", iface); + + return device->feature_level; +} + +static const struct ID3D10Device1Vtbl d3d10_device1_vtbl = +{ + /* IUnknown methods */ + d3d10_device_QueryInterface, + d3d10_device_AddRef, + d3d10_device_Release, + /* ID3D10Device methods */ + d3d10_device_VSSetConstantBuffers, + d3d10_device_PSSetShaderResources, + d3d10_device_PSSetShader, + d3d10_device_PSSetSamplers, + d3d10_device_VSSetShader, + d3d10_device_DrawIndexed, + d3d10_device_Draw, + d3d10_device_PSSetConstantBuffers, + d3d10_device_IASetInputLayout, + d3d10_device_IASetVertexBuffers, + d3d10_device_IASetIndexBuffer, + d3d10_device_DrawIndexedInstanced, + d3d10_device_DrawInstanced, + d3d10_device_GSSetConstantBuffers, + d3d10_device_GSSetShader, + d3d10_device_IASetPrimitiveTopology, + d3d10_device_VSSetShaderResources, + d3d10_device_VSSetSamplers, + d3d10_device_SetPredication, + d3d10_device_GSSetShaderResources, + d3d10_device_GSSetSamplers, + d3d10_device_OMSetRenderTargets, + d3d10_device_OMSetBlendState, + d3d10_device_OMSetDepthStencilState, + d3d10_device_SOSetTargets, + d3d10_device_DrawAuto, + d3d10_device_RSSetState, + d3d10_device_RSSetViewports, + d3d10_device_RSSetScissorRects, + d3d10_device_CopySubresourceRegion, + d3d10_device_CopyResource, + d3d10_device_UpdateSubresource, + d3d10_device_ClearRenderTargetView, + d3d10_device_ClearDepthStencilView, + d3d10_device_GenerateMips, + d3d10_device_ResolveSubresource, + d3d10_device_VSGetConstantBuffers, + d3d10_device_PSGetShaderResources, + d3d10_device_PSGetShader, + d3d10_device_PSGetSamplers, + d3d10_device_VSGetShader, + d3d10_device_PSGetConstantBuffers, + d3d10_device_IAGetInputLayout, + d3d10_device_IAGetVertexBuffers, + d3d10_device_IAGetIndexBuffer, + d3d10_device_GSGetConstantBuffers, + d3d10_device_GSGetShader, + d3d10_device_IAGetPrimitiveTopology, + d3d10_device_VSGetShaderResources, + d3d10_device_VSGetSamplers, + d3d10_device_GetPredication, + d3d10_device_GSGetShaderResources, + d3d10_device_GSGetSamplers, + d3d10_device_OMGetRenderTargets, + d3d10_device_OMGetBlendState, + d3d10_device_OMGetDepthStencilState, + d3d10_device_SOGetTargets, + d3d10_device_RSGetState, + d3d10_device_RSGetViewports, + d3d10_device_RSGetScissorRects, + d3d10_device_GetDeviceRemovedReason, + d3d10_device_SetExceptionMode, + d3d10_device_GetExceptionMode, + d3d10_device_GetPrivateData, + d3d10_device_SetPrivateData, + d3d10_device_SetPrivateDataInterface, + d3d10_device_ClearState, + d3d10_device_Flush, + d3d10_device_CreateBuffer, + d3d10_device_CreateTexture1D, + d3d10_device_CreateTexture2D, + d3d10_device_CreateTexture3D, + d3d10_device_CreateShaderResourceView, + d3d10_device_CreateRenderTargetView, + d3d10_device_CreateDepthStencilView, + d3d10_device_CreateInputLayout, + d3d10_device_CreateVertexShader, + d3d10_device_CreateGeometryShader, + d3d10_device_CreateGeometryShaderWithStreamOutput, + d3d10_device_CreatePixelShader, + d3d10_device_CreateBlendState, + d3d10_device_CreateDepthStencilState, + d3d10_device_CreateRasterizerState, + d3d10_device_CreateSamplerState, + d3d10_device_CreateQuery, + d3d10_device_CreatePredicate, + d3d10_device_CreateCounter, + d3d10_device_CheckFormatSupport, + d3d10_device_CheckMultisampleQualityLevels, + d3d10_device_CheckCounterInfo, + d3d10_device_CheckCounter, + d3d10_device_GetCreationFlags, + d3d10_device_OpenSharedResource, + d3d10_device_SetTextFilterSize, + d3d10_device_GetTextFilterSize, + d3d10_device_CreateShaderResourceView1, + d3d10_device_CreateBlendState1, + d3d10_device_GetFeatureLevel, +}; + +static const struct IUnknownVtbl d3d_device_inner_unknown_vtbl = +{ + /* IUnknown methods */ + d3d_device_inner_QueryInterface, + d3d_device_inner_AddRef, + d3d_device_inner_Release, +}; + +/* ID3D10Multithread methods */ + +static inline struct d3d_device *impl_from_ID3D10Multithread(ID3D10Multithread *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device, ID3D10Multithread_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_multithread_QueryInterface(ID3D10Multithread *iface, REFIID iid, void **out) +{ + struct d3d_device *device = impl_from_ID3D10Multithread(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return IUnknown_QueryInterface(device->outer_unk, iid, out); +} + +static ULONG STDMETHODCALLTYPE d3d10_multithread_AddRef(ID3D10Multithread *iface) +{ + struct d3d_device *device = impl_from_ID3D10Multithread(iface); + + TRACE("iface %p.\n", iface); + + return IUnknown_AddRef(device->outer_unk); +} + +static ULONG STDMETHODCALLTYPE d3d10_multithread_Release(ID3D10Multithread *iface) +{ + struct d3d_device *device = impl_from_ID3D10Multithread(iface); + + TRACE("iface %p.\n", iface); + + return IUnknown_Release(device->outer_unk); +} + +static void STDMETHODCALLTYPE d3d10_multithread_Enter(ID3D10Multithread *iface) +{ + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); +} + +static void STDMETHODCALLTYPE d3d10_multithread_Leave(ID3D10Multithread *iface) +{ + TRACE("iface %p.\n", iface); + + wined3d_mutex_unlock(); +} + +static BOOL STDMETHODCALLTYPE d3d10_multithread_SetMultithreadProtected(ID3D10Multithread *iface, BOOL enable) +{ + FIXME("iface %p, enable %#x stub!\n", iface, enable); + + return TRUE; +} + +static BOOL STDMETHODCALLTYPE d3d10_multithread_GetMultithreadProtected(ID3D10Multithread *iface) +{ + FIXME("iface %p stub!\n", iface); + + return TRUE; +} + +static const struct ID3D10MultithreadVtbl d3d10_multithread_vtbl = +{ + d3d10_multithread_QueryInterface, + d3d10_multithread_AddRef, + d3d10_multithread_Release, + d3d10_multithread_Enter, + d3d10_multithread_Leave, + d3d10_multithread_SetMultithreadProtected, + d3d10_multithread_GetMultithreadProtected, +}; + +/* IWineDXGIDeviceParent IUnknown methods */ + +static inline struct d3d_device *device_from_dxgi_device_parent(IWineDXGIDeviceParent *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device, IWineDXGIDeviceParent_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_parent_QueryInterface(IWineDXGIDeviceParent *iface, + REFIID iid, void **out) +{ + struct d3d_device *device = device_from_dxgi_device_parent(iface); + return IUnknown_QueryInterface(device->outer_unk, iid, out); +} + +static ULONG STDMETHODCALLTYPE dxgi_device_parent_AddRef(IWineDXGIDeviceParent *iface) +{ + struct d3d_device *device = device_from_dxgi_device_parent(iface); + return IUnknown_AddRef(device->outer_unk); +} + +static ULONG STDMETHODCALLTYPE dxgi_device_parent_Release(IWineDXGIDeviceParent *iface) +{ + struct d3d_device *device = device_from_dxgi_device_parent(iface); + return IUnknown_Release(device->outer_unk); +} + +static struct wined3d_device_parent * STDMETHODCALLTYPE dxgi_device_parent_get_wined3d_device_parent( + IWineDXGIDeviceParent *iface) +{ + struct d3d_device *device = device_from_dxgi_device_parent(iface); + return &device->device_parent; +} + +static const struct IWineDXGIDeviceParentVtbl d3d_dxgi_device_parent_vtbl = +{ + /* IUnknown methods */ + dxgi_device_parent_QueryInterface, + dxgi_device_parent_AddRef, + dxgi_device_parent_Release, + /* IWineDXGIDeviceParent methods */ + dxgi_device_parent_get_wined3d_device_parent, +}; + +static inline struct d3d_device *device_from_wined3d_device_parent(struct wined3d_device_parent *device_parent) +{ + return CONTAINING_RECORD(device_parent, struct d3d_device, device_parent); +} + +static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent, + struct wined3d_device *wined3d_device) +{ + struct d3d_device *device = device_from_wined3d_device_parent(device_parent); + + TRACE("device_parent %p, wined3d_device %p.\n", device_parent, wined3d_device); + + wined3d_device_incref(wined3d_device); + device->wined3d_device = wined3d_device; + + device->feature_level = wined3d_device_get_feature_level(wined3d_device); + + set_default_depth_stencil_state(wined3d_device); +} + +static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent) +{ + TRACE("device_parent %p.\n", device_parent); +} + +static void CDECL device_parent_activate(struct wined3d_device_parent *device_parent, BOOL activate) +{ + TRACE("device_parent %p, activate %#x.\n", device_parent, activate); +} + +static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, + enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, + void **parent, const struct wined3d_parent_ops **parent_ops) +{ + TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); + + *parent = NULL; + *parent_ops = &d3d_null_wined3d_parent_ops; + + return S_OK; +} + +static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, + void *container_parent, const struct wined3d_resource_desc *wined3d_desc, DWORD texture_flags, + struct wined3d_texture **wined3d_texture) +{ + struct d3d_device *device = device_from_wined3d_device_parent(device_parent); + struct d3d_texture2d *texture; + ID3D11Texture2D *texture_iface; + D3D11_TEXTURE2D_DESC desc; + HRESULT hr; + + TRACE("device_parent %p, container_parent %p, wined3d_desc %p, texture_flags %#x, wined3d_texture %p.\n", + device_parent, container_parent, wined3d_desc, texture_flags, wined3d_texture); + + desc.Width = wined3d_desc->width; + desc.Height = wined3d_desc->height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = dxgi_format_from_wined3dformat(wined3d_desc->format); + desc.SampleDesc.Count = wined3d_desc->multisample_type ? wined3d_desc->multisample_type : 1; + desc.SampleDesc.Quality = wined3d_desc->multisample_quality; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = d3d11_bind_flags_from_wined3d(wined3d_desc->bind_flags); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + if (texture_flags & WINED3D_TEXTURE_CREATE_GET_DC) + { + desc.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE; + texture_flags &= ~WINED3D_TEXTURE_CREATE_GET_DC; + } + + if (texture_flags) + FIXME("Unhandled flags %#x.\n", texture_flags); + + if (FAILED(hr = d3d11_device_CreateTexture2D(&device->ID3D11Device2_iface, + &desc, NULL, &texture_iface))) + { + WARN("Failed to create 2D texture, hr %#x.\n", hr); + return hr; + } + + texture = impl_from_ID3D11Texture2D(texture_iface); + + *wined3d_texture = texture->wined3d_texture; + wined3d_texture_incref(*wined3d_texture); + ID3D11Texture2D_Release(&texture->ID3D11Texture2D_iface); + + return S_OK; +} + +static const struct wined3d_device_parent_ops d3d_wined3d_device_parent_ops = +{ + device_parent_wined3d_device_created, + device_parent_mode_changed, + device_parent_activate, + device_parent_texture_sub_resource_created, + device_parent_create_swapchain_texture, +}; + +static int d3d_sampler_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const D3D11_SAMPLER_DESC *ka = key; + const D3D11_SAMPLER_DESC *kb = &WINE_RB_ENTRY_VALUE(entry, const struct d3d_sampler_state, entry)->desc; + + return memcmp(ka, kb, sizeof(*ka)); +} + +static int d3d_blend_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const D3D11_BLEND_DESC *ka = key; + const D3D11_BLEND_DESC *kb = &WINE_RB_ENTRY_VALUE(entry, const struct d3d_blend_state, entry)->desc; + + return memcmp(ka, kb, sizeof(*ka)); +} + +static int d3d_depthstencil_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const D3D11_DEPTH_STENCIL_DESC *ka = key; + const D3D11_DEPTH_STENCIL_DESC *kb = &WINE_RB_ENTRY_VALUE(entry, + const struct d3d_depthstencil_state, entry)->desc; + + return memcmp(ka, kb, sizeof(*ka)); +} + +static int d3d_rasterizer_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const D3D11_RASTERIZER_DESC *ka = key; + const D3D11_RASTERIZER_DESC *kb = &WINE_RB_ENTRY_VALUE(entry, const struct d3d_rasterizer_state, entry)->desc; + + return memcmp(ka, kb, sizeof(*ka)); +} + +void d3d_device_init(struct d3d_device *device, void *outer_unknown) +{ + device->IUnknown_inner.lpVtbl = &d3d_device_inner_unknown_vtbl; + device->ID3D11Device2_iface.lpVtbl = &d3d11_device_vtbl; + device->ID3D10Device1_iface.lpVtbl = &d3d10_device1_vtbl; + device->ID3D10Multithread_iface.lpVtbl = &d3d10_multithread_vtbl; + device->IWineDXGIDeviceParent_iface.lpVtbl = &d3d_dxgi_device_parent_vtbl; + device->device_parent.ops = &d3d_wined3d_device_parent_ops; + device->refcount = 1; + /* COM aggregation always takes place */ + device->outer_unk = outer_unknown; + + d3d11_immediate_context_init(&device->immediate_context, device); + ID3D11DeviceContext1_Release(&device->immediate_context.ID3D11DeviceContext1_iface); + + wine_rb_init(&device->blend_states, d3d_blend_state_compare); + wine_rb_init(&device->depthstencil_states, d3d_depthstencil_state_compare); + wine_rb_init(&device->rasterizer_states, d3d_rasterizer_state_compare); + wine_rb_init(&device->sampler_states, d3d_sampler_state_compare); +} diff --git a/dll/directx/wine/d3d11/inputlayout.c b/dll/directx/wine/d3d11/inputlayout.c new file mode 100644 index 00000000000..29340735840 --- /dev/null +++ b/dll/directx/wine/d3d11/inputlayout.c @@ -0,0 +1,406 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, + const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx) +{ + struct wined3d_shader_signature_element *e = s->elements; + unsigned int i; + + for (i = 0; i < s->element_count; ++i) + { + if (!_strnicmp(e[i].semantic_name, semantic_name, -1) && e[i].semantic_idx == semantic_idx + && e[i].stream_idx == stream_idx) + return &e[i]; + } + + return NULL; +} + +static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEMENT_DESC *element_descs, + UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, + struct wined3d_vertex_element **wined3d_elements) +{ + struct wined3d_shader_signature is; + unsigned int i; + HRESULT hr; + + if (FAILED(hr = wined3d_extract_shader_input_signature_from_dxbc(&is, shader_byte_code, shader_byte_code_length))) + { + ERR("Failed to extract input signature.\n"); + return E_FAIL; + } + + if (!(*wined3d_elements = heap_calloc(element_count, sizeof(**wined3d_elements)))) + { + ERR("Failed to allocate wined3d vertex element array memory.\n"); + heap_free(is.elements); + return E_OUTOFMEMORY; + } + + for (i = 0; i < element_count; ++i) + { + struct wined3d_vertex_element *e = &(*wined3d_elements)[i]; + const D3D11_INPUT_ELEMENT_DESC *f = &element_descs[i]; + struct wined3d_shader_signature_element *element; + + e->format = wined3dformat_from_dxgi_format(f->Format); + e->input_slot = f->InputSlot; + e->offset = f->AlignedByteOffset; + e->output_slot = WINED3D_OUTPUT_SLOT_UNUSED; + e->input_slot_class = f->InputSlotClass; + e->instance_data_step_rate = f->InstanceDataStepRate; + e->method = WINED3D_DECL_METHOD_DEFAULT; + e->usage = 0; + e->usage_idx = 0; + + if ((element = shader_find_signature_element(&is, f->SemanticName, f->SemanticIndex, 0))) + e->output_slot = element->register_idx; + else + WARN("Unused input element %u.\n", i); + } + + heap_free(is.elements); + + return S_OK; +} + +/* ID3D11InputLayout methods */ + +static inline struct d3d_input_layout *impl_from_ID3D11InputLayout(ID3D11InputLayout *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_input_layout, ID3D11InputLayout_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_input_layout_QueryInterface(ID3D11InputLayout *iface, + REFIID riid, void **object) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11InputLayout) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11InputLayout_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10InputLayout) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10InputLayout_AddRef(&layout->ID3D10InputLayout_iface); + *object = &layout->ID3D10InputLayout_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_input_layout_AddRef(ID3D11InputLayout *iface) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + ULONG refcount = InterlockedIncrement(&layout->refcount); + + TRACE("%p increasing refcount to %u.\n", layout, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(layout->device); + wined3d_mutex_lock(); + wined3d_vertex_declaration_incref(layout->wined3d_decl); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_input_layout_Release(ID3D11InputLayout *iface) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + ULONG refcount = InterlockedDecrement(&layout->refcount); + + TRACE("%p decreasing refcount to %u.\n", layout, refcount); + + if (!refcount) + { + ID3D11Device2 *device = layout->device; + + wined3d_mutex_lock(); + wined3d_vertex_declaration_decref(layout->wined3d_decl); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_input_layout_GetDevice(ID3D11InputLayout *iface, + ID3D11Device **device) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device_AddRef(*device = (ID3D11Device *)layout->device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_input_layout_GetPrivateData(ID3D11InputLayout *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&layout->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_input_layout_SetPrivateData(ID3D11InputLayout *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&layout->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_input_layout_SetPrivateDataInterface(ID3D11InputLayout *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_input_layout *layout = impl_from_ID3D11InputLayout(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&layout->private_store, guid, data); +} + +static const struct ID3D11InputLayoutVtbl d3d11_input_layout_vtbl = +{ + /* IUnknown methods */ + d3d11_input_layout_QueryInterface, + d3d11_input_layout_AddRef, + d3d11_input_layout_Release, + /* ID3D11DeviceChild methods */ + d3d11_input_layout_GetDevice, + d3d11_input_layout_GetPrivateData, + d3d11_input_layout_SetPrivateData, + d3d11_input_layout_SetPrivateDataInterface, +}; + +/* ID3D10InputLayout methods */ + +static inline struct d3d_input_layout *impl_from_ID3D10InputLayout(ID3D10InputLayout *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_input_layout, ID3D10InputLayout_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_QueryInterface(ID3D10InputLayout *iface, + REFIID riid, void **object) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_input_layout_QueryInterface(&layout->ID3D11InputLayout_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_input_layout_AddRef(ID3D10InputLayout *iface) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_input_layout_AddRef(&layout->ID3D11InputLayout_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_input_layout_Release(ID3D10InputLayout *iface) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_input_layout_Release(&layout->ID3D11InputLayout_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_input_layout_GetDevice(ID3D10InputLayout *iface, ID3D10Device **device) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(layout->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_GetPrivateData(ID3D10InputLayout *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&layout->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_SetPrivateData(ID3D10InputLayout *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&layout->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_SetPrivateDataInterface(ID3D10InputLayout *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_input_layout *layout = impl_from_ID3D10InputLayout(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&layout->private_store, guid, data); +} + +static const struct ID3D10InputLayoutVtbl d3d10_input_layout_vtbl = +{ + /* IUnknown methods */ + d3d10_input_layout_QueryInterface, + d3d10_input_layout_AddRef, + d3d10_input_layout_Release, + /* ID3D10DeviceChild methods */ + d3d10_input_layout_GetDevice, + d3d10_input_layout_GetPrivateData, + d3d10_input_layout_SetPrivateData, + d3d10_input_layout_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d_input_layout_wined3d_object_destroyed(void *parent) +{ + struct d3d_input_layout *layout = parent; + + wined3d_private_store_cleanup(&layout->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_input_layout_wined3d_parent_ops = +{ + d3d_input_layout_wined3d_object_destroyed, +}; + +static HRESULT d3d_input_layout_init(struct d3d_input_layout *layout, struct d3d_device *device, + const D3D11_INPUT_ELEMENT_DESC *element_descs, UINT element_count, + const void *shader_byte_code, SIZE_T shader_byte_code_length) +{ + struct wined3d_vertex_element *wined3d_elements; + HRESULT hr; + + layout->ID3D11InputLayout_iface.lpVtbl = &d3d11_input_layout_vtbl; + layout->ID3D10InputLayout_iface.lpVtbl = &d3d10_input_layout_vtbl; + layout->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&layout->private_store); + + if (FAILED(hr = d3d11_input_layout_to_wined3d_declaration(element_descs, element_count, + shader_byte_code, shader_byte_code_length, &wined3d_elements))) + { + WARN("Failed to create wined3d vertex declaration elements, hr %#x.\n", hr); + wined3d_private_store_cleanup(&layout->private_store); + wined3d_mutex_unlock(); + return hr; + } + + hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, element_count, + layout, &d3d_input_layout_wined3d_parent_ops, &layout->wined3d_decl); + heap_free(wined3d_elements); + if (FAILED(hr)) + { + WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr); + wined3d_private_store_cleanup(&layout->private_store); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(layout->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_input_layout_create(struct d3d_device *device, + const D3D11_INPUT_ELEMENT_DESC *element_descs, UINT element_count, + const void *shader_byte_code, SIZE_T shader_byte_code_length, + struct d3d_input_layout **layout) +{ + struct d3d_input_layout *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_input_layout_init(object, device, element_descs, element_count, + shader_byte_code, shader_byte_code_length))) + { + WARN("Failed to initialize input layout, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created input layout %p.\n", object); + *layout = object; + + return S_OK; +} + +struct d3d_input_layout *unsafe_impl_from_ID3D11InputLayout(ID3D11InputLayout *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_input_layout_vtbl); + + return impl_from_ID3D11InputLayout(iface); +} + +struct d3d_input_layout *unsafe_impl_from_ID3D10InputLayout(ID3D10InputLayout *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_input_layout_vtbl); + + return impl_from_ID3D10InputLayout(iface); +} diff --git a/dll/directx/wine/d3d11/shader.c b/dll/directx/wine/d3d11/shader.c new file mode 100644 index 00000000000..2667e9a883f --- /dev/null +++ b/dll/directx/wine/d3d11/shader.c @@ -0,0 +1,1870 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +/* ID3D11VertexShader methods */ + +static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D11VertexShader_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_QueryInterface(ID3D11VertexShader *iface, + REFIID riid, void **object) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11VertexShader) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11VertexShader_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10VertexShader) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + IUnknown_AddRef(&shader->ID3D10VertexShader_iface); + *object = &shader->ID3D10VertexShader_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_AddRef(ID3D11VertexShader *iface) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + ULONG refcount = InterlockedIncrement(&shader->refcount); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(shader->device); + wined3d_mutex_lock(); + wined3d_shader_incref(shader->wined3d_shader); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + ULONG refcount = InterlockedDecrement(&shader->refcount); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + ID3D11Device2 *device = shader->device; + + wined3d_mutex_lock(); + wined3d_shader_decref(shader->wined3d_shader); + wined3d_mutex_unlock(); + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface, + ID3D11Device **device) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)shader->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl = +{ + /* IUnknown methods */ + d3d11_vertex_shader_QueryInterface, + d3d11_vertex_shader_AddRef, + d3d11_vertex_shader_Release, + /* ID3D11DeviceChild methods */ + d3d11_vertex_shader_GetDevice, + d3d11_vertex_shader_GetPrivateData, + d3d11_vertex_shader_SetPrivateData, + d3d11_vertex_shader_SetPrivateDataInterface, +}; + +/* ID3D10VertexShader methods */ + +static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface, + REFIID riid, void **object) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl = +{ + /* IUnknown methods */ + d3d10_vertex_shader_QueryInterface, + d3d10_vertex_shader_AddRef, + d3d10_vertex_shader_Release, + /* ID3D10DeviceChild methods */ + d3d10_vertex_shader_GetDevice, + d3d10_vertex_shader_GetPrivateData, + d3d10_vertex_shader_SetPrivateData, + d3d10_vertex_shader_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d_vertex_shader *shader = parent; + + wined3d_private_store_cleanup(&shader->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops = +{ + d3d_vertex_shader_wined3d_object_destroyed, +}; + +static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device, + const void *byte_code, SIZE_T byte_code_length) +{ + struct wined3d_shader_desc desc; + HRESULT hr; + + shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl; + shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl; + shader->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&shader->private_store); + + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + if (FAILED(hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader, + &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader))) + { + WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr); + wined3d_private_store_cleanup(&shader->private_store); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d_vertex_shader **shader) +{ + struct d3d_vertex_shader *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length))) + { + WARN("Failed to initialize vertex shader, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created vertex shader %p.\n", object); + *shader = object; + + return S_OK; +} + +struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl); + + return impl_from_ID3D11VertexShader(iface); +} + +struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl); + + return impl_from_ID3D10VertexShader(iface); +} + +/* ID3D11HullShader methods */ + +static inline struct d3d11_hull_shader *impl_from_ID3D11HullShader(ID3D11HullShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_hull_shader, ID3D11HullShader_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_QueryInterface(ID3D11HullShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11HullShader) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11HullShader_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_hull_shader_AddRef(ID3D11HullShader *iface) +{ + struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface); + ULONG refcount = InterlockedIncrement(&shader->refcount); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(shader->device); + wined3d_mutex_lock(); + wined3d_shader_incref(shader->wined3d_shader); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface) +{ + struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface); + ULONG refcount = InterlockedDecrement(&shader->refcount); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + ID3D11Device2 *device = shader->device; + + wined3d_mutex_lock(); + wined3d_shader_decref(shader->wined3d_shader); + wined3d_mutex_unlock(); + + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_hull_shader_GetDevice(ID3D11HullShader *iface, + ID3D11Device **device) +{ + struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)shader->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_GetPrivateData(ID3D11HullShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateData(ID3D11HullShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl = +{ + /* IUnknown methods */ + d3d11_hull_shader_QueryInterface, + d3d11_hull_shader_AddRef, + d3d11_hull_shader_Release, + /* ID3D11DeviceChild methods */ + d3d11_hull_shader_GetDevice, + d3d11_hull_shader_GetPrivateData, + d3d11_hull_shader_SetPrivateData, + d3d11_hull_shader_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d11_hull_shader *shader = parent; + + wined3d_private_store_cleanup(&shader->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops = +{ + d3d11_hull_shader_wined3d_object_destroyed, +}; + +static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device, + const void *byte_code, SIZE_T byte_code_length) +{ + struct wined3d_shader_desc desc; + HRESULT hr; + + shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl; + shader->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&shader->private_store); + + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + if (FAILED(hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader, + &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader))) + { + WARN("Failed to create wined3d hull shader, hr %#x.\n", hr); + wined3d_private_store_cleanup(&shader->private_store); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d11_hull_shader **shader) +{ + struct d3d11_hull_shader *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length))) + { + heap_free(object); + return hr; + } + + TRACE("Created hull shader %p.\n", object); + *shader = object; + + return S_OK; +} + +struct d3d11_hull_shader *unsafe_impl_from_ID3D11HullShader(ID3D11HullShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_hull_shader_vtbl); + + return impl_from_ID3D11HullShader(iface); +} + +/* ID3D11DomainShader methods */ + +static inline struct d3d11_domain_shader *impl_from_ID3D11DomainShader(ID3D11DomainShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_domain_shader, ID3D11DomainShader_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_QueryInterface(ID3D11DomainShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11DomainShader) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11DomainShader_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_domain_shader_AddRef(ID3D11DomainShader *iface) +{ + struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface); + ULONG refcount = InterlockedIncrement(&shader->refcount); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(shader->device); + wined3d_mutex_lock(); + wined3d_shader_incref(shader->wined3d_shader); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_domain_shader_Release(ID3D11DomainShader *iface) +{ + struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface); + ULONG refcount = InterlockedDecrement(&shader->refcount); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + ID3D11Device2 *device = shader->device; + + wined3d_mutex_lock(); + wined3d_shader_decref(shader->wined3d_shader); + wined3d_mutex_unlock(); + + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_domain_shader_GetDevice(ID3D11DomainShader *iface, + ID3D11Device **device) +{ + struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)shader->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_GetPrivateData(ID3D11DomainShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateData(ID3D11DomainShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl = +{ + /* IUnknown methods */ + d3d11_domain_shader_QueryInterface, + d3d11_domain_shader_AddRef, + d3d11_domain_shader_Release, + /* ID3D11DeviceChild methods */ + d3d11_domain_shader_GetDevice, + d3d11_domain_shader_GetPrivateData, + d3d11_domain_shader_SetPrivateData, + d3d11_domain_shader_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d11_domain_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d11_domain_shader *shader = parent; + + wined3d_private_store_cleanup(&shader->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops = +{ + d3d11_domain_shader_wined3d_object_destroyed, +}; + +static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, struct d3d_device *device, + const void *byte_code, SIZE_T byte_code_length) +{ + struct wined3d_shader_desc desc; + HRESULT hr; + + shader->ID3D11DomainShader_iface.lpVtbl = &d3d11_domain_shader_vtbl; + shader->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&shader->private_store); + + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + if (FAILED(hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader, + &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader))) + { + WARN("Failed to create wined3d domain shader, hr %#x.\n", hr); + wined3d_private_store_cleanup(&shader->private_store); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d11_domain_shader **shader) +{ + struct d3d11_domain_shader *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d11_domain_shader_init(object, device, byte_code, byte_code_length))) + { + heap_free(object); + return hr; + } + + TRACE("Created domain shader %p.\n", object); + *shader = object; + + return S_OK; +} + +struct d3d11_domain_shader *unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_domain_shader_vtbl); + + return impl_from_ID3D11DomainShader(iface); +} + +/* ID3D11GeometryShader methods */ + +static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface, + REFIID riid, void **object) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11GeometryShader) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11GeometryShader_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10GeometryShader) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface); + *object = &shader->ID3D10GeometryShader_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + ULONG refcount = InterlockedIncrement(&shader->refcount); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(shader->device); + wined3d_mutex_lock(); + wined3d_shader_incref(shader->wined3d_shader); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + ULONG refcount = InterlockedDecrement(&shader->refcount); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + ID3D11Device2 *device = shader->device; + + wined3d_mutex_lock(); + wined3d_shader_decref(shader->wined3d_shader); + wined3d_mutex_unlock(); + + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface, + ID3D11Device **device) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)shader->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl = +{ + /* IUnknown methods */ + d3d11_geometry_shader_QueryInterface, + d3d11_geometry_shader_AddRef, + d3d11_geometry_shader_Release, + /* ID3D11DeviceChild methods */ + d3d11_geometry_shader_GetDevice, + d3d11_geometry_shader_GetPrivateData, + d3d11_geometry_shader_SetPrivateData, + d3d11_geometry_shader_SetPrivateDataInterface, +}; + +/* ID3D10GeometryShader methods */ + +static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface, + REFIID riid, void **object) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl = +{ + /* IUnknown methods */ + d3d10_geometry_shader_QueryInterface, + d3d10_geometry_shader_AddRef, + d3d10_geometry_shader_Release, + /* ID3D10DeviceChild methods */ + d3d10_geometry_shader_GetDevice, + d3d10_geometry_shader_GetPrivateData, + d3d10_geometry_shader_SetPrivateData, + d3d10_geometry_shader_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d_geometry_shader *shader = parent; + + wined3d_private_store_cleanup(&shader->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops = +{ + d3d_geometry_shader_wined3d_object_destroyed, +}; + +static HRESULT validate_stream_output_entries(const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count, + const unsigned int *buffer_strides, unsigned int buffer_stride_count, D3D_FEATURE_LEVEL feature_level) +{ + unsigned int i, j; + + for (i = 0; i < entry_count; ++i) + { + const D3D11_SO_DECLARATION_ENTRY *e = &entries[i]; + + TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, " + "component count %u, output slot %u.\n", + e->Stream, debugstr_a(e->SemanticName), e->SemanticIndex, + e->StartComponent, e->ComponentCount, e->OutputSlot); + + if (e->Stream >= D3D11_SO_STREAM_COUNT) + { + WARN("Invalid stream %u.\n", e->Stream); + return E_INVALIDARG; + } + if (e->Stream && feature_level < D3D_FEATURE_LEVEL_11_0) + { + WARN("Invalid stream %u for feature level %#x.\n", e->Stream, feature_level); + return E_INVALIDARG; + } + if (e->Stream) + { + FIXME("Streams not implemented yet.\n"); + return E_INVALIDARG; + } + if (e->OutputSlot >= D3D11_SO_BUFFER_SLOT_COUNT) + { + WARN("Invalid output slot %u.\n", e->OutputSlot); + return E_INVALIDARG; + } + + if (!e->SemanticName) + { + if (e->SemanticIndex) + { + WARN("Invalid semantic idx %u for stream output gap.\n", e->SemanticIndex); + return E_INVALIDARG; + } + if (e->StartComponent || !e->ComponentCount) + { + WARN("Invalid stream output gap %u-%u.\n", e->StartComponent, e->ComponentCount); + return E_INVALIDARG; + } + } + else + { + if (e->StartComponent > 3 || e->ComponentCount > 4 || !e->ComponentCount + || e->StartComponent + e->ComponentCount > 4) + { + WARN("Invalid component range %u-%u.\n", e->StartComponent, e->ComponentCount); + return E_INVALIDARG; + } + } + } + + for (i = 0; i < entry_count; ++i) + { + const D3D11_SO_DECLARATION_ENTRY *e1 = &entries[i]; + if (!e1->SemanticName) /* gap */ + continue; + + for (j = i + 1; j < entry_count; ++j) + { + const D3D11_SO_DECLARATION_ENTRY *e2 = &entries[j]; + if (!e2->SemanticName) /* gap */ + continue; + + if (e1->Stream == e2->Stream + && !_strnicmp(e1->SemanticName, e2->SemanticName, -1) + && e1->SemanticIndex == e2->SemanticIndex + && e1->StartComponent < e2->StartComponent + e2->ComponentCount + && e1->StartComponent + e1->ComponentCount > e2->StartComponent) + { + WARN("Stream output elements %u and %u overlap.\n", i, j); + return E_INVALIDARG; + } + } + } + + for (i = 0; i < D3D11_SO_STREAM_COUNT; ++i) + { + unsigned int current_stride[D3D11_SO_BUFFER_SLOT_COUNT] = {0}; + unsigned int element_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0}; + unsigned int gap_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0}; + + for (j = 0; j < entry_count; ++j) + { + const D3D11_SO_DECLARATION_ENTRY *e = &entries[j]; + + if (e->Stream != i) + continue; + current_stride[e->OutputSlot] += 4 * e->ComponentCount; + ++element_count[e->OutputSlot]; + if (!e->SemanticName) + ++gap_count[e->OutputSlot]; + } + + for (j = 0; j < D3D11_SO_BUFFER_SLOT_COUNT; ++j) + { + if (!element_count[j]) + continue; + if (element_count[j] == gap_count[j]) + { + WARN("Stream %u, output slot %u contains only gaps.\n", i, j); + return E_INVALIDARG; + } + if (buffer_stride_count) + { + if (buffer_stride_count <= j) + { + WARN("Buffer strides are required for all buffer slots.\n"); + return E_INVALIDARG; + } + if (buffer_strides[j] < current_stride[j] || buffer_strides[j] % 4) + { + WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides[j], j); + return E_INVALIDARG; + } + } + } + + if (!i && feature_level < D3D_FEATURE_LEVEL_11_0 && element_count[0] != entry_count) + { + for (j = 0; j < ARRAY_SIZE(element_count); ++j) + { + if (element_count[j] > 1) + { + WARN("Only one element per output slot is allowed.\n"); + return E_INVALIDARG; + } + } + } + } + + return S_OK; +} + +static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, + struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count, + const unsigned int *buffer_strides, unsigned int buffer_stride_count, + unsigned int rasterizer_stream) +{ + struct wined3d_stream_output_desc so_desc; + struct wined3d_shader_desc desc; + unsigned int i; + HRESULT hr; + + if (so_entry_count > D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT) + { + WARN("Entry count %u is greater than %u.\n", + so_entry_count, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT); + return E_INVALIDARG; + } + if (so_entries && !so_entry_count) + { + WARN("Invalid SO entry count %u.\n", so_entry_count); + return E_INVALIDARG; + } + if (rasterizer_stream != D3D11_SO_NO_RASTERIZED_STREAM && rasterizer_stream >= D3D11_SO_STREAM_COUNT) + { + WARN("Invalid rasterizer stream %u.\n", rasterizer_stream); + return E_INVALIDARG; + } + if (device->feature_level < D3D_FEATURE_LEVEL_11_0) + { + if (rasterizer_stream) + { + WARN("Invalid rasterizer stream %u for feature level %#x.\n", + rasterizer_stream, device->feature_level); + return E_INVALIDARG; + } + if (buffer_stride_count && buffer_stride_count != 1) + { + WARN("Invalid buffer stride count %u for feature level %#x.\n", + buffer_stride_count, device->feature_level); + return E_INVALIDARG; + } + } + + if (FAILED(hr = validate_stream_output_entries(so_entries, so_entry_count, + buffer_strides, buffer_stride_count, device->feature_level))) + return hr; + + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + + memset(&so_desc, 0, sizeof(so_desc)); + if (so_entries) + { + so_desc.elements = (const struct wined3d_stream_output_element *)so_entries; + so_desc.element_count = so_entry_count; + for (i = 0; i < min(buffer_stride_count, ARRAY_SIZE(so_desc.buffer_strides)); ++i) + so_desc.buffer_strides[i] = buffer_strides[i]; + so_desc.buffer_stride_count = buffer_stride_count; + so_desc.rasterizer_stream_idx = rasterizer_stream; + } + + shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl; + shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl; + shader->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&shader->private_store); + + if (FAILED(hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL, + shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader))) + { + WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr); + wined3d_private_store_cleanup(&shader->private_store); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count, + const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream, + struct d3d_geometry_shader **shader) +{ + struct d3d_geometry_shader *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length, + so_entries, so_entry_count, buffer_strides, buffer_stride_count, rasterizer_stream))) + { + WARN("Failed to initialize geometry shader, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created geometry shader %p.\n", object); + *shader = object; + + return S_OK; +} + +struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl); + + return impl_from_ID3D11GeometryShader(iface); +} + +struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl); + + return impl_from_ID3D10GeometryShader(iface); +} + +/* ID3D11PixelShader methods */ + +static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface, + REFIID riid, void **object) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11PixelShader) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11PixelShader_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10PixelShader) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + IUnknown_AddRef(&shader->ID3D10PixelShader_iface); + *object = &shader->ID3D10PixelShader_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + ULONG refcount = InterlockedIncrement(&shader->refcount); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(shader->device); + wined3d_mutex_lock(); + wined3d_shader_incref(shader->wined3d_shader); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + ULONG refcount = InterlockedDecrement(&shader->refcount); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + ID3D11Device2 *device = shader->device; + + wined3d_mutex_lock(); + wined3d_shader_decref(shader->wined3d_shader); + wined3d_mutex_unlock(); + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface, + ID3D11Device **device) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)shader->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl = +{ + /* IUnknown methods */ + d3d11_pixel_shader_QueryInterface, + d3d11_pixel_shader_AddRef, + d3d11_pixel_shader_Release, + /* ID3D11DeviceChild methods */ + d3d11_pixel_shader_GetDevice, + d3d11_pixel_shader_GetPrivateData, + d3d11_pixel_shader_SetPrivateData, + d3d11_pixel_shader_SetPrivateDataInterface, +}; + +/* ID3D10PixelShader methods */ + +static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface, + REFIID riid, void **object) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl = +{ + /* IUnknown methods */ + d3d10_pixel_shader_QueryInterface, + d3d10_pixel_shader_AddRef, + d3d10_pixel_shader_Release, + /* ID3D10DeviceChild methods */ + d3d10_pixel_shader_GetDevice, + d3d10_pixel_shader_GetPrivateData, + d3d10_pixel_shader_SetPrivateData, + d3d10_pixel_shader_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d_pixel_shader *shader = parent; + + wined3d_private_store_cleanup(&shader->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops = +{ + d3d_pixel_shader_wined3d_object_destroyed, +}; + +static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device, + const void *byte_code, SIZE_T byte_code_length) +{ + struct wined3d_shader_desc desc; + HRESULT hr; + + shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl; + shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl; + shader->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&shader->private_store); + + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + if (FAILED(hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader, + &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader))) + { + WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr); + wined3d_private_store_cleanup(&shader->private_store); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d_pixel_shader **shader) +{ + struct d3d_pixel_shader *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length))) + { + WARN("Failed to initialize pixel shader, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created pixel shader %p.\n", object); + *shader = object; + + return S_OK; +} + +struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl); + + return impl_from_ID3D11PixelShader(iface); +} + +struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl); + + return impl_from_ID3D10PixelShader(iface); +} + +/* ID3D11ComputeShader methods */ + +static inline struct d3d11_compute_shader *impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_compute_shader, ID3D11ComputeShader_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_QueryInterface(ID3D11ComputeShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11ComputeShader) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11ComputeShader_AddRef(*object = iface); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_compute_shader_AddRef(ID3D11ComputeShader *iface) +{ + struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface); + ULONG refcount = InterlockedIncrement(&shader->refcount); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(shader->device); + wined3d_mutex_lock(); + wined3d_shader_incref(shader->wined3d_shader); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_compute_shader_Release(ID3D11ComputeShader *iface) +{ + struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface); + ULONG refcount = InterlockedDecrement(&shader->refcount); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + ID3D11Device2 *device = shader->device; + + wined3d_mutex_lock(); + wined3d_shader_decref(shader->wined3d_shader); + wined3d_mutex_unlock(); + + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_compute_shader_GetDevice(ID3D11ComputeShader *iface, + ID3D11Device **device) +{ + struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device_AddRef(*device = (ID3D11Device *)shader->device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&shader->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&shader->private_store, guid, data); +} + +static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl = +{ + /* IUnknown methods */ + d3d11_compute_shader_QueryInterface, + d3d11_compute_shader_AddRef, + d3d11_compute_shader_Release, + /* ID3D11DeviceChild methods */ + d3d11_compute_shader_GetDevice, + d3d11_compute_shader_GetPrivateData, + d3d11_compute_shader_SetPrivateData, + d3d11_compute_shader_SetPrivateDataInterface, +}; + +static void STDMETHODCALLTYPE d3d11_compute_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d11_compute_shader *shader = parent; + + wined3d_private_store_cleanup(&shader->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops = +{ + d3d11_compute_shader_wined3d_object_destroyed, +}; + +static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, struct d3d_device *device, + const void *byte_code, SIZE_T byte_code_length) +{ + struct wined3d_shader_desc desc; + HRESULT hr; + + shader->ID3D11ComputeShader_iface.lpVtbl = &d3d11_compute_shader_vtbl; + shader->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&shader->private_store); + + desc.byte_code = byte_code; + desc.byte_code_size = byte_code_length; + if (FAILED(hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader, + &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader))) + { + WARN("Failed to create wined3d compute shader, hr %#x.\n", hr); + wined3d_private_store_cleanup(&shader->private_store); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length, + struct d3d11_compute_shader **shader) +{ + struct d3d11_compute_shader *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d11_compute_shader_init(object, device, byte_code, byte_code_length))) + { + heap_free(object); + return hr; + } + + TRACE("Created compute shader %p.\n", object); + *shader = object; + + return S_OK; +} + +struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_compute_shader_vtbl); + + return impl_from_ID3D11ComputeShader(iface); +} + +/* ID3D11ClassLinkage methods */ + +static inline struct d3d11_class_linkage *impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_class_linkage, ID3D11ClassLinkage_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11ClassLinkage) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11ClassLinkage_AddRef(*object = iface); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_class_linkage_AddRef(ID3D11ClassLinkage *iface) +{ + struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface); + ULONG refcount = InterlockedIncrement(&class_linkage->refcount); + + TRACE("%p increasing refcount to %u.\n", class_linkage, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_class_linkage_Release(ID3D11ClassLinkage *iface) +{ + struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface); + ULONG refcount = InterlockedDecrement(&class_linkage->refcount); + + TRACE("%p decreasing refcount to %u.\n", class_linkage, refcount); + + if (!refcount) + { + ID3D11Device2 *device = class_linkage->device; + + wined3d_private_store_cleanup(&class_linkage->private_store); + heap_free(class_linkage); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_class_linkage_GetDevice(ID3D11ClassLinkage *iface, + ID3D11Device **device) +{ + struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device_AddRef(*device = (ID3D11Device *)class_linkage->device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&class_linkage->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&class_linkage->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&class_linkage->private_store, guid, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage *iface, + const char *instance_name, UINT instance_index, ID3D11ClassInstance **class_instance) +{ + FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n", + iface, debugstr_a(instance_name), instance_index, class_instance); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage *iface, + const char *type_name, UINT cb_offset, UINT cb_vector_offset, UINT texture_offset, + UINT sampler_offset, ID3D11ClassInstance **class_instance) +{ + FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, " + "sampler_offset %u, class_instance %p stub!\n", + iface, debugstr_a(type_name), cb_offset, cb_vector_offset, texture_offset, + sampler_offset, class_instance); + + return E_NOTIMPL; +} + +static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl = +{ + /* IUnknown methods */ + d3d11_class_linkage_QueryInterface, + d3d11_class_linkage_AddRef, + d3d11_class_linkage_Release, + /* ID3D11DeviceChild methods */ + d3d11_class_linkage_GetDevice, + d3d11_class_linkage_GetPrivateData, + d3d11_class_linkage_SetPrivateData, + d3d11_class_linkage_SetPrivateDataInterface, + /* ID3D11ClassLinkage methods */ + d3d11_class_linkage_GetClassInstance, + d3d11_class_linkage_CreateClassInstance, +}; + +HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage) +{ + struct d3d11_class_linkage *object; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID3D11ClassLinkage_iface.lpVtbl = &d3d11_class_linkage_vtbl; + object->refcount = 1; + wined3d_private_store_init(&object->private_store); + + ID3D11Device2_AddRef(object->device = &device->ID3D11Device2_iface); + + TRACE("Created class linkage %p.\n", object); + *class_linkage = object; + + return S_OK; +} diff --git a/dll/directx/wine/d3d11/state.c b/dll/directx/wine/d3d11/state.c new file mode 100644 index 00000000000..92b75f8e1fb --- /dev/null +++ b/dll/directx/wine/d3d11/state.c @@ -0,0 +1,1583 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +/* ID3D11BlendState methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_QueryInterface(ID3D11BlendState *iface, + REFIID riid, void **object) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11BlendState) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11BlendState_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10BlendState1) + || IsEqualGUID(riid, &IID_ID3D10BlendState) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10BlendState1_AddRef(&state->ID3D10BlendState1_iface); + *object = &state->ID3D10BlendState1_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_blend_state_AddRef(ID3D11BlendState *iface) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(state->device); + wined3d_mutex_lock(); + wined3d_blend_state_incref(state->wined3d_state); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState *iface) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + ID3D11Device2 *device = state->device; + + wined3d_mutex_lock(); + wined3d_blend_state_decref(state->wined3d_state); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_blend_state_GetDevice(ID3D11BlendState *iface, + ID3D11Device **device) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)state->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_GetPrivateData(ID3D11BlendState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateData(ID3D11BlendState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_blend_state_GetDesc(ID3D11BlendState *iface, D3D11_BLEND_DESC *desc) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = state->desc; +} + +static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl = +{ + /* IUnknown methods */ + d3d11_blend_state_QueryInterface, + d3d11_blend_state_AddRef, + d3d11_blend_state_Release, + /* ID3D11DeviceChild methods */ + d3d11_blend_state_GetDevice, + d3d11_blend_state_GetPrivateData, + d3d11_blend_state_SetPrivateData, + d3d11_blend_state_SetPrivateDataInterface, + /* ID3D11BlendState methods */ + d3d11_blend_state_GetDesc, +}; + +/* ID3D10BlendState methods */ + +static inline struct d3d_blend_state *impl_from_ID3D10BlendState(ID3D10BlendState1 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_blend_state, ID3D10BlendState1_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_blend_state_QueryInterface(ID3D10BlendState1 *iface, + REFIID riid, void **object) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_blend_state_QueryInterface(&state->ID3D11BlendState_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_blend_state_AddRef(ID3D10BlendState1 *iface) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_blend_state_AddRef(&state->ID3D11BlendState_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_blend_state_Release(ID3D10BlendState1 *iface) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_blend_state_Release(&state->ID3D11BlendState_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_blend_state_GetDevice(ID3D10BlendState1 *iface, ID3D10Device **device) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(state->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_blend_state_GetPrivateData(ID3D10BlendState1 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_blend_state_SetPrivateData(ID3D10BlendState1 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1 *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +/* ID3D10BlendState methods */ + +static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc(ID3D10BlendState1 *iface, D3D10_BLEND_DESC *desc) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + const D3D11_BLEND_DESC *d3d11_desc = &state->desc; + unsigned int i; + + TRACE("iface %p, desc %p.\n", iface, desc); + + desc->AlphaToCoverageEnable = d3d11_desc->AlphaToCoverageEnable; + desc->SrcBlend = d3d11_desc->RenderTarget[0].SrcBlend; + desc->DestBlend = d3d11_desc->RenderTarget[0].DestBlend; + desc->BlendOp = d3d11_desc->RenderTarget[0].BlendOp; + desc->SrcBlendAlpha = d3d11_desc->RenderTarget[0].SrcBlendAlpha; + desc->DestBlendAlpha = d3d11_desc->RenderTarget[0].DestBlendAlpha; + desc->BlendOpAlpha = d3d11_desc->RenderTarget[0].BlendOpAlpha; + for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + desc->BlendEnable[i] = d3d11_desc->RenderTarget[i].BlendEnable; + desc->RenderTargetWriteMask[i] = d3d11_desc->RenderTarget[i].RenderTargetWriteMask; + } +} + +static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc1(ID3D10BlendState1 *iface, D3D10_BLEND_DESC1 *desc) +{ + struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &state->desc, sizeof(*desc)); +} + +static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl = +{ + /* IUnknown methods */ + d3d10_blend_state_QueryInterface, + d3d10_blend_state_AddRef, + d3d10_blend_state_Release, + /* ID3D10DeviceChild methods */ + d3d10_blend_state_GetDevice, + d3d10_blend_state_GetPrivateData, + d3d10_blend_state_SetPrivateData, + d3d10_blend_state_SetPrivateDataInterface, + /* ID3D10BlendState methods */ + d3d10_blend_state_GetDesc, + /* ID3D10BlendState1 methods */ + d3d10_blend_state_GetDesc1, +}; + +static void STDMETHODCALLTYPE d3d_blend_state_wined3d_object_destroyed(void *parent) +{ + struct d3d_blend_state *state = parent; + struct d3d_device *device = impl_from_ID3D11Device2(state->device); + + wine_rb_remove(&device->blend_states, &state->entry); + wined3d_private_store_cleanup(&state->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_blend_state_wined3d_parent_ops = +{ + d3d_blend_state_wined3d_object_destroyed, +}; + +HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC *desc, + struct d3d_blend_state **state) +{ + struct wined3d_blend_state_desc wined3d_desc; + struct d3d_blend_state *object; + struct wine_rb_entry *entry; + D3D11_BLEND_DESC tmp_desc; + unsigned int i, j; + HRESULT hr; + + if (!desc) + return E_INVALIDARG; + + /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use + * D3D11_BLEND_DESC as a key in the rbtree. */ + memset(&tmp_desc, 0, sizeof(tmp_desc)); + tmp_desc.AlphaToCoverageEnable = desc->AlphaToCoverageEnable; + tmp_desc.IndependentBlendEnable = desc->IndependentBlendEnable; + for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + j = desc->IndependentBlendEnable ? i : 0; + tmp_desc.RenderTarget[i].BlendEnable = desc->RenderTarget[j].BlendEnable; + if (tmp_desc.RenderTarget[i].BlendEnable) + { + tmp_desc.RenderTarget[i].SrcBlend = desc->RenderTarget[j].SrcBlend; + tmp_desc.RenderTarget[i].DestBlend = desc->RenderTarget[j].DestBlend; + tmp_desc.RenderTarget[i].BlendOp = desc->RenderTarget[j].BlendOp; + tmp_desc.RenderTarget[i].SrcBlendAlpha = desc->RenderTarget[j].SrcBlendAlpha; + tmp_desc.RenderTarget[i].DestBlendAlpha = desc->RenderTarget[j].DestBlendAlpha; + tmp_desc.RenderTarget[i].BlendOpAlpha = desc->RenderTarget[j].BlendOpAlpha; + } + else + { + tmp_desc.RenderTarget[i].SrcBlend = D3D11_BLEND_ONE; + tmp_desc.RenderTarget[i].DestBlend = D3D11_BLEND_ZERO; + tmp_desc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD; + tmp_desc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE; + tmp_desc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO; + tmp_desc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; + } + tmp_desc.RenderTarget[i].RenderTargetWriteMask = desc->RenderTarget[j].RenderTargetWriteMask; + + if (i > 3 && tmp_desc.RenderTarget[i].RenderTargetWriteMask != D3D11_COLOR_WRITE_ENABLE_ALL) + FIXME("Color mask %#x not supported for render target %u.\n", + tmp_desc.RenderTarget[i].RenderTargetWriteMask, i); + } + + /* glEnableIndexedEXT(GL_BLEND, ...) */ + if (tmp_desc.IndependentBlendEnable) + FIXME("Per-rendertarget blend not implemented.\n"); + + wined3d_mutex_lock(); + if ((entry = wine_rb_get(&device->blend_states, &tmp_desc))) + { + object = WINE_RB_ENTRY_VALUE(entry, struct d3d_blend_state, entry); + + TRACE("Returning existing blend state %p.\n", object); + ID3D11BlendState_AddRef(&object->ID3D11BlendState_iface); + *state = object; + wined3d_mutex_unlock(); + + return S_OK; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } + + object->ID3D11BlendState_iface.lpVtbl = &d3d11_blend_state_vtbl; + object->ID3D10BlendState1_iface.lpVtbl = &d3d10_blend_state_vtbl; + object->refcount = 1; + wined3d_private_store_init(&object->private_store); + object->desc = tmp_desc; + + if (wine_rb_put(&device->blend_states, &tmp_desc, &object->entry) == -1) + { + ERR("Failed to insert blend state entry.\n"); + wined3d_private_store_cleanup(&object->private_store); + heap_free(object); + wined3d_mutex_unlock(); + return E_FAIL; + } + + wined3d_desc.alpha_to_coverage = desc->AlphaToCoverageEnable; + + /* We cannot fail after creating a wined3d_blend_state object. It + * would lead to double free. */ + if (FAILED(hr = wined3d_blend_state_create(device->wined3d_device, &wined3d_desc, + object, &d3d_blend_state_wined3d_parent_ops, &object->wined3d_state))) + { + WARN("Failed to create wined3d blend state, hr %#x.\n", hr); + wined3d_private_store_cleanup(&object->private_store); + wine_rb_remove(&device->blend_states, &object->entry); + heap_free(object); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(object->device = &device->ID3D11Device2_iface); + + TRACE("Created blend state %p.\n", object); + *state = object; + + return S_OK; +} + +struct d3d_blend_state *unsafe_impl_from_ID3D11BlendState(ID3D11BlendState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_blend_state_vtbl); + + return impl_from_ID3D11BlendState(iface); +} + +struct d3d_blend_state *unsafe_impl_from_ID3D10BlendState(ID3D10BlendState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == (ID3D10BlendStateVtbl *)&d3d10_blend_state_vtbl); + + return impl_from_ID3D10BlendState((ID3D10BlendState1 *)iface); +} + +/* ID3D11DepthStencilState methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState *iface, + REFIID riid, void **object) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11DepthStencilState) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11DepthStencilState_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10DepthStencilState) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10DepthStencilState_AddRef(&state->ID3D10DepthStencilState_iface); + *object = &state->ID3D10DepthStencilState_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState *iface) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + return refcount; +} + +static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state *state) +{ + wined3d_private_store_cleanup(&state->private_store); + ID3D11Device2_Release(state->device); +} + +static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStencilState *iface) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + struct d3d_device *device = impl_from_ID3D11Device2(state->device); + wined3d_mutex_lock(); + wine_rb_remove(&device->depthstencil_states, &state->entry); + d3d_depthstencil_state_cleanup(state); + wined3d_mutex_unlock(); + heap_free(state); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState *iface, + ID3D11Device **device) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)state->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState *iface, + D3D11_DEPTH_STENCIL_DESC *desc) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = state->desc; +} + +static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl = +{ + /* IUnknown methods */ + d3d11_depthstencil_state_QueryInterface, + d3d11_depthstencil_state_AddRef, + d3d11_depthstencil_state_Release, + /* ID3D11DeviceChild methods */ + d3d11_depthstencil_state_GetDevice, + d3d11_depthstencil_state_GetPrivateData, + d3d11_depthstencil_state_SetPrivateData, + d3d11_depthstencil_state_SetPrivateDataInterface, + /* ID3D11DepthStencilState methods */ + d3d11_depthstencil_state_GetDesc, +}; + +/* ID3D10DepthStencilState methods */ + +static inline struct d3d_depthstencil_state *impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_depthstencil_state, ID3D10DepthStencilState_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState *iface, + REFIID riid, void **object) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_depthstencil_state_QueryInterface(&state->ID3D11DepthStencilState_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState *iface) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_depthstencil_state_AddRef(&state->ID3D11DepthStencilState_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_depthstencil_state_Release(ID3D10DepthStencilState *iface) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_depthstencil_state_Release(&state->ID3D11DepthStencilState_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState *iface, ID3D10Device **device) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(state->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +/* ID3D10DepthStencilState methods */ + +static void STDMETHODCALLTYPE d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState *iface, + D3D10_DEPTH_STENCIL_DESC *desc) +{ + struct d3d_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &state->desc, sizeof(*desc)); +} + +static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl = +{ + /* IUnknown methods */ + d3d10_depthstencil_state_QueryInterface, + d3d10_depthstencil_state_AddRef, + d3d10_depthstencil_state_Release, + /* ID3D10DeviceChild methods */ + d3d10_depthstencil_state_GetDevice, + d3d10_depthstencil_state_GetPrivateData, + d3d10_depthstencil_state_SetPrivateData, + d3d10_depthstencil_state_SetPrivateDataInterface, + /* ID3D10DepthStencilState methods */ + d3d10_depthstencil_state_GetDesc, +}; + +static HRESULT d3d_depthstencil_state_init(struct d3d_depthstencil_state *state, struct d3d_device *device, + const D3D11_DEPTH_STENCIL_DESC *desc) +{ + state->ID3D11DepthStencilState_iface.lpVtbl = &d3d11_depthstencil_state_vtbl; + state->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl; + state->refcount = 1; + wined3d_private_store_init(&state->private_store); + state->desc = *desc; + + ID3D11Device2_AddRef(state->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEPTH_STENCIL_DESC *desc, + struct d3d_depthstencil_state **state) +{ + struct d3d_depthstencil_state *object; + D3D11_DEPTH_STENCIL_DESC tmp_desc; + struct wine_rb_entry *entry; + HRESULT hr; + + if (!desc) + return E_INVALIDARG; + + /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use + * it as a key in the rbtree. */ + memset(&tmp_desc, 0, sizeof(tmp_desc)); + tmp_desc.DepthEnable = desc->DepthEnable; + if (desc->DepthEnable) + { + tmp_desc.DepthWriteMask = desc->DepthWriteMask; + tmp_desc.DepthFunc = desc->DepthFunc; + } + else + { + tmp_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + tmp_desc.DepthFunc = D3D11_COMPARISON_LESS; + } + tmp_desc.StencilEnable = desc->StencilEnable; + if (desc->StencilEnable) + { + tmp_desc.StencilReadMask = desc->StencilReadMask; + tmp_desc.StencilWriteMask = desc->StencilWriteMask; + tmp_desc.FrontFace = desc->FrontFace; + tmp_desc.BackFace = desc->BackFace; + } + else + { + tmp_desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + tmp_desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + tmp_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + tmp_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + tmp_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + tmp_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + tmp_desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + tmp_desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + tmp_desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + tmp_desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + } + + wined3d_mutex_lock(); + if ((entry = wine_rb_get(&device->depthstencil_states, &tmp_desc))) + { + object = WINE_RB_ENTRY_VALUE(entry, struct d3d_depthstencil_state, entry); + + TRACE("Returning existing depthstencil state %p.\n", object); + ID3D11DepthStencilState_AddRef(&object->ID3D11DepthStencilState_iface); + *state = object; + wined3d_mutex_unlock(); + + return S_OK; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = d3d_depthstencil_state_init(object, device, &tmp_desc))) + { + WARN("Failed to initialize depthstencil state, hr %#x.\n", hr); + heap_free(object); + wined3d_mutex_unlock(); + return hr; + } + + if (wine_rb_put(&device->depthstencil_states, &tmp_desc, &object->entry) == -1) + { + ERR("Failed to insert depthstencil state entry.\n"); + d3d_depthstencil_state_cleanup(object); + heap_free(object); + wined3d_mutex_unlock(); + return E_FAIL; + } + wined3d_mutex_unlock(); + + TRACE("Created depthstencil state %p.\n", object); + *state = object; + + return S_OK; +} + +struct d3d_depthstencil_state *unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_depthstencil_state_vtbl); + + return impl_from_ID3D11DepthStencilState(iface); +} + +struct d3d_depthstencil_state *unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_depthstencil_state_vtbl); + + return impl_from_ID3D10DepthStencilState(iface); +} + +/* ID3D11RasterizerState methods */ + +static inline struct d3d_rasterizer_state *impl_from_ID3D11RasterizerState(ID3D11RasterizerState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_rasterizer_state, ID3D11RasterizerState_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState *iface, + REFIID riid, void **object) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11RasterizerState) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11RasterizerState_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10RasterizerState) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10RasterizerState_AddRef(&state->ID3D10RasterizerState_iface); + *object = &state->ID3D10RasterizerState_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_rasterizer_state_AddRef(ID3D11RasterizerState *iface) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(state->device); + wined3d_mutex_lock(); + wined3d_rasterizer_state_incref(state->wined3d_state); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_rasterizer_state_Release(ID3D11RasterizerState *iface) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + ID3D11Device2 *device = state->device; + + wined3d_mutex_lock(); + wined3d_rasterizer_state_decref(state->wined3d_state); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState *iface, + ID3D11Device **device) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)state->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState *iface, + D3D11_RASTERIZER_DESC *desc) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D11RasterizerState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = state->desc; +} + +static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl = +{ + /* IUnknown methods */ + d3d11_rasterizer_state_QueryInterface, + d3d11_rasterizer_state_AddRef, + d3d11_rasterizer_state_Release, + /* ID3D11DeviceChild methods */ + d3d11_rasterizer_state_GetDevice, + d3d11_rasterizer_state_GetPrivateData, + d3d11_rasterizer_state_SetPrivateData, + d3d11_rasterizer_state_SetPrivateDataInterface, + /* ID3D11RasterizerState methods */ + d3d11_rasterizer_state_GetDesc, +}; + +/* ID3D10RasterizerState methods */ + +static inline struct d3d_rasterizer_state *impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_rasterizer_state, ID3D10RasterizerState_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState *iface, + REFIID riid, void **object) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_rasterizer_state_QueryInterface(&state->ID3D11RasterizerState_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_rasterizer_state_AddRef(ID3D10RasterizerState *iface) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_rasterizer_state_AddRef(&state->ID3D11RasterizerState_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_rasterizer_state_Release(ID3D10RasterizerState *iface) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p.\n", state); + + return d3d11_rasterizer_state_Release(&state->ID3D11RasterizerState_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState *iface, ID3D10Device **device) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(state->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +/* ID3D10RasterizerState methods */ + +static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState *iface, + D3D10_RASTERIZER_DESC *desc) +{ + struct d3d_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &state->desc, sizeof(*desc)); +} + +static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl = +{ + /* IUnknown methods */ + d3d10_rasterizer_state_QueryInterface, + d3d10_rasterizer_state_AddRef, + d3d10_rasterizer_state_Release, + /* ID3D10DeviceChild methods */ + d3d10_rasterizer_state_GetDevice, + d3d10_rasterizer_state_GetPrivateData, + d3d10_rasterizer_state_SetPrivateData, + d3d10_rasterizer_state_SetPrivateDataInterface, + /* ID3D10RasterizerState methods */ + d3d10_rasterizer_state_GetDesc, +}; + +static void STDMETHODCALLTYPE d3d_rasterizer_state_wined3d_object_destroyed(void *parent) +{ + struct d3d_rasterizer_state *state = parent; + struct d3d_device *device = impl_from_ID3D11Device2(state->device); + + wine_rb_remove(&device->rasterizer_states, &state->entry); + wined3d_private_store_cleanup(&state->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops = +{ + d3d_rasterizer_state_wined3d_object_destroyed, +}; + +static HRESULT d3d_rasterizer_state_init(struct d3d_rasterizer_state *state, struct d3d_device *device, + const D3D11_RASTERIZER_DESC *desc) +{ + struct wined3d_rasterizer_state_desc wined3d_desc; + HRESULT hr; + + state->ID3D11RasterizerState_iface.lpVtbl = &d3d11_rasterizer_state_vtbl; + state->ID3D10RasterizerState_iface.lpVtbl = &d3d10_rasterizer_state_vtbl; + state->refcount = 1; + wined3d_private_store_init(&state->private_store); + state->desc = *desc; + + if (wine_rb_put(&device->rasterizer_states, desc, &state->entry) == -1) + { + ERR("Failed to insert rasterizer state entry.\n"); + wined3d_private_store_cleanup(&state->private_store); + return E_FAIL; + } + + wined3d_desc.front_ccw = desc->FrontCounterClockwise; + wined3d_desc.depth_clip = desc->DepthClipEnable; + wined3d_desc.depth_bias_clamp = desc->DepthBiasClamp; + + /* We cannot fail after creating a wined3d_rasterizer_state object. It + * would lead to double free. */ + if (FAILED(hr = wined3d_rasterizer_state_create(device->wined3d_device, &wined3d_desc, + state, &d3d_rasterizer_state_wined3d_parent_ops, &state->wined3d_state))) + { + WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr); + wined3d_private_store_cleanup(&state->private_store); + wine_rb_remove(&device->rasterizer_states, &state->entry); + return hr; + } + + ID3D11Device2_AddRef(state->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_rasterizer_state_create(struct d3d_device *device, const D3D11_RASTERIZER_DESC *desc, + struct d3d_rasterizer_state **state) +{ + struct d3d_rasterizer_state *object; + struct wine_rb_entry *entry; + HRESULT hr; + + if (!desc) + return E_INVALIDARG; + + wined3d_mutex_lock(); + if ((entry = wine_rb_get(&device->rasterizer_states, desc))) + { + object = WINE_RB_ENTRY_VALUE(entry, struct d3d_rasterizer_state, entry); + + TRACE("Returning existing rasterizer state %p.\n", object); + ID3D11RasterizerState_AddRef(&object->ID3D11RasterizerState_iface); + *state = object; + wined3d_mutex_unlock(); + + return S_OK; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } + + hr = d3d_rasterizer_state_init(object, device, desc); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to initialize rasterizer state, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created rasterizer state %p.\n", object); + *state = object; + + return S_OK; +} + +struct d3d_rasterizer_state *unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_rasterizer_state_vtbl); + + return impl_from_ID3D11RasterizerState(iface); +} + +struct d3d_rasterizer_state *unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_rasterizer_state_vtbl); + + return impl_from_ID3D10RasterizerState(iface); +} + +/* ID3D11SampleState methods */ + +static inline struct d3d_sampler_state *impl_from_ID3D11SamplerState(ID3D11SamplerState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_sampler_state, ID3D11SamplerState_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_QueryInterface(ID3D11SamplerState *iface, + REFIID riid, void **object) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11SamplerState) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11SamplerState_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10SamplerState) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10SamplerState_AddRef(&state->ID3D10SamplerState_iface); + *object = &state->ID3D10SamplerState_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_sampler_state_AddRef(ID3D11SamplerState *iface) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(state->device); + wined3d_mutex_lock(); + wined3d_sampler_incref(state->wined3d_sampler); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_sampler_state_Release(ID3D11SamplerState *iface) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + ID3D11Device2 *device = state->device; + + wined3d_mutex_lock(); + wined3d_sampler_decref(state->wined3d_sampler); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_sampler_state_GetDevice(ID3D11SamplerState *iface, + ID3D11Device **device) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)state->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_GetPrivateData(ID3D11SamplerState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_SetPrivateData(ID3D11SamplerState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_sampler_state_GetDesc(ID3D11SamplerState *iface, + D3D11_SAMPLER_DESC *desc) +{ + struct d3d_sampler_state *state = impl_from_ID3D11SamplerState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = state->desc; +} + +static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl = +{ + /* IUnknown methods */ + d3d11_sampler_state_QueryInterface, + d3d11_sampler_state_AddRef, + d3d11_sampler_state_Release, + /* ID3D11DeviceChild methods */ + d3d11_sampler_state_GetDevice, + d3d11_sampler_state_GetPrivateData, + d3d11_sampler_state_SetPrivateData, + d3d11_sampler_state_SetPrivateDataInterface, + /* ID3D11SamplerState methods */ + d3d11_sampler_state_GetDesc, +}; + +/* ID3D10SamplerState methods */ + +static inline struct d3d_sampler_state *impl_from_ID3D10SamplerState(ID3D10SamplerState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_sampler_state, ID3D10SamplerState_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_QueryInterface(ID3D10SamplerState *iface, + REFIID riid, void **object) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_sampler_state_QueryInterface(&state->ID3D11SamplerState_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_sampler_state_AddRef(ID3D10SamplerState *iface) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_sampler_state_AddRef(&state->ID3D11SamplerState_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_sampler_state_Release(ID3D10SamplerState *iface) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_sampler_state_Release(&state->ID3D11SamplerState_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_sampler_state_GetDevice(ID3D10SamplerState *iface, ID3D10Device **device) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(state->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_GetPrivateData(ID3D10SamplerState *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateData(ID3D10SamplerState *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +/* ID3D10SamplerState methods */ + +static void STDMETHODCALLTYPE d3d10_sampler_state_GetDesc(ID3D10SamplerState *iface, + D3D10_SAMPLER_DESC *desc) +{ + struct d3d_sampler_state *state = impl_from_ID3D10SamplerState(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &state->desc, sizeof(*desc)); +} + +static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl = +{ + /* IUnknown methods */ + d3d10_sampler_state_QueryInterface, + d3d10_sampler_state_AddRef, + d3d10_sampler_state_Release, + /* ID3D10DeviceChild methods */ + d3d10_sampler_state_GetDevice, + d3d10_sampler_state_GetPrivateData, + d3d10_sampler_state_SetPrivateData, + d3d10_sampler_state_SetPrivateDataInterface, + /* ID3D10SamplerState methods */ + d3d10_sampler_state_GetDesc, +}; + +static void STDMETHODCALLTYPE d3d_sampler_wined3d_object_destroyed(void *parent) +{ + struct d3d_sampler_state *state = parent; + struct d3d_device *device = impl_from_ID3D11Device2(state->device); + + wine_rb_remove(&device->sampler_states, &state->entry); + wined3d_private_store_cleanup(&state->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops = +{ + d3d_sampler_wined3d_object_destroyed, +}; + +static enum wined3d_texture_address wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t) +{ + return (enum wined3d_texture_address)t; +} + +static enum wined3d_texture_filter_type wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f) +{ + if (D3D11_DECODE_MIP_FILTER(f) == D3D11_FILTER_TYPE_LINEAR) + return WINED3D_TEXF_LINEAR; + return WINED3D_TEXF_POINT; +} + +static enum wined3d_texture_filter_type wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f) +{ + if (D3D11_DECODE_MAG_FILTER(f) == D3D11_FILTER_TYPE_LINEAR) + return WINED3D_TEXF_LINEAR; + return WINED3D_TEXF_POINT; +} + +static enum wined3d_texture_filter_type wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f) +{ + if (D3D11_DECODE_MIN_FILTER(f) == D3D11_FILTER_TYPE_LINEAR) + return WINED3D_TEXF_LINEAR; + return WINED3D_TEXF_POINT; +} + +static BOOL wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f) +{ + return D3D11_DECODE_IS_COMPARISON_FILTER(f); +} + +static enum wined3d_cmp_func wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f) +{ + return (enum wined3d_cmp_func)f; +} + +static HRESULT d3d_sampler_state_init(struct d3d_sampler_state *state, struct d3d_device *device, + const D3D11_SAMPLER_DESC *desc) +{ + struct wined3d_sampler_desc wined3d_desc; + HRESULT hr; + + state->ID3D11SamplerState_iface.lpVtbl = &d3d11_sampler_state_vtbl; + state->ID3D10SamplerState_iface.lpVtbl = &d3d10_sampler_state_vtbl; + state->refcount = 1; + wined3d_private_store_init(&state->private_store); + state->desc = *desc; + + wined3d_desc.address_u = wined3d_texture_address_from_d3d11(desc->AddressU); + wined3d_desc.address_v = wined3d_texture_address_from_d3d11(desc->AddressV); + wined3d_desc.address_w = wined3d_texture_address_from_d3d11(desc->AddressW); + memcpy(wined3d_desc.border_color, desc->BorderColor, sizeof(wined3d_desc.border_color)); + wined3d_desc.mag_filter = wined3d_texture_filter_mag_from_d3d11(desc->Filter); + wined3d_desc.min_filter = wined3d_texture_filter_min_from_d3d11(desc->Filter); + wined3d_desc.mip_filter = wined3d_texture_filter_mip_from_d3d11(desc->Filter); + wined3d_desc.lod_bias = desc->MipLODBias; + wined3d_desc.min_lod = desc->MinLOD; + wined3d_desc.max_lod = desc->MaxLOD; + wined3d_desc.mip_base_level = 0; + wined3d_desc.max_anisotropy = D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc->Filter) ? desc->MaxAnisotropy : 1; + wined3d_desc.compare = wined3d_texture_compare_from_d3d11(desc->Filter); + wined3d_desc.comparison_func = wined3d_cmp_func_from_d3d11(desc->ComparisonFunc); + wined3d_desc.srgb_decode = TRUE; + + if (wine_rb_put(&device->sampler_states, desc, &state->entry) == -1) + { + ERR("Failed to insert sampler state entry.\n"); + wined3d_private_store_cleanup(&state->private_store); + return E_FAIL; + } + + /* We cannot fail after creating a wined3d_sampler object. It would lead to + * double free. */ + if (FAILED(hr = wined3d_sampler_create(device->wined3d_device, &wined3d_desc, + state, &d3d_sampler_wined3d_parent_ops, &state->wined3d_sampler))) + { + WARN("Failed to create wined3d sampler, hr %#x.\n", hr); + wined3d_private_store_cleanup(&state->private_store); + wine_rb_remove(&device->sampler_states, &state->entry); + return hr; + } + + ID3D11Device2_AddRef(state->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_sampler_state_create(struct d3d_device *device, const D3D11_SAMPLER_DESC *desc, + struct d3d_sampler_state **state) +{ + D3D11_SAMPLER_DESC normalized_desc; + struct d3d_sampler_state *object; + struct wine_rb_entry *entry; + HRESULT hr; + + if (!desc) + return E_INVALIDARG; + + normalized_desc = *desc; + if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc.Filter)) + normalized_desc.MaxAnisotropy = 0; + if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc.Filter)) + normalized_desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + if (normalized_desc.AddressU != D3D11_TEXTURE_ADDRESS_BORDER + && normalized_desc.AddressV != D3D11_TEXTURE_ADDRESS_BORDER + && normalized_desc.AddressW != D3D11_TEXTURE_ADDRESS_BORDER) + memset(&normalized_desc.BorderColor, 0, sizeof(normalized_desc.BorderColor)); + + wined3d_mutex_lock(); + if ((entry = wine_rb_get(&device->sampler_states, &normalized_desc))) + { + object = WINE_RB_ENTRY_VALUE(entry, struct d3d_sampler_state, entry); + + TRACE("Returning existing sampler state %p.\n", object); + ID3D11SamplerState_AddRef(&object->ID3D11SamplerState_iface); + *state = object; + wined3d_mutex_unlock(); + + return S_OK; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } + + hr = d3d_sampler_state_init(object, device, &normalized_desc); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to initialize sampler state, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created sampler state %p.\n", object); + *state = object; + + return S_OK; +} + +struct d3d_sampler_state *unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_sampler_state_vtbl); + + return impl_from_ID3D11SamplerState(iface); +} + +struct d3d_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_sampler_state_vtbl); + + return impl_from_ID3D10SamplerState(iface); +} diff --git a/dll/directx/wine/d3d11/texture.c b/dll/directx/wine/d3d11/texture.c new file mode 100644 index 00000000000..d54f22f35c9 --- /dev/null +++ b/dll/directx/wine/d3d11/texture.c @@ -0,0 +1,1522 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2015 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +/* ID3D11Texture1D methods */ + +static inline struct d3d_texture1d *impl_from_ID3D11Texture1D(ID3D11Texture1D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D11Texture1D_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_QueryInterface(ID3D11Texture1D *iface, REFIID iid, void **out) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID3D11Texture1D) + || IsEqualGUID(iid, &IID_ID3D11Resource) + || IsEqualGUID(iid, &IID_ID3D11DeviceChild) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + IUnknown_AddRef(iface); + return S_OK; + } + + if (IsEqualGUID(iid, &IID_ID3D10Texture1D) + || IsEqualGUID(iid, &IID_ID3D10Resource) + || IsEqualGUID(iid, &IID_ID3D10DeviceChild)) + { + *out = &texture->ID3D10Texture1D_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + if (texture->dxgi_surface) + { + TRACE("Forwarding to dxgi surface.\n"); + return IUnknown_QueryInterface(texture->dxgi_surface, iid, out); + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture1d_AddRef(ID3D11Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + ULONG refcount = InterlockedIncrement(&texture->refcount); + + TRACE("%p increasing refcount to %u.\n", texture, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(texture->device); + wined3d_mutex_lock(); + wined3d_texture_incref(texture->wined3d_texture); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture1d_Release(ID3D11Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + ULONG refcount = InterlockedDecrement(&texture->refcount); + + TRACE("%p decreasing refcount to %u.\n", texture, refcount); + + if (!refcount) + { + ID3D11Device2 *device = texture->device; + + wined3d_mutex_lock(); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_texture1d_GetDevice(ID3D11Texture1D *iface, ID3D11Device **device) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)texture->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_GetPrivateData(ID3D11Texture1D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + IDXGISurface *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + if (texture->dxgi_surface + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + return d3d_get_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateData(ID3D11Texture1D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + IDXGISurface *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + if (texture->dxgi_surface + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + return d3d_set_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateDataInterface(ID3D11Texture1D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + IDXGISurface *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + if (texture->dxgi_surface + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + return d3d_set_private_data_interface(&texture->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_texture1d_GetType(ID3D11Texture1D *iface, + D3D11_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension); + + *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D; +} + +static void STDMETHODCALLTYPE d3d11_texture1d_SetEvictionPriority(ID3D11Texture1D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d11_texture1d_GetEvictionPriority(ID3D11Texture1D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d3d11_texture1d_GetDesc(ID3D11Texture1D *iface, D3D11_TEXTURE1D_DESC *desc) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = texture->desc; +} + +static const struct ID3D11Texture1DVtbl d3d11_texture1d_vtbl = +{ + /* IUnknown methods */ + d3d11_texture1d_QueryInterface, + d3d11_texture1d_AddRef, + d3d11_texture1d_Release, + /* ID3D11DeviceChild methods */ + d3d11_texture1d_GetDevice, + d3d11_texture1d_GetPrivateData, + d3d11_texture1d_SetPrivateData, + d3d11_texture1d_SetPrivateDataInterface, + /* ID3D11Resource methods */ + d3d11_texture1d_GetType, + d3d11_texture1d_SetEvictionPriority, + d3d11_texture1d_GetEvictionPriority, + /* ID3D11Texture1D methods */ + d3d11_texture1d_GetDesc, +}; + +struct d3d_texture1d *unsafe_impl_from_ID3D11Texture1D(ID3D11Texture1D *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_texture1d_vtbl); + return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D11Texture1D_iface); +} + +static inline struct d3d_texture1d *impl_from_ID3D10Texture1D(ID3D10Texture1D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_QueryInterface(ID3D10Texture1D *iface, REFIID iid, void **out) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return d3d11_texture1d_QueryInterface(&texture->ID3D11Texture1D_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture1d_AddRef(ID3D10Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture1d_AddRef(&texture->ID3D11Texture1D_iface); +} + +static void STDMETHODCALLTYPE d3d_texture1d_wined3d_object_released(void *parent) +{ + struct d3d_texture1d *texture = parent; + + if (texture->dxgi_surface) + IUnknown_Release(texture->dxgi_surface); + wined3d_private_store_cleanup(&texture->private_store); + heap_free(texture); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture1d_Release(ID3D10Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture1d_Release(&texture->ID3D11Texture1D_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_texture1d_GetDevice(ID3D10Texture1D *iface, ID3D10Device **device) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_GetPrivateData(ID3D10Texture1D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_texture1d_GetPrivateData(&texture->ID3D11Texture1D_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_SetPrivateData(ID3D10Texture1D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_texture1d_SetPrivateData(&texture->ID3D11Texture1D_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_SetPrivateDataInterface(ID3D10Texture1D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d11_texture1d_SetPrivateDataInterface(&texture->ID3D11Texture1D_iface, guid, data); +} + +/* ID3D10Resource methods */ + +static void STDMETHODCALLTYPE d3d10_texture1d_GetType(ID3D10Texture1D *iface, + D3D10_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p\n", iface, resource_dimension); + + *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE1D; +} + +static void STDMETHODCALLTYPE d3d10_texture1d_SetEvictionPriority(ID3D10Texture1D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d10_texture1d_GetEvictionPriority(ID3D10Texture1D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +/* ID3D10Texture1D methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_Map(ID3D10Texture1D *iface, UINT sub_resource_idx, + D3D10_MAP map_type, UINT map_flags, void **data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + struct wined3d_map_desc wined3d_map_desc; + HRESULT hr; + + TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, data %p.\n", + iface, sub_resource_idx, map_type, map_flags, data); + + if (map_flags) + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_mutex_lock(); + if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, + &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) + { + *data = wined3d_map_desc.data; + } + wined3d_mutex_unlock(); + + return hr; +} + +static void STDMETHODCALLTYPE d3d10_texture1d_Unmap(ID3D10Texture1D *iface, UINT sub_resource_idx) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); + + wined3d_mutex_lock(); + wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_texture1d_GetDesc(ID3D10Texture1D *iface, D3D10_TEXTURE1D_DESC *desc) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + D3D11_TEXTURE1D_DESC d3d11_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + d3d11_texture1d_GetDesc(&texture->ID3D11Texture1D_iface, &d3d11_desc); + + desc->Width = d3d11_desc.Width; + desc->MipLevels = d3d11_desc.MipLevels; + desc->ArraySize = d3d11_desc.ArraySize; + desc->Format = d3d11_desc.Format; + desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc.Usage); + desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc.BindFlags); + desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc.CPUAccessFlags); + desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc.MiscFlags); +} + +static const struct ID3D10Texture1DVtbl d3d10_texture1d_vtbl = +{ + /* IUnknown methods */ + d3d10_texture1d_QueryInterface, + d3d10_texture1d_AddRef, + d3d10_texture1d_Release, + /* ID3D10DeviceChild methods */ + d3d10_texture1d_GetDevice, + d3d10_texture1d_GetPrivateData, + d3d10_texture1d_SetPrivateData, + d3d10_texture1d_SetPrivateDataInterface, + /* ID3D10Resource methods */ + d3d10_texture1d_GetType, + d3d10_texture1d_SetEvictionPriority, + d3d10_texture1d_GetEvictionPriority, + /* ID3D10Texture1D methods */ + d3d10_texture1d_Map, + d3d10_texture1d_Unmap, + d3d10_texture1d_GetDesc, +}; + +struct d3d_texture1d *unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_texture1d_vtbl); + return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface); +} + +static const struct wined3d_parent_ops d3d_texture1d_wined3d_parent_ops = +{ + d3d_texture1d_wined3d_object_released, +}; + +HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **out) +{ + struct wined3d_resource_desc wined3d_desc; + struct d3d_texture1d *texture; + unsigned int levels; + DWORD flags = 0; + HRESULT hr; + + if (!(texture = heap_alloc_zero(sizeof(*texture)))) + return E_OUTOFMEMORY; + + texture->ID3D11Texture1D_iface.lpVtbl = &d3d11_texture1d_vtbl; + texture->ID3D10Texture1D_iface.lpVtbl = &d3d10_texture1d_vtbl; + texture->refcount = 1; + wined3d_private_store_init(&texture->private_store); + texture->desc = *desc; + levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(desc->Width) + 1; + texture->desc.MipLevels = levels; + + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_1D; + wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); + wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + wined3d_desc.multisample_quality = 0; + wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage); + wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags); + wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage, + desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags); + wined3d_desc.width = desc->Width; + wined3d_desc.height = 1; + wined3d_desc.depth = 1; + wined3d_desc.size = 0; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, + desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data, + texture, &d3d_texture1d_wined3d_parent_ops, &texture->wined3d_texture))) + { + WARN("Failed to create wined3d texture, hr %#x.\n", hr); + wined3d_private_store_cleanup(&texture->private_store); + heap_free(texture); + wined3d_mutex_unlock(); + if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL) + hr = E_INVALIDARG; + return hr; + } + + if (desc->MipLevels == 1 && desc->ArraySize == 1) + { + IWineDXGIDevice *wine_device; + + if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, + (void **)&wine_device))) + { + ERR("Device should implement IWineDXGIDevice.\n"); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return E_FAIL; + } + + hr = IWineDXGIDevice_create_surface(wine_device, texture->wined3d_texture, 0, NULL, + (IUnknown *)&texture->ID3D10Texture1D_iface, (void **)&texture->dxgi_surface); + IWineDXGIDevice_Release(wine_device); + if (FAILED(hr)) + { + ERR("Failed to create DXGI surface, returning %#.x\n", hr); + texture->dxgi_surface = NULL; + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return hr; + } + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(texture->device = &device->ID3D11Device2_iface); + + TRACE("Created texture %p.\n", texture); + *out = texture; + + return S_OK; +} + +/* ID3D11Texture2D methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D *iface, REFIID riid, void **object) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11Texture2D) + || IsEqualGUID(riid, &IID_ID3D11Resource) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + *object = &texture->ID3D11Texture2D_iface; + IUnknown_AddRef((IUnknown *)*object); + return S_OK; + } + else if (IsEqualGUID(riid, &IID_ID3D10Texture2D) + || IsEqualGUID(riid, &IID_ID3D10Resource) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + *object = &texture->ID3D10Texture2D_iface; + IUnknown_AddRef((IUnknown *)*object); + return S_OK; + } + + if (texture->dxgi_surface) + { + TRACE("Forwarding to dxgi surface.\n"); + return IUnknown_QueryInterface(texture->dxgi_surface, riid, object); + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture2d_AddRef(ID3D11Texture2D *iface) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + ULONG refcount = InterlockedIncrement(&texture->refcount); + + TRACE("%p increasing refcount to %u.\n", texture, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(texture->device); + wined3d_mutex_lock(); + wined3d_texture_incref(texture->wined3d_texture); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture2d_Release(ID3D11Texture2D *iface) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + ULONG refcount = InterlockedDecrement(&texture->refcount); + + TRACE("%p decreasing refcount to %u.\n", texture, refcount); + + if (!refcount) + { + ID3D11Device2 *device = texture->device; + + wined3d_mutex_lock(); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_texture2d_GetDevice(ID3D11Texture2D *iface, ID3D11Device **device) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)texture->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + IDXGISurface *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + if (texture->dxgi_surface + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + return d3d_get_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + IDXGISurface *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + if (texture->dxgi_surface + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + return d3d_set_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11Texture2D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + IDXGISurface *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + if (texture->dxgi_surface + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + return d3d_set_private_data_interface(&texture->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_texture2d_GetType(ID3D11Texture2D *iface, + D3D11_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension); + + *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; +} + +static void STDMETHODCALLTYPE d3d11_texture2d_SetEvictionPriority(ID3D11Texture2D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d11_texture2d_GetEvictionPriority(ID3D11Texture2D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(ID3D11Texture2D *iface, D3D11_TEXTURE2D_DESC *desc) +{ + struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); + struct wined3d_resource_desc wined3d_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = texture->desc; + + wined3d_mutex_lock(); + wined3d_resource_get_desc(wined3d_texture_get_resource(texture->wined3d_texture), &wined3d_desc); + wined3d_mutex_unlock(); + + /* FIXME: Resizing swapchain buffers can cause these to change. We'd like + * to get everything from wined3d, but e.g. bind flags don't exist as such + * there (yet). */ + desc->Width = wined3d_desc.width; + desc->Height = wined3d_desc.height; + desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format); + desc->SampleDesc.Count = wined3d_desc.multisample_type == WINED3D_MULTISAMPLE_NONE + ? 1 : wined3d_desc.multisample_type; + desc->SampleDesc.Quality = wined3d_desc.multisample_quality; +} + +static const struct ID3D11Texture2DVtbl d3d11_texture2d_vtbl = +{ + /* IUnknown methods */ + d3d11_texture2d_QueryInterface, + d3d11_texture2d_AddRef, + d3d11_texture2d_Release, + /* ID3D11DeviceChild methods */ + d3d11_texture2d_GetDevice, + d3d11_texture2d_GetPrivateData, + d3d11_texture2d_SetPrivateData, + d3d11_texture2d_SetPrivateDataInterface, + /* ID3D11Resource methods */ + d3d11_texture2d_GetType, + d3d11_texture2d_SetEvictionPriority, + d3d11_texture2d_GetEvictionPriority, + /* ID3D11Texture2D methods */ + d3d11_texture2d_GetDesc, +}; + +struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_texture2d_vtbl); + return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D11Texture2D_iface); +} + +/* IUnknown methods */ + +static inline struct d3d_texture2d *impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D10Texture2D_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture2d_QueryInterface(ID3D10Texture2D *iface, REFIID riid, void **object) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_texture2d_QueryInterface(&texture->ID3D11Texture2D_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture2d_AddRef(ID3D10Texture2D *iface) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture2d_AddRef(&texture->ID3D11Texture2D_iface); +} + +static void STDMETHODCALLTYPE d3d_texture2d_wined3d_object_released(void *parent) +{ + struct d3d_texture2d *texture = parent; + + if (texture->dxgi_surface) IUnknown_Release(texture->dxgi_surface); + wined3d_private_store_cleanup(&texture->private_store); + heap_free(texture); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture2d_Release(&texture->ID3D11Texture2D_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_texture2d_GetDevice(ID3D10Texture2D *iface, ID3D10Device **device) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture2d_GetPrivateData(ID3D10Texture2D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_texture2d_GetPrivateData(&texture->ID3D11Texture2D_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture2d_SetPrivateData(ID3D10Texture2D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_texture2d_SetPrivateData(&texture->ID3D11Texture2D_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture2d_SetPrivateDataInterface(ID3D10Texture2D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d11_texture2d_SetPrivateDataInterface(&texture->ID3D11Texture2D_iface, guid, data); +} + +/* ID3D10Resource methods */ + +static void STDMETHODCALLTYPE d3d10_texture2d_GetType(ID3D10Texture2D *iface, + D3D10_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p\n", iface, resource_dimension); + + *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; +} + +static void STDMETHODCALLTYPE d3d10_texture2d_SetEvictionPriority(ID3D10Texture2D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d10_texture2d_GetEvictionPriority(ID3D10Texture2D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +/* ID3D10Texture2D methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_texture2d_Map(ID3D10Texture2D *iface, UINT sub_resource_idx, + D3D10_MAP map_type, UINT map_flags, D3D10_MAPPED_TEXTURE2D *mapped_texture) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + struct wined3d_map_desc wined3d_map_desc; + HRESULT hr; + + TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n", + iface, sub_resource_idx, map_type, map_flags, mapped_texture); + + if (map_flags) + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_mutex_lock(); + if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, + &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) + { + mapped_texture->pData = wined3d_map_desc.data; + mapped_texture->RowPitch = wined3d_map_desc.row_pitch; + } + wined3d_mutex_unlock(); + + return hr; +} + +static void STDMETHODCALLTYPE d3d10_texture2d_Unmap(ID3D10Texture2D *iface, UINT sub_resource_idx) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + + TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); + + wined3d_mutex_lock(); + wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_texture2d_GetDesc(ID3D10Texture2D *iface, D3D10_TEXTURE2D_DESC *desc) +{ + struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface); + D3D11_TEXTURE2D_DESC d3d11_desc; + + TRACE("iface %p, desc %p\n", iface, desc); + + d3d11_texture2d_GetDesc(&texture->ID3D11Texture2D_iface, &d3d11_desc); + + desc->Width = d3d11_desc.Width; + desc->Height = d3d11_desc.Height; + desc->MipLevels = d3d11_desc.MipLevels; + desc->ArraySize = d3d11_desc.ArraySize; + desc->Format = d3d11_desc.Format; + desc->SampleDesc = d3d11_desc.SampleDesc; + desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc.Usage); + desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc.BindFlags); + desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc.CPUAccessFlags); + desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc.MiscFlags); +} + +static const struct ID3D10Texture2DVtbl d3d10_texture2d_vtbl = +{ + /* IUnknown methods */ + d3d10_texture2d_QueryInterface, + d3d10_texture2d_AddRef, + d3d10_texture2d_Release, + /* ID3D10DeviceChild methods */ + d3d10_texture2d_GetDevice, + d3d10_texture2d_GetPrivateData, + d3d10_texture2d_SetPrivateData, + d3d10_texture2d_SetPrivateDataInterface, + /* ID3D10Resource methods */ + d3d10_texture2d_GetType, + d3d10_texture2d_SetEvictionPriority, + d3d10_texture2d_GetEvictionPriority, + /* ID3D10Texture2D methods */ + d3d10_texture2d_Map, + d3d10_texture2d_Unmap, + d3d10_texture2d_GetDesc, +}; + +struct d3d_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_texture2d_vtbl); + return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D10Texture2D_iface); +} + +static const struct wined3d_parent_ops d3d_texture2d_wined3d_parent_ops = +{ + d3d_texture2d_wined3d_object_released, +}; + +static BOOL is_gdi_compatible_texture(const D3D11_TEXTURE2D_DESC *desc) +{ + if (!(desc->Format == DXGI_FORMAT_B8G8R8A8_UNORM + || desc->Format == DXGI_FORMAT_B8G8R8A8_TYPELESS + || desc->Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)) + return FALSE; + + if (desc->Usage != D3D11_USAGE_DEFAULT) + return FALSE; + + return TRUE; +} + +static BOOL validate_texture2d_desc(const D3D11_TEXTURE2D_DESC *desc, D3D_FEATURE_LEVEL feature_level) +{ + if (!validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION_TEXTURE2D, + desc->Usage, desc->BindFlags, desc->CPUAccessFlags, feature_level)) + return FALSE; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE + && desc->ArraySize < 6) + { + WARN("Invalid array size %u for cube texture.\n", desc->ArraySize); + return FALSE; + } + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE + && !is_gdi_compatible_texture(desc)) + { + WARN("Incompatible description used to create GDI compatible texture.\n"); + return FALSE; + } + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS + && (~desc->BindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE))) + { + WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET and " + "D3D11_BIND_SHADER_RESOURCE.\n"); + return FALSE; + } + + return TRUE; +} + +HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out) +{ + struct wined3d_resource_desc wined3d_desc; + struct d3d_texture2d *texture; + unsigned int levels; + DWORD flags = 0; + HRESULT hr; + + if (!validate_texture2d_desc(desc, device->feature_level)) + { + WARN("Failed to validate texture desc.\n"); + return E_INVALIDARG; + } + + if (!(texture = heap_alloc_zero(sizeof(*texture)))) + return E_OUTOFMEMORY; + + texture->ID3D11Texture2D_iface.lpVtbl = &d3d11_texture2d_vtbl; + texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; + texture->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&texture->private_store); + texture->desc = *desc; + + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); + wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; + wined3d_desc.multisample_quality = desc->SampleDesc.Quality; + wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage); + wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags); + wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage, + desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags); + wined3d_desc.width = desc->Width; + wined3d_desc.height = desc->Height; + wined3d_desc.depth = 1; + wined3d_desc.size = 0; + + levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, + desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data, + texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) + { + WARN("Failed to create wined3d texture, hr %#x.\n", hr); + wined3d_private_store_cleanup(&texture->private_store); + heap_free(texture); + wined3d_mutex_unlock(); + if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL) + hr = E_INVALIDARG; + return hr; + } + texture->desc.MipLevels = levels; + + if (desc->MipLevels == 1 && desc->ArraySize == 1) + { + IWineDXGIDevice *wine_device; + + if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, + (void **)&wine_device))) + { + ERR("Device should implement IWineDXGIDevice.\n"); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return E_FAIL; + } + + hr = IWineDXGIDevice_create_surface(wine_device, texture->wined3d_texture, 0, NULL, + (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); + IWineDXGIDevice_Release(wine_device); + if (FAILED(hr)) + { + ERR("Failed to create DXGI surface, returning %#.x\n", hr); + texture->dxgi_surface = NULL; + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return hr; + } + } + wined3d_mutex_unlock(); + + ID3D11Device2_AddRef(texture->device = &device->ID3D11Device2_iface); + + TRACE("Created texture %p.\n", texture); + *out = texture; + + return S_OK; +} + +/* ID3D11Texture3D methods */ + +static inline struct d3d_texture3d *impl_from_ID3D11Texture3D(ID3D11Texture3D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture3d, ID3D11Texture3D_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture3d_QueryInterface(ID3D11Texture3D *iface, REFIID riid, void **object) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11Texture3D) + || IsEqualGUID(riid, &IID_ID3D11Resource) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + else if (IsEqualGUID(riid, &IID_ID3D10Texture3D) + || IsEqualGUID(riid, &IID_ID3D10Resource) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + IUnknown_AddRef(iface); + *object = &texture->ID3D10Texture3D_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture3d_AddRef(ID3D11Texture3D *iface) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + ULONG refcount = InterlockedIncrement(&texture->refcount); + + TRACE("%p increasing refcount to %u.\n", texture, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(texture->device); + wined3d_mutex_lock(); + wined3d_texture_incref(texture->wined3d_texture); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d_texture3d_wined3d_object_released(void *parent) +{ + struct d3d_texture3d *texture = parent; + + wined3d_private_store_cleanup(&texture->private_store); + heap_free(parent); +} + +static ULONG STDMETHODCALLTYPE d3d11_texture3d_Release(ID3D11Texture3D *iface) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + ULONG refcount = InterlockedDecrement(&texture->refcount); + + TRACE("%p decreasing refcount to %u.\n", texture, refcount); + + if (!refcount) + { + ID3D11Device2 *device = texture->device; + + wined3d_mutex_lock(); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + /* Release the device last, it may cause the wined3d device to be + * destroyed. */ + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_texture3d_GetDevice(ID3D11Texture3D *iface, ID3D11Device **device) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)texture->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture3d_GetPrivateData(ID3D11Texture3D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture3d_SetPrivateData(ID3D11Texture3D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture3d_SetPrivateDataInterface(ID3D11Texture3D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&texture->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_texture3d_GetType(ID3D11Texture3D *iface, + D3D11_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension); + + *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE3D; +} + +static void STDMETHODCALLTYPE d3d11_texture3d_SetEvictionPriority(ID3D11Texture3D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d11_texture3d_GetEvictionPriority(ID3D11Texture3D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d3d11_texture3d_GetDesc(ID3D11Texture3D *iface, D3D11_TEXTURE3D_DESC *desc) +{ + struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = texture->desc; +} + +static const struct ID3D11Texture3DVtbl d3d11_texture3d_vtbl = +{ + /* IUnknown methods */ + d3d11_texture3d_QueryInterface, + d3d11_texture3d_AddRef, + d3d11_texture3d_Release, + /* ID3D11DeviceChild methods */ + d3d11_texture3d_GetDevice, + d3d11_texture3d_GetPrivateData, + d3d11_texture3d_SetPrivateData, + d3d11_texture3d_SetPrivateDataInterface, + /* ID3D11Resource methods */ + d3d11_texture3d_GetType, + d3d11_texture3d_SetEvictionPriority, + d3d11_texture3d_GetEvictionPriority, + /* ID3D11Texture3D methods */ + d3d11_texture3d_GetDesc, +}; + +/* ID3D10Texture3D methods */ + +static inline struct d3d_texture3d *impl_from_ID3D10Texture3D(ID3D10Texture3D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture3d, ID3D10Texture3D_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture3d_QueryInterface(ID3D10Texture3D *iface, REFIID riid, void **object) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_texture3d_QueryInterface(&texture->ID3D11Texture3D_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture3d_AddRef(ID3D10Texture3D *iface) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture3d_AddRef(&texture->ID3D11Texture3D_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture3d_Release(ID3D10Texture3D *iface) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture3d_Release(&texture->ID3D11Texture3D_iface); +} + +static void STDMETHODCALLTYPE d3d10_texture3d_GetDevice(ID3D10Texture3D *iface, ID3D10Device **device) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture3d_GetPrivateData(ID3D10Texture3D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateData(ID3D10Texture3D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateDataInterface(ID3D10Texture3D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&texture->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d10_texture3d_GetType(ID3D10Texture3D *iface, + D3D10_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension); + + *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; +} + +static void STDMETHODCALLTYPE d3d10_texture3d_SetEvictionPriority(ID3D10Texture3D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d10_texture3d_GetEvictionPriority(ID3D10Texture3D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture3d_Map(ID3D10Texture3D *iface, UINT sub_resource_idx, + D3D10_MAP map_type, UINT map_flags, D3D10_MAPPED_TEXTURE3D *mapped_texture) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + struct wined3d_map_desc wined3d_map_desc; + HRESULT hr; + + TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n", + iface, sub_resource_idx, map_type, map_flags, mapped_texture); + + if (map_flags) + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_mutex_lock(); + if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, + &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) + { + mapped_texture->pData = wined3d_map_desc.data; + mapped_texture->RowPitch = wined3d_map_desc.row_pitch; + mapped_texture->DepthPitch = wined3d_map_desc.slice_pitch; + } + wined3d_mutex_unlock(); + + return hr; +} + +static void STDMETHODCALLTYPE d3d10_texture3d_Unmap(ID3D10Texture3D *iface, UINT sub_resource_idx) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + + TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); + + wined3d_mutex_lock(); + wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); + wined3d_mutex_unlock(); +} + +static void STDMETHODCALLTYPE d3d10_texture3d_GetDesc(ID3D10Texture3D *iface, D3D10_TEXTURE3D_DESC *desc) +{ + struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface); + D3D11_TEXTURE3D_DESC d3d11_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + d3d11_texture3d_GetDesc(&texture->ID3D11Texture3D_iface, &d3d11_desc); + + desc->Width = d3d11_desc.Width; + desc->Height = d3d11_desc.Height; + desc->Depth = d3d11_desc.Depth; + desc->MipLevels = d3d11_desc.MipLevels; + desc->Format = d3d11_desc.Format; + desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc.Usage); + desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc.BindFlags); + desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc.CPUAccessFlags); + desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc.MiscFlags); +} + +static const struct ID3D10Texture3DVtbl d3d10_texture3d_vtbl = +{ + /* IUnknown methods */ + d3d10_texture3d_QueryInterface, + d3d10_texture3d_AddRef, + d3d10_texture3d_Release, + /* ID3D10DeviceChild methods */ + d3d10_texture3d_GetDevice, + d3d10_texture3d_GetPrivateData, + d3d10_texture3d_SetPrivateData, + d3d10_texture3d_SetPrivateDataInterface, + /* ID3D10Resource methods */ + d3d10_texture3d_GetType, + d3d10_texture3d_SetEvictionPriority, + d3d10_texture3d_GetEvictionPriority, + /* ID3D10Texture3D methods */ + d3d10_texture3d_Map, + d3d10_texture3d_Unmap, + d3d10_texture3d_GetDesc, +}; + +struct d3d_texture3d *unsafe_impl_from_ID3D10Texture3D(ID3D10Texture3D *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_texture3d_vtbl); + return CONTAINING_RECORD(iface, struct d3d_texture3d, ID3D10Texture3D_iface); +} + +struct d3d_texture3d *unsafe_impl_from_ID3D11Texture3D(ID3D11Texture3D *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_texture3d_vtbl); + return impl_from_ID3D11Texture3D(iface); +} + +static const struct wined3d_parent_ops d3d_texture3d_wined3d_parent_ops = +{ + d3d_texture3d_wined3d_object_released, +}; + +static HRESULT d3d_texture3d_init(struct d3d_texture3d *texture, struct d3d_device *device, + const D3D11_TEXTURE3D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data) +{ + struct wined3d_resource_desc wined3d_desc; + unsigned int levels; + DWORD flags = 0; + HRESULT hr; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS + && (~desc->BindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE))) + { + WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET " + "and D3D11_BIND_SHADER_RESOURCE.\n"); + return E_INVALIDARG; + } + + texture->ID3D11Texture3D_iface.lpVtbl = &d3d11_texture3d_vtbl; + texture->ID3D10Texture3D_iface.lpVtbl = &d3d10_texture3d_vtbl; + texture->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&texture->private_store); + texture->desc = *desc; + + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; + wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); + wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + wined3d_desc.multisample_quality = 0; + wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage); + wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags); + wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage, + desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags); + wined3d_desc.width = desc->Width; + wined3d_desc.height = desc->Height; + wined3d_desc.depth = desc->Depth; + wined3d_desc.size = 0; + + levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(max(desc->Width, desc->Height), desc->Depth)) + 1; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, + 1, levels, flags, (struct wined3d_sub_resource_data *)data, texture, + &d3d_texture3d_wined3d_parent_ops, &texture->wined3d_texture))) + { + WARN("Failed to create wined3d texture, hr %#x.\n", hr); + wined3d_private_store_cleanup(&texture->private_store); + wined3d_mutex_unlock(); + if (hr == WINED3DERR_INVALIDCALL) + hr = E_INVALIDARG; + return hr; + } + wined3d_mutex_unlock(); + texture->desc.MipLevels = levels; + + ID3D11Device2_AddRef(texture->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_texture3d_create(struct d3d_device *device, const D3D11_TEXTURE3D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture3d **texture) +{ + struct d3d_texture3d *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_texture3d_init(object, device, desc, data))) + { + WARN("Failed to initialize texture, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created texture %p.\n", object); + *texture = object; + + return S_OK; +} diff --git a/dll/directx/wine/d3d11/utils.c b/dll/directx/wine/d3d11/utils.c new file mode 100644 index 00000000000..065436cb4f5 --- /dev/null +++ b/dll/directx/wine/d3d11/utils.c @@ -0,0 +1,870 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +#define WINE_D3D_TO_STR(x) case x: return #x + +const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology) +{ + switch (topology) + { + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_POINTLIST); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINELIST); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ); + default: + FIXME("Unrecognized D3D10_PRIMITIVE_TOPOLOGY %#x\n", topology); + return "unrecognized"; + } +} + +const char *debug_dxgi_format(DXGI_FORMAT format) +{ + switch(format) + { + WINE_D3D_TO_STR(DXGI_FORMAT_UNKNOWN); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G8X24_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10A2_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10A2_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10A2_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R11G11B10_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_D32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R24G8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_D24_UNORM_S8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_X24_TYPELESS_G8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_D16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_A8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R1_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_B8G8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_G8R8_G8B8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC1_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC1_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC1_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC2_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC2_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC2_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC3_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC3_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC3_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC4_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC4_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC4_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC5_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC5_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC5_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B5G6R5_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B5G5R5A1_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8A8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8X8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC6H_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC6H_UF16); + WINE_D3D_TO_STR(DXGI_FORMAT_BC6H_SF16); + WINE_D3D_TO_STR(DXGI_FORMAT_BC7_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC7_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC7_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_B4G4R4A4_UNORM); + default: + FIXME("Unrecognized DXGI_FORMAT %#x.\n", format); + return "unrecognized"; + } +} + +#undef WINE_D3D_TO_STR + +const char *debug_float4(const float *values) +{ + if (!values) + return "(null)"; + return wine_dbg_sprintf("{%.8e, %.8e, %.8e, %.8e}", + values[0], values[1], values[2], values[3]); +} + +void d3d11_primitive_topology_from_wined3d_primitive_type(enum wined3d_primitive_type primitive_type, + unsigned int patch_vertex_count, D3D11_PRIMITIVE_TOPOLOGY *topology) +{ + if (primitive_type <= WINED3D_PT_TRIANGLESTRIP_ADJ) + { + *topology = (D3D11_PRIMITIVE_TOPOLOGY)primitive_type; + return; + } + + if (primitive_type == WINED3D_PT_PATCH) + { + *topology = D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + patch_vertex_count - 1; + return; + } + + *topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; +} + +void wined3d_primitive_type_from_d3d11_primitive_topology(D3D11_PRIMITIVE_TOPOLOGY topology, + enum wined3d_primitive_type *type, unsigned int *patch_vertex_count) +{ + if (topology <= D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) + { + *type = (enum wined3d_primitive_type)topology; + *patch_vertex_count = 0; + return; + } + + if (D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST <= topology + && topology <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) + { + *type = WINED3D_PT_PATCH; + *patch_vertex_count = topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1; + return; + } + + WARN("Invalid primitive topology %#x.\n", topology); + *type = WINED3D_PT_UNDEFINED; + *patch_vertex_count = 0; +} + +DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) +{ + switch(format) + { + case WINED3DFMT_UNKNOWN: return DXGI_FORMAT_UNKNOWN; + case WINED3DFMT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS; + case WINED3DFMT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case WINED3DFMT_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT; + case WINED3DFMT_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_SINT; + case WINED3DFMT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_TYPELESS; + case WINED3DFMT_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT; + case WINED3DFMT_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_UINT; + case WINED3DFMT_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_SINT; + case WINED3DFMT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_TYPELESS; + case WINED3DFMT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case WINED3DFMT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case WINED3DFMT_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_UINT; + case WINED3DFMT_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM; + case WINED3DFMT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SINT; + case WINED3DFMT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_TYPELESS; + case WINED3DFMT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT; + case WINED3DFMT_R32G32_UINT: return DXGI_FORMAT_R32G32_UINT; + case WINED3DFMT_R32G32_SINT: return DXGI_FORMAT_R32G32_SINT; + case WINED3DFMT_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS; + case WINED3DFMT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case WINED3DFMT_R32_FLOAT_X8X24_TYPELESS: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + case WINED3DFMT_X32_TYPELESS_G8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case WINED3DFMT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_TYPELESS; + case WINED3DFMT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM; + case WINED3DFMT_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UINT; + case WINED3DFMT_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT; + case WINED3DFMT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS; + case WINED3DFMT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case WINED3DFMT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + case WINED3DFMT_R8G8B8A8_UINT: return DXGI_FORMAT_R8G8B8A8_UINT; + case WINED3DFMT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM; + case WINED3DFMT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SINT; + case WINED3DFMT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_TYPELESS; + case WINED3DFMT_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT; + case WINED3DFMT_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM; + case WINED3DFMT_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT; + case WINED3DFMT_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM; + case WINED3DFMT_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT; + case WINED3DFMT_R32_TYPELESS: return DXGI_FORMAT_R32_TYPELESS; + case WINED3DFMT_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT; + case WINED3DFMT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case WINED3DFMT_R32_UINT: return DXGI_FORMAT_R32_UINT; + case WINED3DFMT_R32_SINT: return DXGI_FORMAT_R32_SINT; + case WINED3DFMT_R24G8_TYPELESS: return DXGI_FORMAT_R24G8_TYPELESS; + case WINED3DFMT_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case WINED3DFMT_R24_UNORM_X8_TYPELESS: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case WINED3DFMT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + case WINED3DFMT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_TYPELESS; + case WINED3DFMT_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM; + case WINED3DFMT_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT; + case WINED3DFMT_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM; + case WINED3DFMT_R8G8_SINT: return DXGI_FORMAT_R8G8_SINT; + case WINED3DFMT_R16_TYPELESS: return DXGI_FORMAT_R16_TYPELESS; + case WINED3DFMT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case WINED3DFMT_D16_UNORM: return DXGI_FORMAT_D16_UNORM; + case WINED3DFMT_R16_UNORM: return DXGI_FORMAT_R16_UNORM; + case WINED3DFMT_R16_UINT: return DXGI_FORMAT_R16_UINT; + case WINED3DFMT_R16_SNORM: return DXGI_FORMAT_R16_SNORM; + case WINED3DFMT_R16_SINT: return DXGI_FORMAT_R16_SINT; + case WINED3DFMT_R8_TYPELESS: return DXGI_FORMAT_R8_TYPELESS; + case WINED3DFMT_R8_UNORM: return DXGI_FORMAT_R8_UNORM; + case WINED3DFMT_R8_UINT: return DXGI_FORMAT_R8_UINT; + case WINED3DFMT_R8_SNORM: return DXGI_FORMAT_R8_SNORM; + case WINED3DFMT_R8_SINT: return DXGI_FORMAT_R8_SINT; + case WINED3DFMT_A8_UNORM: return DXGI_FORMAT_A8_UNORM; + case WINED3DFMT_R1_UNORM: return DXGI_FORMAT_R1_UNORM; + case WINED3DFMT_R9G9B9E5_SHAREDEXP: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + case WINED3DFMT_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM; + case WINED3DFMT_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case WINED3DFMT_BC1_TYPELESS: return DXGI_FORMAT_BC1_TYPELESS; + case WINED3DFMT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM; + case WINED3DFMT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB; + case WINED3DFMT_BC2_TYPELESS: return DXGI_FORMAT_BC2_TYPELESS; + case WINED3DFMT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM; + case WINED3DFMT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB; + case WINED3DFMT_BC3_TYPELESS: return DXGI_FORMAT_BC3_TYPELESS; + case WINED3DFMT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM; + case WINED3DFMT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB; + case WINED3DFMT_BC4_TYPELESS: return DXGI_FORMAT_BC4_TYPELESS; + case WINED3DFMT_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM; + case WINED3DFMT_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM; + case WINED3DFMT_BC5_TYPELESS: return DXGI_FORMAT_BC5_TYPELESS; + case WINED3DFMT_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM; + case WINED3DFMT_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM; + case WINED3DFMT_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM; + case WINED3DFMT_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM; + case WINED3DFMT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM; + case WINED3DFMT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM; + case WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM: return DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM; + case WINED3DFMT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS; + case WINED3DFMT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case WINED3DFMT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_TYPELESS; + case WINED3DFMT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + case WINED3DFMT_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_TYPELESS; + case WINED3DFMT_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16; + case WINED3DFMT_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16; + case WINED3DFMT_BC7_TYPELESS: return DXGI_FORMAT_BC7_TYPELESS; + case WINED3DFMT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM; + case WINED3DFMT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB; + case WINED3DFMT_B4G4R4A4_UNORM: return DXGI_FORMAT_B4G4R4A4_UNORM; + default: + FIXME("Unhandled wined3d format %#x.\n", format); + return DXGI_FORMAT_UNKNOWN; + } +} + +enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) +{ + switch(format) + { + case DXGI_FORMAT_UNKNOWN: return WINED3DFMT_UNKNOWN; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: return WINED3DFMT_R32G32B32A32_TYPELESS; + case DXGI_FORMAT_R32G32B32A32_FLOAT: return WINED3DFMT_R32G32B32A32_FLOAT; + case DXGI_FORMAT_R32G32B32A32_UINT: return WINED3DFMT_R32G32B32A32_UINT; + case DXGI_FORMAT_R32G32B32A32_SINT: return WINED3DFMT_R32G32B32A32_SINT; + case DXGI_FORMAT_R32G32B32_TYPELESS: return WINED3DFMT_R32G32B32_TYPELESS; + case DXGI_FORMAT_R32G32B32_FLOAT: return WINED3DFMT_R32G32B32_FLOAT; + case DXGI_FORMAT_R32G32B32_UINT: return WINED3DFMT_R32G32B32_UINT; + case DXGI_FORMAT_R32G32B32_SINT: return WINED3DFMT_R32G32B32_SINT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: return WINED3DFMT_R16G16B16A16_TYPELESS; + case DXGI_FORMAT_R16G16B16A16_FLOAT: return WINED3DFMT_R16G16B16A16_FLOAT; + case DXGI_FORMAT_R16G16B16A16_UNORM: return WINED3DFMT_R16G16B16A16_UNORM; + case DXGI_FORMAT_R16G16B16A16_UINT: return WINED3DFMT_R16G16B16A16_UINT; + case DXGI_FORMAT_R16G16B16A16_SNORM: return WINED3DFMT_R16G16B16A16_SNORM; + case DXGI_FORMAT_R16G16B16A16_SINT: return WINED3DFMT_R16G16B16A16_SINT; + case DXGI_FORMAT_R32G32_TYPELESS: return WINED3DFMT_R32G32_TYPELESS; + case DXGI_FORMAT_R32G32_FLOAT: return WINED3DFMT_R32G32_FLOAT; + case DXGI_FORMAT_R32G32_UINT: return WINED3DFMT_R32G32_UINT; + case DXGI_FORMAT_R32G32_SINT: return WINED3DFMT_R32G32_SINT; + case DXGI_FORMAT_R32G8X24_TYPELESS: return WINED3DFMT_R32G8X24_TYPELESS; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return WINED3DFMT_D32_FLOAT_S8X24_UINT; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return WINED3DFMT_R32_FLOAT_X8X24_TYPELESS; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return WINED3DFMT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: return WINED3DFMT_R10G10B10A2_TYPELESS; + case DXGI_FORMAT_R10G10B10A2_UNORM: return WINED3DFMT_R10G10B10A2_UNORM; + case DXGI_FORMAT_R10G10B10A2_UINT: return WINED3DFMT_R10G10B10A2_UINT; + case DXGI_FORMAT_R11G11B10_FLOAT: return WINED3DFMT_R11G11B10_FLOAT; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: return WINED3DFMT_R8G8B8A8_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_UNORM: return WINED3DFMT_R8G8B8A8_UNORM; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return WINED3DFMT_R8G8B8A8_UNORM_SRGB; + case DXGI_FORMAT_R8G8B8A8_UINT: return WINED3DFMT_R8G8B8A8_UINT; + case DXGI_FORMAT_R8G8B8A8_SNORM: return WINED3DFMT_R8G8B8A8_SNORM; + case DXGI_FORMAT_R8G8B8A8_SINT: return WINED3DFMT_R8G8B8A8_SINT; + case DXGI_FORMAT_R16G16_TYPELESS: return WINED3DFMT_R16G16_TYPELESS; + case DXGI_FORMAT_R16G16_FLOAT: return WINED3DFMT_R16G16_FLOAT; + case DXGI_FORMAT_R16G16_UNORM: return WINED3DFMT_R16G16_UNORM; + case DXGI_FORMAT_R16G16_UINT: return WINED3DFMT_R16G16_UINT; + case DXGI_FORMAT_R16G16_SNORM: return WINED3DFMT_R16G16_SNORM; + case DXGI_FORMAT_R16G16_SINT: return WINED3DFMT_R16G16_SINT; + case DXGI_FORMAT_R32_TYPELESS: return WINED3DFMT_R32_TYPELESS; + case DXGI_FORMAT_D32_FLOAT: return WINED3DFMT_D32_FLOAT; + case DXGI_FORMAT_R32_FLOAT: return WINED3DFMT_R32_FLOAT; + case DXGI_FORMAT_R32_UINT: return WINED3DFMT_R32_UINT; + case DXGI_FORMAT_R32_SINT: return WINED3DFMT_R32_SINT; + case DXGI_FORMAT_R24G8_TYPELESS: return WINED3DFMT_R24G8_TYPELESS; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return WINED3DFMT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return WINED3DFMT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return WINED3DFMT_X24_TYPELESS_G8_UINT; + case DXGI_FORMAT_R8G8_TYPELESS: return WINED3DFMT_R8G8_TYPELESS; + case DXGI_FORMAT_R8G8_UNORM: return WINED3DFMT_R8G8_UNORM; + case DXGI_FORMAT_R8G8_UINT: return WINED3DFMT_R8G8_UINT; + case DXGI_FORMAT_R8G8_SNORM: return WINED3DFMT_R8G8_SNORM; + case DXGI_FORMAT_R8G8_SINT: return WINED3DFMT_R8G8_SINT; + case DXGI_FORMAT_R16_TYPELESS: return WINED3DFMT_R16_TYPELESS; + case DXGI_FORMAT_R16_FLOAT: return WINED3DFMT_R16_FLOAT; + case DXGI_FORMAT_D16_UNORM: return WINED3DFMT_D16_UNORM; + case DXGI_FORMAT_R16_UNORM: return WINED3DFMT_R16_UNORM; + case DXGI_FORMAT_R16_UINT: return WINED3DFMT_R16_UINT; + case DXGI_FORMAT_R16_SNORM: return WINED3DFMT_R16_SNORM; + case DXGI_FORMAT_R16_SINT: return WINED3DFMT_R16_SINT; + case DXGI_FORMAT_R8_TYPELESS: return WINED3DFMT_R8_TYPELESS; + case DXGI_FORMAT_R8_UNORM: return WINED3DFMT_R8_UNORM; + case DXGI_FORMAT_R8_UINT: return WINED3DFMT_R8_UINT; + case DXGI_FORMAT_R8_SNORM: return WINED3DFMT_R8_SNORM; + case DXGI_FORMAT_R8_SINT: return WINED3DFMT_R8_SINT; + case DXGI_FORMAT_A8_UNORM: return WINED3DFMT_A8_UNORM; + case DXGI_FORMAT_R1_UNORM: return WINED3DFMT_R1_UNORM; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return WINED3DFMT_R9G9B9E5_SHAREDEXP; + case DXGI_FORMAT_R8G8_B8G8_UNORM: return WINED3DFMT_R8G8_B8G8_UNORM; + case DXGI_FORMAT_G8R8_G8B8_UNORM: return WINED3DFMT_G8R8_G8B8_UNORM; + case DXGI_FORMAT_BC1_TYPELESS: return WINED3DFMT_BC1_TYPELESS; + case DXGI_FORMAT_BC1_UNORM: return WINED3DFMT_BC1_UNORM; + case DXGI_FORMAT_BC1_UNORM_SRGB: return WINED3DFMT_BC1_UNORM_SRGB; + case DXGI_FORMAT_BC2_TYPELESS: return WINED3DFMT_BC2_TYPELESS; + case DXGI_FORMAT_BC2_UNORM: return WINED3DFMT_BC2_UNORM; + case DXGI_FORMAT_BC2_UNORM_SRGB: return WINED3DFMT_BC2_UNORM_SRGB; + case DXGI_FORMAT_BC3_TYPELESS: return WINED3DFMT_BC3_TYPELESS; + case DXGI_FORMAT_BC3_UNORM: return WINED3DFMT_BC3_UNORM; + case DXGI_FORMAT_BC3_UNORM_SRGB: return WINED3DFMT_BC3_UNORM_SRGB; + case DXGI_FORMAT_BC4_TYPELESS: return WINED3DFMT_BC4_TYPELESS; + case DXGI_FORMAT_BC4_UNORM: return WINED3DFMT_BC4_UNORM; + case DXGI_FORMAT_BC4_SNORM: return WINED3DFMT_BC4_SNORM; + case DXGI_FORMAT_BC5_TYPELESS: return WINED3DFMT_BC5_TYPELESS; + case DXGI_FORMAT_BC5_UNORM: return WINED3DFMT_BC5_UNORM; + case DXGI_FORMAT_BC5_SNORM: return WINED3DFMT_BC5_SNORM; + case DXGI_FORMAT_B5G6R5_UNORM: return WINED3DFMT_B5G6R5_UNORM; + case DXGI_FORMAT_B5G5R5A1_UNORM: return WINED3DFMT_B5G5R5A1_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM: return WINED3DFMT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_UNORM: return WINED3DFMT_B8G8R8X8_UNORM; + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: return WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return WINED3DFMT_B8G8R8A8_TYPELESS; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return WINED3DFMT_B8G8R8A8_UNORM_SRGB; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return WINED3DFMT_B8G8R8X8_TYPELESS; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return WINED3DFMT_B8G8R8X8_UNORM_SRGB; + case DXGI_FORMAT_BC6H_TYPELESS: return WINED3DFMT_BC6H_TYPELESS; + case DXGI_FORMAT_BC6H_UF16: return WINED3DFMT_BC6H_UF16; + case DXGI_FORMAT_BC6H_SF16: return WINED3DFMT_BC6H_SF16; + case DXGI_FORMAT_BC7_TYPELESS: return WINED3DFMT_BC7_TYPELESS; + case DXGI_FORMAT_BC7_UNORM: return WINED3DFMT_BC7_UNORM; + case DXGI_FORMAT_BC7_UNORM_SRGB: return WINED3DFMT_BC7_UNORM_SRGB; + case DXGI_FORMAT_B4G4R4A4_UNORM: return WINED3DFMT_B4G4R4A4_UNORM; + default: + FIXME("Unhandled DXGI_FORMAT %#x.\n", format); + return WINED3DFMT_UNKNOWN; + } +} + +unsigned int wined3d_getdata_flags_from_d3d11_async_getdata_flags(unsigned int d3d11_flags) +{ + if (d3d11_flags & ~D3D11_ASYNC_GETDATA_DONOTFLUSH) + FIXME("Unhandled async getdata flags %#x.\n", d3d11_flags); + + if (d3d11_flags & D3D11_ASYNC_GETDATA_DONOTFLUSH) + return 0; + + return WINED3DGETDATA_FLUSH; +} + +DWORD wined3d_usage_from_d3d11(enum D3D11_USAGE usage) +{ + DWORD wined3d_usage = 0; + + if (usage == D3D11_USAGE_DYNAMIC) + wined3d_usage |= WINED3DUSAGE_DYNAMIC; + + return wined3d_usage; +} + +enum D3D11_USAGE d3d11_usage_from_d3d10_usage(enum D3D10_USAGE usage) +{ + switch (usage) + { + case D3D10_USAGE_DEFAULT: return D3D11_USAGE_DEFAULT; + case D3D10_USAGE_IMMUTABLE: return D3D11_USAGE_IMMUTABLE; + case D3D10_USAGE_DYNAMIC: return D3D11_USAGE_DYNAMIC; + case D3D10_USAGE_STAGING: return D3D11_USAGE_STAGING; + default: + FIXME("Unhandled usage %#x.\n", usage); + return D3D11_USAGE_DEFAULT; + } +} + +enum D3D10_USAGE d3d10_usage_from_d3d11_usage(enum D3D11_USAGE usage) +{ + switch (usage) + { + case D3D11_USAGE_DEFAULT: return D3D10_USAGE_DEFAULT; + case D3D11_USAGE_IMMUTABLE: return D3D10_USAGE_IMMUTABLE; + case D3D11_USAGE_DYNAMIC: return D3D10_USAGE_DYNAMIC; + case D3D11_USAGE_STAGING: return D3D10_USAGE_STAGING; + default: + FIXME("Unhandled usage %#x.\n", usage); + return D3D10_USAGE_DEFAULT; + } +} + +UINT d3d11_bind_flags_from_d3d10_bind_flags(UINT bind_flags) +{ + static const UINT handled_flags = D3D10_BIND_VERTEX_BUFFER + | D3D10_BIND_INDEX_BUFFER + | D3D10_BIND_CONSTANT_BUFFER + | D3D10_BIND_SHADER_RESOURCE + | D3D10_BIND_STREAM_OUTPUT + | D3D10_BIND_RENDER_TARGET + | D3D10_BIND_DEPTH_STENCIL; + UINT d3d11_bind_flags = bind_flags & handled_flags; + + if (bind_flags & ~handled_flags) + FIXME("Unhandled bind flags %#x.\n", bind_flags & ~handled_flags); + + return d3d11_bind_flags; +} + +UINT d3d10_bind_flags_from_d3d11_bind_flags(UINT bind_flags) +{ + static const UINT handled_flags = D3D11_BIND_VERTEX_BUFFER + | D3D11_BIND_INDEX_BUFFER + | D3D11_BIND_CONSTANT_BUFFER + | D3D11_BIND_SHADER_RESOURCE + | D3D11_BIND_STREAM_OUTPUT + | D3D11_BIND_RENDER_TARGET + | D3D11_BIND_DEPTH_STENCIL + | D3D11_BIND_UNORDERED_ACCESS + | D3D11_BIND_DECODER + | D3D11_BIND_VIDEO_ENCODER; + UINT d3d10_bind_flags = bind_flags & handled_flags; + + if (bind_flags & ~handled_flags) + FIXME("Unhandled bind flags %#x.\n", bind_flags & ~handled_flags); + + return d3d10_bind_flags; +} + +UINT d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(UINT cpu_access_flags) +{ + static const UINT handled_flags = D3D10_CPU_ACCESS_WRITE + | D3D10_CPU_ACCESS_READ; + UINT d3d11_cpu_access_flags = cpu_access_flags & handled_flags; + + if (cpu_access_flags & ~handled_flags) + FIXME("Unhandled cpu access flags %#x.\n", cpu_access_flags & ~handled_flags); + + return d3d11_cpu_access_flags; +} + +UINT d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(UINT cpu_access_flags) +{ + static const UINT handled_flags = D3D11_CPU_ACCESS_WRITE + | D3D11_CPU_ACCESS_READ; + UINT d3d10_cpu_access_flags = cpu_access_flags & handled_flags; + + if (cpu_access_flags & ~handled_flags) + FIXME("Unhandled cpu access flags %#x.\n", cpu_access_flags & ~handled_flags); + + return d3d10_cpu_access_flags; +} + +UINT d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(UINT resource_misc_flags) +{ + static const UINT bitwise_identical_flags = D3D10_RESOURCE_MISC_GENERATE_MIPS + | D3D10_RESOURCE_MISC_SHARED + | D3D10_RESOURCE_MISC_TEXTURECUBE; + const UINT handled_flags = bitwise_identical_flags + | D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX + | D3D10_RESOURCE_MISC_GDI_COMPATIBLE; + UINT d3d11_resource_misc_flags = resource_misc_flags & bitwise_identical_flags; + + if (resource_misc_flags & D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX) + d3d11_resource_misc_flags |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; + if (resource_misc_flags & D3D10_RESOURCE_MISC_GDI_COMPATIBLE) + d3d11_resource_misc_flags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE; + + if (resource_misc_flags & ~handled_flags) + FIXME("Unhandled resource misc flags %#x.\n", resource_misc_flags & ~handled_flags); + + return d3d11_resource_misc_flags; +} + +UINT d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(UINT resource_misc_flags) +{ + static const UINT bitwise_identical_flags = D3D11_RESOURCE_MISC_GENERATE_MIPS + | D3D11_RESOURCE_MISC_SHARED + | D3D11_RESOURCE_MISC_TEXTURECUBE; + const UINT handled_flags = bitwise_identical_flags + | D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS + | D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS + | D3D11_RESOURCE_MISC_BUFFER_STRUCTURED + | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX + | D3D11_RESOURCE_MISC_GDI_COMPATIBLE + | D3D11_RESOURCE_MISC_SHARED_NTHANDLE; + UINT d3d10_resource_misc_flags = resource_misc_flags & bitwise_identical_flags; + + if (resource_misc_flags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) + d3d10_resource_misc_flags |= D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX; + if (resource_misc_flags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) + d3d10_resource_misc_flags |= D3D10_RESOURCE_MISC_GDI_COMPATIBLE; + + if (resource_misc_flags & ~handled_flags) + FIXME("Unhandled resource misc flags #%x.\n", resource_misc_flags & ~handled_flags); + + return d3d10_resource_misc_flags; +} + +static BOOL d3d11_bind_flags_are_gpu_read_only(UINT bind_flags) +{ + static const BOOL read_only_bind_flags = D3D11_BIND_VERTEX_BUFFER + | D3D11_BIND_INDEX_BUFFER | D3D11_BIND_CONSTANT_BUFFER + | D3D11_BIND_SHADER_RESOURCE; + + return !(bind_flags & ~read_only_bind_flags); +} + +BOOL validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION resource_dimension, + D3D11_USAGE usage, UINT bind_flags, UINT cpu_access_flags, D3D_FEATURE_LEVEL feature_level) +{ + const BOOL is_texture = resource_dimension != D3D11_RESOURCE_DIMENSION_BUFFER; + + switch (usage) + { + case D3D11_USAGE_DEFAULT: + if ((bind_flags == D3D11_BIND_SHADER_RESOURCE && feature_level >= D3D_FEATURE_LEVEL_11_0) + || (is_texture && bind_flags == D3D11_BIND_RENDER_TARGET) + || bind_flags == D3D11_BIND_UNORDERED_ACCESS) + break; + if (cpu_access_flags) + { + WARN("Default resources are not CPU accessible.\n"); + return FALSE; + } + break; + + case D3D11_USAGE_IMMUTABLE: + if (!bind_flags) + { + WARN("Bind flags must be non-zero for immutable resources.\n"); + return FALSE; + } + if (!d3d11_bind_flags_are_gpu_read_only(bind_flags)) + { + WARN("Immutable resources cannot be writable by GPU.\n"); + return FALSE; + } + + if (cpu_access_flags) + { + WARN("Immutable resources are not CPU accessible.\n"); + return FALSE; + } + break; + + case D3D11_USAGE_DYNAMIC: + if (!bind_flags) + { + WARN("Bind flags must be non-zero for dynamic resources.\n"); + return FALSE; + } + if (!d3d11_bind_flags_are_gpu_read_only(bind_flags)) + { + WARN("Dynamic resources cannot be writable by GPU.\n"); + return FALSE; + } + + if (cpu_access_flags != D3D11_CPU_ACCESS_WRITE) + { + WARN("CPU access must be D3D11_CPU_ACCESS_WRITE for dynamic resources.\n"); + return FALSE; + } + break; + + case D3D11_USAGE_STAGING: + if (bind_flags) + { + WARN("Invalid bind flags %#x for staging resources.\n", bind_flags); + return FALSE; + } + + if (!cpu_access_flags) + { + WARN("CPU access must be non-zero for staging resources.\n"); + return FALSE; + } + break; + + default: + WARN("Invalid usage %#x.\n", usage); + return FALSE; + } + + return TRUE; +} + +struct wined3d_resource *wined3d_resource_from_d3d11_resource(ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + + ID3D11Resource_GetType(resource, &dimension); + + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + return wined3d_buffer_get_resource(unsafe_impl_from_ID3D11Buffer( + (ID3D11Buffer *)resource)->wined3d_buffer); + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + return wined3d_texture_get_resource(unsafe_impl_from_ID3D11Texture1D( + (ID3D11Texture1D *)resource)->wined3d_texture); + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + return wined3d_texture_get_resource(unsafe_impl_from_ID3D11Texture2D( + (ID3D11Texture2D *)resource)->wined3d_texture); + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + return wined3d_texture_get_resource(unsafe_impl_from_ID3D11Texture3D( + (ID3D11Texture3D *)resource)->wined3d_texture); + + default: + FIXME("Unhandled resource dimension %#x.\n", dimension); + return NULL; + } +} + +struct wined3d_resource *wined3d_resource_from_d3d10_resource(ID3D10Resource *resource) +{ + D3D10_RESOURCE_DIMENSION dimension; + + ID3D10Resource_GetType(resource, &dimension); + + switch (dimension) + { + case D3D10_RESOURCE_DIMENSION_BUFFER: + return wined3d_buffer_get_resource(unsafe_impl_from_ID3D10Buffer( + (ID3D10Buffer *)resource)->wined3d_buffer); + + case D3D10_RESOURCE_DIMENSION_TEXTURE1D: + return wined3d_texture_get_resource(unsafe_impl_from_ID3D10Texture1D( + (ID3D10Texture1D *)resource)->wined3d_texture); + + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + return wined3d_texture_get_resource(unsafe_impl_from_ID3D10Texture2D( + (ID3D10Texture2D *)resource)->wined3d_texture); + + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + return wined3d_texture_get_resource(unsafe_impl_from_ID3D10Texture3D( + (ID3D10Texture3D *)resource)->wined3d_texture); + + default: + FIXME("Unhandled resource dimension %#x.\n", dimension); + return NULL; + } +} + +DWORD wined3d_map_flags_from_d3d11_map_type(D3D11_MAP map_type) +{ + switch (map_type) + { + case D3D11_MAP_WRITE: + return WINED3D_MAP_WRITE; + + case D3D11_MAP_READ_WRITE: + return WINED3D_MAP_READ | WINED3D_MAP_WRITE; + + case D3D11_MAP_READ: + return WINED3D_MAP_READ; + + case D3D11_MAP_WRITE_DISCARD: + return WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD; + + case D3D11_MAP_WRITE_NO_OVERWRITE: + return WINED3D_MAP_WRITE | WINED3D_MAP_NOOVERWRITE; + + default: + FIXME("Unhandled map_type %#x.\n", map_type); + return WINED3D_MAP_READ | WINED3D_MAP_WRITE; + } +} + +DWORD wined3d_clear_flags_from_d3d11_clear_flags(UINT clear_flags) +{ + DWORD wined3d_clear_flags = 0; + + if (clear_flags & D3D11_CLEAR_DEPTH) + wined3d_clear_flags |= WINED3DCLEAR_ZBUFFER; + if (clear_flags & D3D11_CLEAR_STENCIL) + wined3d_clear_flags |= WINED3DCLEAR_STENCIL; + + if (clear_flags & ~(D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL)) + { + FIXME("Unhandled clear flags %#x.\n", + clear_flags & ~(D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL)); + } + + return wined3d_clear_flags; +} + +unsigned int wined3d_access_from_d3d11(D3D11_USAGE usage, UINT cpu_access) +{ + unsigned int access; + + access = usage == D3D11_USAGE_STAGING ? WINED3D_RESOURCE_ACCESS_CPU : WINED3D_RESOURCE_ACCESS_GPU; + if (cpu_access & D3D11_CPU_ACCESS_WRITE) + access |= WINED3D_RESOURCE_ACCESS_MAP_W; + if (cpu_access & D3D11_CPU_ACCESS_READ) + access |= WINED3D_RESOURCE_ACCESS_MAP_R; + if (cpu_access &= ~(D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ)) + FIXME("Unhandled CPU access flags %#x.\n", cpu_access); + + return access; +} + +HRESULT d3d_get_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT *data_size, void *data) +{ + const struct wined3d_private_data *stored_data; + DWORD size_in; + + if (!data_size) + return E_INVALIDARG; + + wined3d_mutex_lock(); + if (!(stored_data = wined3d_private_store_get_private_data(store, guid))) + { + *data_size = 0; + wined3d_mutex_unlock(); + return DXGI_ERROR_NOT_FOUND; + } + + size_in = *data_size; + *data_size = stored_data->size; + if (!data) + { + wined3d_mutex_unlock(); + return S_OK; + } + if (size_in < stored_data->size) + { + wined3d_mutex_unlock(); + return DXGI_ERROR_MORE_DATA; + } + + if (stored_data->flags & WINED3DSPD_IUNKNOWN) + IUnknown_AddRef(stored_data->content.object); + memcpy(data, stored_data->content.data, stored_data->size); + + wined3d_mutex_unlock(); + return S_OK; +} + +HRESULT d3d_set_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT data_size, const void *data) +{ + struct wined3d_private_data *entry; + HRESULT hr; + + wined3d_mutex_lock(); + if (!data) + { + if (!(entry = wined3d_private_store_get_private_data(store, guid))) + { + wined3d_mutex_unlock(); + return S_FALSE; + } + wined3d_private_store_free_private_data(store, entry); + wined3d_mutex_unlock(); + + return S_OK; + } + + hr = wined3d_private_store_set_private_data(store, guid, data, data_size, 0); + wined3d_mutex_unlock(); + + return hr; +} + +HRESULT d3d_set_private_data_interface(struct wined3d_private_store *store, + REFGUID guid, const IUnknown *object) +{ + HRESULT hr; + + if (!object) + return d3d_set_private_data(store, guid, sizeof(object), &object); + + wined3d_mutex_lock(); + hr = wined3d_private_store_set_private_data(store, + guid, object, sizeof(object), WINED3DSPD_IUNKNOWN); + wined3d_mutex_unlock(); + + return hr; +} diff --git a/dll/directx/wine/d3d11/version.rc b/dll/directx/wine/d3d11/version.rc new file mode 100644 index 00000000000..4246bda4da1 --- /dev/null +++ b/dll/directx/wine/d3d11/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2013 Andrey Gusev + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine Direct3D" +#define WINE_FILENAME_STR "d3d11.dll" +#define WINE_FILEVERSION 7,0,6002,18107 +#define WINE_FILEVERSION_STR "7.0.6002.18107" +#define WINE_PRODUCTVERSION 7,0,6002,18107 +#define WINE_PRODUCTVERSION_STR "7.0.6002.18107" + +#include "wine/wine_common_ver.rc" diff --git a/dll/directx/wine/d3d11/view.c b/dll/directx/wine/d3d11/view.c new file mode 100644 index 00000000000..a6eddf59ce3 --- /dev/null +++ b/dll/directx/wine/d3d11/view.c @@ -0,0 +1,2603 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#define NONAMELESSUNION +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +static HRESULT get_resource_properties(ID3D11Resource *resource, D3D11_RESOURCE_DIMENSION *dimension, + DXGI_FORMAT *format, unsigned int *miplevel_count, unsigned int *layer_count) +{ + ID3D11Resource_GetType(resource, dimension); + switch (*dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + return S_OK; + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + const struct d3d_texture1d *texture; + + if (!(texture = unsafe_impl_from_ID3D11Texture1D((ID3D11Texture1D *)resource))) + { + ERR("Cannot get implementation from ID3D11Texture1D.\n"); + return E_FAIL; + } + + *format = texture->desc.Format; + if (miplevel_count) + *miplevel_count = texture->desc.MipLevels; + *layer_count = texture->desc.ArraySize; + break; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + const struct d3d_texture2d *texture; + + if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource))) + { + ERR("Cannot get implementation from ID3D11Texture2D.\n"); + return E_FAIL; + } + + *format = texture->desc.Format; + if (miplevel_count) + *miplevel_count = texture->desc.MipLevels; + *layer_count = texture->desc.ArraySize; + break; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + const struct d3d_texture3d *texture; + + if (!(texture = unsafe_impl_from_ID3D11Texture3D((ID3D11Texture3D *)resource))) + { + ERR("Cannot get implementation from ID3D11Texture3D.\n"); + return E_FAIL; + } + + *format = texture->desc.Format; + if (miplevel_count) + *miplevel_count = texture->desc.MipLevels; + *layer_count = texture->desc.Depth; + break; + } + + default: + WARN("Invalid resource dimension %#x.\n", *dimension); + return E_INVALIDARG; + } + + return S_OK; +} + +static HRESULT set_dsv_desc_from_resource(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + + ID3D11Resource_GetType(resource, &dimension); + + desc->Flags = 0; + + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + D3D11_TEXTURE1D_DESC texture_desc; + ID3D11Texture1D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture))) + { + ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture1D_GetDesc(texture, &texture_desc); + ID3D11Texture1D_Release(texture); + + desc->Format = texture_desc.Format; + if (texture_desc.ArraySize == 1) + { + desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; + desc->u.Texture1D.MipSlice = 0; + } + else + { + desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; + desc->u.Texture1DArray.MipSlice = 0; + desc->u.Texture1DArray.FirstArraySlice = 0; + desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize; + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11Texture2D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture))) + { + ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture2D_GetDesc(texture, &texture_desc); + ID3D11Texture2D_Release(texture); + + desc->Format = texture_desc.Format; + if (texture_desc.ArraySize == 1) + { + if (texture_desc.SampleDesc.Count == 1) + { + desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + desc->u.Texture2D.MipSlice = 0; + } + else + { + desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + } + } + else + { + if (texture_desc.SampleDesc.Count == 1) + { + desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + desc->u.Texture2DArray.MipSlice = 0; + desc->u.Texture2DArray.FirstArraySlice = 0; + desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize; + } + else + { + desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + desc->u.Texture2DMSArray.FirstArraySlice = 0; + desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize; + } + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_BUFFER: + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + default: + WARN("Invalid resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } +} + +static HRESULT normalize_dsv_desc(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + unsigned int layer_count; + DXGI_FORMAT format; + HRESULT hr; + + if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count))) + return hr; + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1D + && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1DARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2D + && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DARRAY + && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMS + && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_BUFFER: + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + default: + WARN("Invalid resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } + + if (desc->Format == DXGI_FORMAT_UNKNOWN) + desc->Format = format; + + switch (desc->ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count) + desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count) + desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count) + desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice; + break; + + default: + break; + } + + return S_OK; +} + +static HRESULT set_rtv_desc_from_resource(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + HRESULT hr; + + ID3D11Resource_GetType(resource, &dimension); + + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + ID3D11Texture1D *texture; + D3D11_TEXTURE1D_DESC texture_desc; + + hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture); + if (FAILED(hr)) + { + ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D?\n"); + return E_INVALIDARG; + } + + ID3D11Texture1D_GetDesc(texture, &texture_desc); + ID3D11Texture1D_Release(texture); + + desc->Format = texture_desc.Format; + if (texture_desc.ArraySize == 1) + { + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; + desc->u.Texture1D.MipSlice = 0; + } + else + { + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; + desc->u.Texture1DArray.MipSlice = 0; + desc->u.Texture1DArray.FirstArraySlice = 0; + desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize; + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + ID3D11Texture2D *texture; + D3D11_TEXTURE2D_DESC texture_desc; + + hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture); + if (FAILED(hr)) + { + ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D?\n"); + return E_INVALIDARG; + } + + ID3D11Texture2D_GetDesc(texture, &texture_desc); + ID3D11Texture2D_Release(texture); + + desc->Format = texture_desc.Format; + if (texture_desc.ArraySize == 1) + { + if (texture_desc.SampleDesc.Count == 1) + { + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + desc->u.Texture2D.MipSlice = 0; + } + else + { + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + } + } + else + { + if (texture_desc.SampleDesc.Count == 1) + { + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + desc->u.Texture2DArray.MipSlice = 0; + desc->u.Texture2DArray.FirstArraySlice = 0; + desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize; + } + else + { + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + desc->u.Texture2DMSArray.FirstArraySlice = 0; + desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize; + } + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + ID3D11Texture3D *texture; + D3D11_TEXTURE3D_DESC texture_desc; + + hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture); + if (FAILED(hr)) + { + ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D?\n"); + return E_INVALIDARG; + } + + ID3D11Texture3D_GetDesc(texture, &texture_desc); + ID3D11Texture3D_Release(texture); + + desc->Format = texture_desc.Format; + desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + desc->u.Texture3D.MipSlice = 0; + desc->u.Texture3D.FirstWSlice = 0; + desc->u.Texture3D.WSize = texture_desc.Depth; + + return S_OK; + } + + default: + FIXME("Unhandled resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } +} + +static HRESULT normalize_rtv_desc(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + unsigned int layer_count; + DXGI_FORMAT format; + HRESULT hr; + + if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count))) + return hr; + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + if (desc->ViewDimension != D3D11_RTV_DIMENSION_BUFFER) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + return S_OK; + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1D + && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1DARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2D + && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DARRAY + && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMS + && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE3D) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + default: + WARN("Invalid resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } + + if (desc->Format == DXGI_FORMAT_UNKNOWN) + desc->Format = format; + + switch (desc->ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count) + desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count) + desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count) + desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE3D: + layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice); + if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count) + desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice; + break; + + default: + break; + } + + return S_OK; +} + +static HRESULT set_srv_desc_from_resource(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + + ID3D11Resource_GetType(resource, &dimension); + + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + { + D3D11_BUFFER_DESC buffer_desc; + ID3D11Buffer *buffer; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer))) + { + ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n"); + return E_INVALIDARG; + } + + ID3D11Buffer_GetDesc(buffer, &buffer_desc); + ID3D11Buffer_Release(buffer); + + if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) + { + desc->Format = DXGI_FORMAT_UNKNOWN; + desc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + desc->u.Buffer.u1.FirstElement = 0; + desc->u.Buffer.u2.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride; + return S_OK; + } + + return E_INVALIDARG; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + D3D11_TEXTURE1D_DESC texture_desc; + ID3D11Texture1D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture))) + { + ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture1D_GetDesc(texture, &texture_desc); + ID3D11Texture1D_Release(texture); + + desc->Format = texture_desc.Format; + if (texture_desc.ArraySize == 1) + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + desc->u.Texture1D.MostDetailedMip = 0; + desc->u.Texture1D.MipLevels = texture_desc.MipLevels; + } + else + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + desc->u.Texture1DArray.MostDetailedMip = 0; + desc->u.Texture1DArray.MipLevels = texture_desc.MipLevels; + desc->u.Texture1DArray.FirstArraySlice = 0; + desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize; + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11Texture2D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture))) + { + ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture2D_GetDesc(texture, &texture_desc); + ID3D11Texture2D_Release(texture); + + desc->Format = texture_desc.Format; + if (texture_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) + { + if (texture_desc.ArraySize >= 12) + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + desc->u.TextureCubeArray.MostDetailedMip = 0; + desc->u.TextureCubeArray.MipLevels = texture_desc.MipLevels; + desc->u.TextureCubeArray.First2DArrayFace = 0; + desc->u.TextureCubeArray.NumCubes = texture_desc.ArraySize / 6; + } + else + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + desc->u.TextureCube.MostDetailedMip = 0; + desc->u.TextureCube.MipLevels = texture_desc.MipLevels; + } + } + else if (texture_desc.ArraySize == 1) + { + if (texture_desc.SampleDesc.Count == 1) + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc->u.Texture2D.MostDetailedMip = 0; + desc->u.Texture2D.MipLevels = texture_desc.MipLevels; + } + else + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } + } + else + { + if (texture_desc.SampleDesc.Count == 1) + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + desc->u.Texture2DArray.MostDetailedMip = 0; + desc->u.Texture2DArray.MipLevels = texture_desc.MipLevels; + desc->u.Texture2DArray.FirstArraySlice = 0; + desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize; + } + else + { + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + desc->u.Texture2DMSArray.FirstArraySlice = 0; + desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize; + } + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + D3D11_TEXTURE3D_DESC texture_desc; + ID3D11Texture3D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture))) + { + ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture3D_GetDesc(texture, &texture_desc); + ID3D11Texture3D_Release(texture); + + desc->Format = texture_desc.Format; + desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + desc->u.Texture3D.MostDetailedMip = 0; + desc->u.Texture3D.MipLevels = texture_desc.MipLevels; + + return S_OK; + } + + default: + WARN("Invalid resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } +} + +static HRESULT normalize_srv_desc(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource) +{ + unsigned int miplevel_count, layer_count; + D3D11_RESOURCE_DIMENSION dimension; + DXGI_FORMAT format; + HRESULT hr; + + if (FAILED(hr = get_resource_properties(resource, &dimension, &format, &miplevel_count, &layer_count))) + return hr; + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + if (desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFER + && desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + if (!desc->u.Buffer.u2.NumElements) + { + WARN("Zero sized buffer view.\n"); + return E_INVALIDARG; + } + return S_OK; + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1D + && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1DARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2D + && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DARRAY + && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMS + && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY + && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBE + && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE3D) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + default: + WARN("Invalid resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } + + if (desc->Format == DXGI_FORMAT_UNKNOWN) + desc->Format = format; + + switch (desc->ViewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE1D: + if (desc->u.Texture1D.MipLevels == ~0u && desc->u.Texture1D.MostDetailedMip < miplevel_count) + desc->u.Texture1D.MipLevels = miplevel_count - desc->u.Texture1D.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + if (desc->u.Texture1DArray.MipLevels == ~0u && desc->u.Texture1DArray.MostDetailedMip < miplevel_count) + desc->u.Texture1DArray.MipLevels = miplevel_count - desc->u.Texture1DArray.MostDetailedMip; + if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < miplevel_count) + desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2D: + if (desc->u.Texture2D.MipLevels == ~0u && desc->u.Texture2D.MostDetailedMip < miplevel_count) + desc->u.Texture2D.MipLevels = miplevel_count - desc->u.Texture2D.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + if (desc->u.Texture2DArray.MipLevels == ~0u && desc->u.Texture2DArray.MostDetailedMip < miplevel_count) + desc->u.Texture2DArray.MipLevels = miplevel_count - desc->u.Texture2DArray.MostDetailedMip; + if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count) + desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count) + desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_SRV_DIMENSION_TEXTURE3D: + if (desc->u.Texture3D.MipLevels == ~0u && desc->u.Texture3D.MostDetailedMip < miplevel_count) + desc->u.Texture3D.MipLevels = miplevel_count - desc->u.Texture3D.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBE: + if (desc->u.TextureCube.MipLevels == ~0u && desc->u.TextureCube.MostDetailedMip < miplevel_count) + desc->u.TextureCube.MipLevels = miplevel_count - desc->u.TextureCube.MostDetailedMip; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + if (desc->u.TextureCubeArray.MipLevels == ~0u && desc->u.TextureCubeArray.MostDetailedMip < miplevel_count) + desc->u.TextureCubeArray.MipLevels = miplevel_count - desc->u.TextureCubeArray.MostDetailedMip; + if (desc->u.TextureCubeArray.NumCubes == ~0u && desc->u.TextureCubeArray.First2DArrayFace < layer_count) + desc->u.TextureCubeArray.NumCubes = (layer_count - desc->u.TextureCubeArray.First2DArrayFace) / 6; + break; + + default: + break; + } + + return S_OK; +} + +static HRESULT set_uav_desc_from_resource(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + + ID3D11Resource_GetType(resource, &dimension); + + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + { + D3D11_BUFFER_DESC buffer_desc; + ID3D11Buffer *buffer; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer))) + { + ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n"); + return E_INVALIDARG; + } + + ID3D11Buffer_GetDesc(buffer, &buffer_desc); + ID3D11Buffer_Release(buffer); + + if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) + { + desc->Format = DXGI_FORMAT_UNKNOWN; + desc->ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + desc->u.Buffer.FirstElement = 0; + desc->u.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride; + desc->u.Buffer.Flags = 0; + return S_OK; + } + + return E_INVALIDARG; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11Texture2D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture))) + { + ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture2D_GetDesc(texture, &texture_desc); + ID3D11Texture2D_Release(texture); + + if (texture_desc.SampleDesc.Count != 1) + { + WARN("Trying to create view for multisample texture.\n"); + return E_INVALIDARG; + } + + desc->Format = texture_desc.Format; + if (texture_desc.ArraySize == 1) + { + desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + desc->u.Texture2D.MipSlice = 0; + } + else + { + desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; + desc->u.Texture2DArray.MipSlice = 0; + desc->u.Texture2DArray.FirstArraySlice = 0; + desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize; + } + + return S_OK; + } + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + D3D11_TEXTURE3D_DESC texture_desc; + ID3D11Texture3D *texture; + + if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture))) + { + ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n"); + return E_INVALIDARG; + } + + ID3D11Texture3D_GetDesc(texture, &texture_desc); + ID3D11Texture3D_Release(texture); + + desc->Format = texture_desc.Format; + desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + desc->u.Texture3D.MipSlice = 0; + desc->u.Texture3D.FirstWSlice = 0; + desc->u.Texture3D.WSize = texture_desc.Depth; + + return S_OK; + } + + default: + FIXME("Unhandled resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } +} + +static HRESULT normalize_uav_desc(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource) +{ + D3D11_RESOURCE_DIMENSION dimension; + unsigned int layer_count; + DXGI_FORMAT format; + HRESULT hr; + + if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count))) + return hr; + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_BUFFER: + if (desc->ViewDimension != D3D11_UAV_DIMENSION_BUFFER) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + return S_OK; + + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1D + && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1DARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2D + && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE3D) + { + WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); + return E_INVALIDARG; + } + break; + + default: + WARN("Invalid resource dimension %#x.\n", dimension); + return E_INVALIDARG; + } + + if (desc->Format == DXGI_FORMAT_UNKNOWN) + desc->Format = format; + + switch (desc->ViewDimension) + { + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count) + desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice; + break; + + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count) + desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice; + break; + + case D3D11_UAV_DIMENSION_TEXTURE3D: + layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice); + if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count) + desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice; + break; + + default: + break; + } + + return S_OK; +} + +/* ID3D11DepthStencilView methods */ + +static inline struct d3d_depthstencil_view *impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D11DepthStencilView_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_QueryInterface(ID3D11DepthStencilView *iface, + REFIID riid, void **object) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11DepthStencilView) + || IsEqualGUID(riid, &IID_ID3D11View) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11DepthStencilView_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10DepthStencilView) + || IsEqualGUID(riid, &IID_ID3D10View) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10DepthStencilView_AddRef(&view->ID3D10DepthStencilView_iface); + *object = &view->ID3D10DepthStencilView_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_AddRef(ID3D11DepthStencilView *iface) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + ULONG refcount = InterlockedIncrement(&view->refcount); + + TRACE("%p increasing refcount to %u.\n", view, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(view->device); + wined3d_mutex_lock(); + wined3d_rendertarget_view_incref(view->wined3d_view); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_Release(ID3D11DepthStencilView *iface) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + ULONG refcount = InterlockedDecrement(&view->refcount); + + TRACE("%p decreasing refcount to %u.\n", view, refcount); + + if (!refcount) + { + ID3D11Device2 *device = view->device; + + wined3d_mutex_lock(); + wined3d_rendertarget_view_decref(view->wined3d_view); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDevice(ID3D11DepthStencilView *iface, + ID3D11Device **device) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)view->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_GetPrivateData(ID3D11DepthStencilView *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateData(ID3D11DepthStencilView *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateDataInterface(ID3D11DepthStencilView *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetResource(ID3D11DepthStencilView *iface, + ID3D11Resource **resource) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, resource %p.\n", iface, resource); + + *resource = view->resource; + ID3D11Resource_AddRef(*resource); +} + +static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDesc(ID3D11DepthStencilView *iface, + D3D11_DEPTH_STENCIL_VIEW_DESC *desc) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = view->desc; +} + +static const struct ID3D11DepthStencilViewVtbl d3d11_depthstencil_view_vtbl = +{ + /* IUnknown methods */ + d3d11_depthstencil_view_QueryInterface, + d3d11_depthstencil_view_AddRef, + d3d11_depthstencil_view_Release, + /* ID3D11DeviceChild methods */ + d3d11_depthstencil_view_GetDevice, + d3d11_depthstencil_view_GetPrivateData, + d3d11_depthstencil_view_SetPrivateData, + d3d11_depthstencil_view_SetPrivateDataInterface, + /* ID3D11View methods */ + d3d11_depthstencil_view_GetResource, + /* ID3D11DepthStencilView methods */ + d3d11_depthstencil_view_GetDesc, +}; + +/* ID3D10DepthStencilView methods */ + +static inline struct d3d_depthstencil_view *impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D10DepthStencilView_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_QueryInterface(ID3D10DepthStencilView *iface, + REFIID riid, void **object) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_depthstencil_view_QueryInterface(&view->ID3D11DepthStencilView_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_AddRef(ID3D10DepthStencilView *iface) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_depthstencil_view_AddRef(&view->ID3D11DepthStencilView_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_Release(ID3D10DepthStencilView *iface) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_depthstencil_view_Release(&view->ID3D11DepthStencilView_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDevice(ID3D10DepthStencilView *iface, ID3D10Device **device) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_GetPrivateData(ID3D10DepthStencilView *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateData(ID3D10DepthStencilView *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateDataInterface(ID3D10DepthStencilView *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +/* ID3D10View methods */ + +static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetResource(ID3D10DepthStencilView *iface, + ID3D10Resource **resource) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + + TRACE("iface %p, resource %p.\n", iface, resource); + + ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource); +} + +/* ID3D10DepthStencilView methods */ + +static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDesc(ID3D10DepthStencilView *iface, + D3D10_DEPTH_STENCIL_VIEW_DESC *desc) +{ + struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface); + const D3D11_DEPTH_STENCIL_VIEW_DESC *d3d11_desc = &view->desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + desc->Format = d3d11_desc->Format; + desc->ViewDimension = (D3D10_DSV_DIMENSION)d3d11_desc->ViewDimension; + memcpy(&desc->u, &d3d11_desc->u, sizeof(desc->u)); +} + +static const struct ID3D10DepthStencilViewVtbl d3d10_depthstencil_view_vtbl = +{ + /* IUnknown methods */ + d3d10_depthstencil_view_QueryInterface, + d3d10_depthstencil_view_AddRef, + d3d10_depthstencil_view_Release, + /* ID3D10DeviceChild methods */ + d3d10_depthstencil_view_GetDevice, + d3d10_depthstencil_view_GetPrivateData, + d3d10_depthstencil_view_SetPrivateData, + d3d10_depthstencil_view_SetPrivateDataInterface, + /* ID3D10View methods */ + d3d10_depthstencil_view_GetResource, + /* ID3D10DepthStencilView methods */ + d3d10_depthstencil_view_GetDesc, +}; + +static void STDMETHODCALLTYPE d3d_depth_stencil_view_wined3d_object_destroyed(void *parent) +{ + struct d3d_depthstencil_view *view = parent; + + wined3d_private_store_cleanup(&view->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_depth_stencil_view_wined3d_parent_ops = +{ + d3d_depth_stencil_view_wined3d_object_destroyed, +}; + +static void wined3d_depth_stencil_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc, + const D3D11_DEPTH_STENCIL_VIEW_DESC *desc) +{ + wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format); + + if (desc->Flags) + FIXME("Unhandled depth stencil view flags %#x.\n", desc->Flags); + + wined3d_desc->flags = 0; + wined3d_desc->u.texture.level_count = 1; + switch (desc->ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2D: + wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize; + break; + + default: + FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension); + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + } +} + +static HRESULT d3d_depthstencil_view_init(struct d3d_depthstencil_view *view, struct d3d_device *device, + ID3D11Resource *resource, const D3D11_DEPTH_STENCIL_VIEW_DESC *desc) +{ + struct wined3d_resource *wined3d_resource; + struct wined3d_view_desc wined3d_desc; + HRESULT hr; + + view->ID3D11DepthStencilView_iface.lpVtbl = &d3d11_depthstencil_view_vtbl; + view->ID3D10DepthStencilView_iface.lpVtbl = &d3d10_depthstencil_view_vtbl; + view->refcount = 1; + + if (!desc) + { + hr = set_dsv_desc_from_resource(&view->desc, resource); + } + else + { + view->desc = *desc; + hr = normalize_dsv_desc(&view->desc, resource); + } + if (FAILED(hr)) + return hr; + + wined3d_mutex_lock(); + if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource))) + { + wined3d_mutex_unlock(); + ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource); + return E_FAIL; + } + + wined3d_depth_stencil_view_desc_from_d3d11(&wined3d_desc, &view->desc); + if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource, + view, &d3d_depth_stencil_view_wined3d_parent_ops, &view->wined3d_view))) + { + wined3d_mutex_unlock(); + WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr); + return hr; + } + + wined3d_private_store_init(&view->private_store); + wined3d_mutex_unlock(); + view->resource = resource; + ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_depthstencil_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, struct d3d_depthstencil_view **view) +{ + struct d3d_depthstencil_view *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_depthstencil_view_init(object, device, resource, desc))) + { + WARN("Failed to initialize depthstencil view, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created depthstencil view %p.\n", object); + *view = object; + + return S_OK; +} + +struct d3d_depthstencil_view *unsafe_impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_depthstencil_view_vtbl); + + return impl_from_ID3D11DepthStencilView(iface); +} + +struct d3d_depthstencil_view *unsafe_impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_depthstencil_view_vtbl); + + return impl_from_ID3D10DepthStencilView(iface); +} + +/* ID3D11RenderTargetView methods */ + +static inline struct d3d_rendertarget_view *impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D11RenderTargetView_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_QueryInterface(ID3D11RenderTargetView *iface, + REFIID riid, void **object) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11RenderTargetView) + || IsEqualGUID(riid, &IID_ID3D11View) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11RenderTargetView_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10RenderTargetView) + || IsEqualGUID(riid, &IID_ID3D10View) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10RenderTargetView_AddRef(&view->ID3D10RenderTargetView_iface); + *object = &view->ID3D10RenderTargetView_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_AddRef(ID3D11RenderTargetView *iface) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + ULONG refcount = InterlockedIncrement(&view->refcount); + + TRACE("%p increasing refcount to %u.\n", view, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(view->device); + wined3d_mutex_lock(); + wined3d_rendertarget_view_incref(view->wined3d_view); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_Release(ID3D11RenderTargetView *iface) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + ULONG refcount = InterlockedDecrement(&view->refcount); + + TRACE("%p decreasing refcount to %u.\n", view, refcount); + + if (!refcount) + { + ID3D11Device2 *device = view->device; + + wined3d_mutex_lock(); + wined3d_rendertarget_view_decref(view->wined3d_view); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDevice(ID3D11RenderTargetView *iface, + ID3D11Device **device) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)view->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_GetPrivateData(ID3D11RenderTargetView *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateData(ID3D11RenderTargetView *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateDataInterface(ID3D11RenderTargetView *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetResource(ID3D11RenderTargetView *iface, + ID3D11Resource **resource) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, resource %p.\n", iface, resource); + + *resource = view->resource; + ID3D11Resource_AddRef(*resource); +} + +static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDesc(ID3D11RenderTargetView *iface, + D3D11_RENDER_TARGET_VIEW_DESC *desc) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = view->desc; +} + +static const struct ID3D11RenderTargetViewVtbl d3d11_rendertarget_view_vtbl = +{ + /* IUnknown methods */ + d3d11_rendertarget_view_QueryInterface, + d3d11_rendertarget_view_AddRef, + d3d11_rendertarget_view_Release, + /* ID3D11DeviceChild methods */ + d3d11_rendertarget_view_GetDevice, + d3d11_rendertarget_view_GetPrivateData, + d3d11_rendertarget_view_SetPrivateData, + d3d11_rendertarget_view_SetPrivateDataInterface, + /* ID3D11View methods */ + d3d11_rendertarget_view_GetResource, + /* ID3D11RenderTargetView methods */ + d3d11_rendertarget_view_GetDesc, +}; + +/* ID3D10RenderTargetView methods */ + +static inline struct d3d_rendertarget_view *impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D10RenderTargetView_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_QueryInterface(ID3D10RenderTargetView *iface, + REFIID riid, void **object) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_rendertarget_view_QueryInterface(&view->ID3D11RenderTargetView_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_AddRef(ID3D10RenderTargetView *iface) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_rendertarget_view_AddRef(&view->ID3D11RenderTargetView_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_Release(ID3D10RenderTargetView *iface) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_rendertarget_view_Release(&view->ID3D11RenderTargetView_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDevice(ID3D10RenderTargetView *iface, ID3D10Device **device) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_GetPrivateData(ID3D10RenderTargetView *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateData(ID3D10RenderTargetView *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateDataInterface(ID3D10RenderTargetView *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +/* ID3D10View methods */ + +static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetResource(ID3D10RenderTargetView *iface, + ID3D10Resource **resource) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, resource %p\n", iface, resource); + + ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource); +} + +/* ID3D10RenderTargetView methods */ + +static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDesc(ID3D10RenderTargetView *iface, + D3D10_RENDER_TARGET_VIEW_DESC *desc) +{ + struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface); + + TRACE("iface %p, desc %p\n", iface, desc); + + memcpy(desc, &view->desc, sizeof(*desc)); +} + +static const struct ID3D10RenderTargetViewVtbl d3d10_rendertarget_view_vtbl = +{ + /* IUnknown methods */ + d3d10_rendertarget_view_QueryInterface, + d3d10_rendertarget_view_AddRef, + d3d10_rendertarget_view_Release, + /* ID3D10DeviceChild methods */ + d3d10_rendertarget_view_GetDevice, + d3d10_rendertarget_view_GetPrivateData, + d3d10_rendertarget_view_SetPrivateData, + d3d10_rendertarget_view_SetPrivateDataInterface, + /* ID3D10View methods */ + d3d10_rendertarget_view_GetResource, + /* ID3D10RenderTargetView methods */ + d3d10_rendertarget_view_GetDesc, +}; + +static void STDMETHODCALLTYPE d3d_render_target_view_wined3d_object_destroyed(void *parent) +{ + struct d3d_rendertarget_view *view = parent; + + wined3d_private_store_cleanup(&view->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_render_target_view_wined3d_parent_ops = +{ + d3d_render_target_view_wined3d_object_destroyed, +}; + +static void wined3d_rendertarget_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc, + const D3D11_RENDER_TARGET_VIEW_DESC *desc) +{ + wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format); + + wined3d_desc->flags = 0; + wined3d_desc->u.texture.level_count = 1; + switch (desc->ViewDimension) + { + case D3D11_RTV_DIMENSION_BUFFER: + wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement; + wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements; + break; + + case D3D11_RTV_DIMENSION_TEXTURE1D: + wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2D: + wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize; + break; + + case D3D11_RTV_DIMENSION_TEXTURE3D: + wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize; + break; + + default: + FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension); + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + } +} + +static HRESULT d3d_rendertarget_view_init(struct d3d_rendertarget_view *view, struct d3d_device *device, + ID3D11Resource *resource, const D3D11_RENDER_TARGET_VIEW_DESC *desc) +{ + struct wined3d_resource *wined3d_resource; + struct wined3d_view_desc wined3d_desc; + HRESULT hr; + + view->ID3D11RenderTargetView_iface.lpVtbl = &d3d11_rendertarget_view_vtbl; + view->ID3D10RenderTargetView_iface.lpVtbl = &d3d10_rendertarget_view_vtbl; + view->refcount = 1; + + if (!desc) + { + hr = set_rtv_desc_from_resource(&view->desc, resource); + } + else + { + view->desc = *desc; + hr = normalize_rtv_desc(&view->desc, resource); + } + if (FAILED(hr)) + return hr; + + wined3d_mutex_lock(); + if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource))) + { + wined3d_mutex_unlock(); + ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource); + return E_FAIL; + } + + wined3d_rendertarget_view_desc_from_d3d11(&wined3d_desc, &view->desc); + if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource, + view, &d3d_render_target_view_wined3d_parent_ops, &view->wined3d_view))) + { + wined3d_mutex_unlock(); + WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr); + return hr; + } + + wined3d_private_store_init(&view->private_store); + wined3d_mutex_unlock(); + view->resource = resource; + ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_rendertarget_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_RENDER_TARGET_VIEW_DESC *desc, struct d3d_rendertarget_view **view) +{ + struct d3d_rendertarget_view *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_rendertarget_view_init(object, device, resource, desc))) + { + WARN("Failed to initialize rendertarget view, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created rendertarget view %p.\n", object); + *view = object; + + return S_OK; +} + +struct d3d_rendertarget_view *unsafe_impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_rendertarget_view_vtbl); + + return impl_from_ID3D11RenderTargetView(iface); +} + +struct d3d_rendertarget_view *unsafe_impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_rendertarget_view_vtbl); + + return impl_from_ID3D10RenderTargetView(iface); +} + +/* ID3D11ShaderResourceView methods */ + +static inline struct d3d_shader_resource_view *impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D11ShaderResourceView_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_QueryInterface(ID3D11ShaderResourceView *iface, + REFIID riid, void **object) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11ShaderResourceView) + || IsEqualGUID(riid, &IID_ID3D11View) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11ShaderResourceView_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_ID3D10ShaderResourceView1) + || IsEqualGUID(riid, &IID_ID3D10ShaderResourceView) + || IsEqualGUID(riid, &IID_ID3D10View) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild)) + { + ID3D10ShaderResourceView1_AddRef(&view->ID3D10ShaderResourceView1_iface); + *object = &view->ID3D10ShaderResourceView1_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_AddRef(ID3D11ShaderResourceView *iface) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + ULONG refcount = InterlockedIncrement(&view->refcount); + + TRACE("%p increasing refcount to %u.\n", view, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(view->device); + wined3d_mutex_lock(); + wined3d_shader_resource_view_incref(view->wined3d_view); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_Release(ID3D11ShaderResourceView *iface) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + ULONG refcount = InterlockedDecrement(&view->refcount); + + TRACE("%p decreasing refcount to %u.\n", view, refcount); + + if (!refcount) + { + ID3D11Device2 *device = view->device; + + wined3d_mutex_lock(); + wined3d_shader_resource_view_decref(view->wined3d_view); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDevice(ID3D11ShaderResourceView *iface, + ID3D11Device **device) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)view->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_GetPrivateData(ID3D11ShaderResourceView *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateData(ID3D11ShaderResourceView *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateDataInterface(ID3D11ShaderResourceView *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetResource(ID3D11ShaderResourceView *iface, + ID3D11Resource **resource) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, resource %p.\n", iface, resource); + + *resource = view->resource; + ID3D11Resource_AddRef(*resource); +} + +static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDesc(ID3D11ShaderResourceView *iface, + D3D11_SHADER_RESOURCE_VIEW_DESC *desc) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = view->desc; +} + +static const struct ID3D11ShaderResourceViewVtbl d3d11_shader_resource_view_vtbl = +{ + /* IUnknown methods */ + d3d11_shader_resource_view_QueryInterface, + d3d11_shader_resource_view_AddRef, + d3d11_shader_resource_view_Release, + /* ID3D11DeviceChild methods */ + d3d11_shader_resource_view_GetDevice, + d3d11_shader_resource_view_GetPrivateData, + d3d11_shader_resource_view_SetPrivateData, + d3d11_shader_resource_view_SetPrivateDataInterface, + /* ID3D11View methods */ + d3d11_shader_resource_view_GetResource, + /* ID3D11ShaderResourceView methods */ + d3d11_shader_resource_view_GetDesc, +}; + +/* ID3D10ShaderResourceView methods */ + +static inline struct d3d_shader_resource_view *impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView1 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_QueryInterface(ID3D10ShaderResourceView1 *iface, + REFIID riid, void **object) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return d3d11_shader_resource_view_QueryInterface(&view->ID3D11ShaderResourceView_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_AddRef(ID3D10ShaderResourceView1 *iface) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_shader_resource_view_AddRef(&view->ID3D11ShaderResourceView_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_Release(ID3D10ShaderResourceView1 *iface) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_shader_resource_view_Release(&view->ID3D11ShaderResourceView_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDevice(ID3D10ShaderResourceView1 *iface, + ID3D10Device **device) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_GetPrivateData(ID3D10ShaderResourceView1 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateData(ID3D10ShaderResourceView1 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateDataInterface(ID3D10ShaderResourceView1 *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +/* ID3D10View methods */ + +static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetResource(ID3D10ShaderResourceView1 *iface, + ID3D10Resource **resource) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, resource %p.\n", iface, resource); + + ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource); +} + +/* ID3D10ShaderResourceView methods */ + +static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc(ID3D10ShaderResourceView1 *iface, + D3D10_SHADER_RESOURCE_VIEW_DESC *desc) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &view->desc, sizeof(*desc)); +} + +static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc1(ID3D10ShaderResourceView1 *iface, + D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc) +{ + struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + memcpy(desc, &view->desc, sizeof(*desc)); +} + +static const struct ID3D10ShaderResourceView1Vtbl d3d10_shader_resource_view_vtbl = +{ + /* IUnknown methods */ + d3d10_shader_resource_view_QueryInterface, + d3d10_shader_resource_view_AddRef, + d3d10_shader_resource_view_Release, + /* ID3D10DeviceChild methods */ + d3d10_shader_resource_view_GetDevice, + d3d10_shader_resource_view_GetPrivateData, + d3d10_shader_resource_view_SetPrivateData, + d3d10_shader_resource_view_SetPrivateDataInterface, + /* ID3D10View methods */ + d3d10_shader_resource_view_GetResource, + /* ID3D10ShaderResourceView methods */ + d3d10_shader_resource_view_GetDesc, + /* ID3D10ShaderResourceView1 methods */ + d3d10_shader_resource_view_GetDesc1, +}; + +static void STDMETHODCALLTYPE d3d_shader_resource_view_wined3d_object_destroyed(void *parent) +{ + struct d3d_shader_resource_view *view = parent; + + wined3d_private_store_cleanup(&view->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d_shader_resource_view_wined3d_parent_ops = +{ + d3d_shader_resource_view_wined3d_object_destroyed, +}; + +static unsigned int wined3d_view_flags_from_d3d11_bufferex_flags(unsigned int d3d11_flags) +{ + unsigned int wined3d_flags = d3d11_flags & WINED3D_VIEW_BUFFER_RAW; + + if (d3d11_flags != wined3d_flags) + FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags); + + return wined3d_flags; +} + +static HRESULT wined3d_shader_resource_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc, + const D3D11_SHADER_RESOURCE_VIEW_DESC *desc) +{ + wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format); + wined3d_desc->flags = 0; + + switch (desc->ViewDimension) + { + case D3D11_SRV_DIMENSION_BUFFER: + wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement; + wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements; + break; + + case D3D11_SRV_DIMENSION_TEXTURE1D: + wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.Texture1D.MipLevels; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.Texture1DArray.MipLevels; + wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2D: + wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.Texture2D.MipLevels; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.Texture2DArray.MipLevels; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.level_count = 1; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = 0; + wined3d_desc->u.texture.level_count = 1; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize; + break; + + case D3D11_SRV_DIMENSION_TEXTURE3D: + wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.Texture3D.MipLevels; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBE: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE; + wined3d_desc->u.texture.level_idx = desc->u.TextureCube.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.TextureCube.MipLevels; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 6; + break; + + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.TextureCubeArray.MostDetailedMip; + wined3d_desc->u.texture.level_count = desc->u.TextureCubeArray.MipLevels; + wined3d_desc->u.texture.layer_idx = desc->u.TextureCubeArray.First2DArrayFace; + wined3d_desc->u.texture.layer_count = 6 * desc->u.TextureCubeArray.NumCubes; + break; + + case D3D11_SRV_DIMENSION_BUFFEREX: + wined3d_desc->flags = wined3d_view_flags_from_d3d11_bufferex_flags(desc->u.BufferEx.Flags); + wined3d_desc->u.buffer.start_idx = desc->u.BufferEx.FirstElement; + wined3d_desc->u.buffer.count = desc->u.BufferEx.NumElements; + break; + + default: + WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension); + return E_FAIL; + } + + return S_OK; +} + +static HRESULT d3d_shader_resource_view_init(struct d3d_shader_resource_view *view, struct d3d_device *device, + ID3D11Resource *resource, const D3D11_SHADER_RESOURCE_VIEW_DESC *desc) +{ + struct wined3d_resource *wined3d_resource; + struct wined3d_view_desc wined3d_desc; + HRESULT hr; + + view->ID3D11ShaderResourceView_iface.lpVtbl = &d3d11_shader_resource_view_vtbl; + view->ID3D10ShaderResourceView1_iface.lpVtbl = &d3d10_shader_resource_view_vtbl; + view->refcount = 1; + + if (!desc) + { + hr = set_srv_desc_from_resource(&view->desc, resource); + } + else + { + view->desc = *desc; + hr = normalize_srv_desc(&view->desc, resource); + } + if (FAILED(hr)) + return hr; + + if (FAILED(hr = wined3d_shader_resource_view_desc_from_d3d11(&wined3d_desc, &view->desc))) + return hr; + + wined3d_mutex_lock(); + if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource))) + { + wined3d_mutex_unlock(); + ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource); + return E_FAIL; + } + + if (FAILED(hr = wined3d_shader_resource_view_create(&wined3d_desc, wined3d_resource, + view, &d3d_shader_resource_view_wined3d_parent_ops, &view->wined3d_view))) + { + wined3d_mutex_unlock(); + WARN("Failed to create wined3d shader resource view, hr %#x.\n", hr); + return hr; + } + + wined3d_private_store_init(&view->private_store); + wined3d_mutex_unlock(); + view->resource = resource; + ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d_shader_resource_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, struct d3d_shader_resource_view **view) +{ + struct d3d_shader_resource_view *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d_shader_resource_view_init(object, device, resource, desc))) + { + WARN("Failed to initialize shader resource view, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created shader resource view %p.\n", object); + *view = object; + + return S_OK; +} + +struct d3d_shader_resource_view *unsafe_impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_shader_resource_view_vtbl); + return impl_from_ID3D11ShaderResourceView(iface); +} + +struct d3d_shader_resource_view *unsafe_impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == (ID3D10ShaderResourceViewVtbl *)&d3d10_shader_resource_view_vtbl); + return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface); +} + +/* ID3D11UnorderedAccessView methods */ + +static inline struct d3d11_unordered_access_view *impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_unordered_access_view, ID3D11UnorderedAccessView_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_QueryInterface(ID3D11UnorderedAccessView *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11UnorderedAccessView) + || IsEqualGUID(riid, &IID_ID3D11View) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11UnorderedAccessView_AddRef(*object = iface); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_AddRef(ID3D11UnorderedAccessView *iface) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + ULONG refcount = InterlockedIncrement(&view->refcount); + + TRACE("%p increasing refcount to %u.\n", view, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(view->device); + wined3d_mutex_lock(); + wined3d_unordered_access_view_incref(view->wined3d_view); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_Release(ID3D11UnorderedAccessView *iface) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + ULONG refcount = InterlockedDecrement(&view->refcount); + + TRACE("%p decreasing refcount to %u.\n", view, refcount); + + if (!refcount) + { + ID3D11Device2 *device = view->device; + + wined3d_mutex_lock(); + wined3d_unordered_access_view_decref(view->wined3d_view); + wined3d_mutex_unlock(); + + ID3D11Device2_Release(device); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDevice(ID3D11UnorderedAccessView *iface, + ID3D11Device **device) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device_AddRef(*device = (ID3D11Device *)view->device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_GetPrivateData(ID3D11UnorderedAccessView *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateData(ID3D11UnorderedAccessView *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&view->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateDataInterface(ID3D11UnorderedAccessView *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&view->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetResource(ID3D11UnorderedAccessView *iface, + ID3D11Resource **resource) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + + TRACE("iface %p, resource %p.\n", iface, resource); + + ID3D11Resource_AddRef(*resource = view->resource); +} + +static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDesc(ID3D11UnorderedAccessView *iface, + D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) +{ + struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = view->desc; +} + +static const struct ID3D11UnorderedAccessViewVtbl d3d11_unordered_access_view_vtbl = +{ + /* IUnknown methods */ + d3d11_unordered_access_view_QueryInterface, + d3d11_unordered_access_view_AddRef, + d3d11_unordered_access_view_Release, + /* ID3D11DeviceChild methods */ + d3d11_unordered_access_view_GetDevice, + d3d11_unordered_access_view_GetPrivateData, + d3d11_unordered_access_view_SetPrivateData, + d3d11_unordered_access_view_SetPrivateDataInterface, + /* ID3D11View methods */ + d3d11_unordered_access_view_GetResource, + /* ID3D11UnorderedAccessView methods */ + d3d11_unordered_access_view_GetDesc, +}; + +static void STDMETHODCALLTYPE d3d11_unordered_access_view_wined3d_object_destroyed(void *parent) +{ + struct d3d11_unordered_access_view *view = parent; + + wined3d_private_store_cleanup(&view->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d11_unordered_access_view_wined3d_parent_ops = +{ + d3d11_unordered_access_view_wined3d_object_destroyed, +}; + +static unsigned int wined3d_view_flags_from_d3d11_buffer_uav_flags(unsigned int d3d11_flags) +{ + unsigned int wined3d_flags = d3d11_flags & (WINED3D_VIEW_BUFFER_RAW + | WINED3D_VIEW_BUFFER_APPEND | WINED3D_VIEW_BUFFER_COUNTER); + + if (d3d11_flags != wined3d_flags) + FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags); + + return wined3d_flags; +} + +static HRESULT wined3d_unordered_access_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc, + const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) +{ + wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format); + + wined3d_desc->flags = 0; + wined3d_desc->u.texture.level_count = 1; + switch (desc->ViewDimension) + { + case D3D11_UAV_DIMENSION_BUFFER: + wined3d_desc->flags = wined3d_view_flags_from_d3d11_buffer_uav_flags(desc->u.Buffer.Flags); + wined3d_desc->u.buffer.start_idx = desc->u.Buffer.FirstElement; + wined3d_desc->u.buffer.count = desc->u.Buffer.NumElements; + break; + + case D3D11_UAV_DIMENSION_TEXTURE1D: + wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize; + break; + + case D3D11_UAV_DIMENSION_TEXTURE2D: + wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice; + wined3d_desc->u.texture.layer_idx = 0; + wined3d_desc->u.texture.layer_count = 1; + break; + + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY; + wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize; + break; + + case D3D11_UAV_DIMENSION_TEXTURE3D: + wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice; + wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice; + wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize; + break; + + default: + WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension); + return E_FAIL; + } + + return S_OK; +} + +static HRESULT d3d11_unordered_access_view_init(struct d3d11_unordered_access_view *view, + struct d3d_device *device, ID3D11Resource *resource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) +{ + struct wined3d_resource *wined3d_resource; + struct wined3d_view_desc wined3d_desc; + HRESULT hr; + + view->ID3D11UnorderedAccessView_iface.lpVtbl = &d3d11_unordered_access_view_vtbl; + view->refcount = 1; + + if (!desc) + { + hr = set_uav_desc_from_resource(&view->desc, resource); + } + else + { + view->desc = *desc; + hr = normalize_uav_desc(&view->desc, resource); + } + if (FAILED(hr)) + return hr; + + if (FAILED(hr = wined3d_unordered_access_view_desc_from_d3d11(&wined3d_desc, &view->desc))) + return hr; + + wined3d_mutex_lock(); + if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource))) + { + wined3d_mutex_unlock(); + ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource); + return E_FAIL; + } + + if (FAILED(hr = wined3d_unordered_access_view_create(&wined3d_desc, wined3d_resource, + view, &d3d11_unordered_access_view_wined3d_parent_ops, &view->wined3d_view))) + { + wined3d_mutex_unlock(); + WARN("Failed to create wined3d unordered access view, hr %#x.\n", hr); + return hr; + } + + wined3d_private_store_init(&view->private_store); + wined3d_mutex_unlock(); + view->resource = resource; + ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface); + + return S_OK; +} + +HRESULT d3d11_unordered_access_view_create(struct d3d_device *device, ID3D11Resource *resource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, struct d3d11_unordered_access_view **view) +{ + struct d3d11_unordered_access_view *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d11_unordered_access_view_init(object, device, resource, desc))) + { + WARN("Failed to initialize unordered access view, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created unordered access view %p.\n", object); + *view = object; + + return S_OK; +} + +struct d3d11_unordered_access_view *unsafe_impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_unordered_access_view_vtbl); + + return impl_from_ID3D11UnorderedAccessView(iface); +} diff --git a/dll/directx/wine/d3d8/buffer.c b/dll/directx/wine/d3d8/buffer.c index fb6b7bc1e92..9eb98bfc2f2 100644 --- a/dll/directx/wine/d3d8/buffer.c +++ b/dll/directx/wine/d3d8/buffer.c @@ -16,7 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -56,7 +55,10 @@ static ULONG WINAPI d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8 *iface) { IDirect3DDevice8_AddRef(buffer->parent_device); wined3d_mutex_lock(); - wined3d_buffer_incref(buffer->wined3d_buffer); + if (buffer->draw_buffer) + wined3d_buffer_incref(buffer->draw_buffer); + else + wined3d_buffer_incref(buffer->wined3d_buffer); wined3d_mutex_unlock(); } @@ -72,10 +74,14 @@ static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface) if (!refcount) { + struct wined3d_buffer *draw_buffer = buffer->draw_buffer; IDirect3DDevice8 *device = buffer->parent_device; wined3d_mutex_lock(); - wined3d_buffer_decref(buffer->wined3d_buffer); + if (draw_buffer) + wined3d_buffer_decref(draw_buffer); + else + wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ @@ -182,6 +188,7 @@ static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT BYTE **data, DWORD flags) { struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface); + struct wined3d_resource *wined3d_resource; struct wined3d_map_desc wined3d_map_desc; struct wined3d_box wined3d_box = {0}; HRESULT hr; @@ -192,8 +199,9 @@ static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT wined3d_box.left = offset; wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), - 0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags)); + wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer); + hr = wined3d_resource_map(wined3d_resource, 0, &wined3d_map_desc, &wined3d_box, + wined3dmapflags_from_d3dmapflags(flags, buffer->usage)); wined3d_mutex_unlock(); *data = wined3d_map_desc.data; @@ -229,7 +237,7 @@ static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface, desc->Format = D3DFMT_VERTEXDATA; desc->Type = D3DRTYPE_VERTEXBUFFER; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = buffer->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->FVF = buffer->fvf; @@ -261,6 +269,9 @@ static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl = static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent) { struct d3d8_vertexbuffer *buffer = parent; + + if (buffer->draw_buffer) + wined3d_buffer_decref(buffer->wined3d_buffer); d3d8_resource_cleanup(&buffer->resource); heap_free(buffer); } @@ -273,6 +284,7 @@ static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops = HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device, UINT size, DWORD usage, DWORD fvf, D3DPOOL pool) { + const struct wined3d_parent_ops *parent_ops = &d3d8_null_wined3d_parent_ops; struct wined3d_buffer_desc desc; HRESULT hr; @@ -282,21 +294,41 @@ HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device * return D3DERR_INVALIDCALL; } + /* In d3d8, buffers can't be used as rendertarget or depth/stencil buffer. */ + if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + return D3DERR_INVALIDCALL; + buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl; d3d8_resource_init(&buffer->resource); buffer->fvf = fvf; + buffer->usage = usage; desc.byte_width = size; desc.usage = usage & WINED3DUSAGE_MASK; - desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = 0; + desc.access = wined3daccess_from_d3dpool(pool, usage) | map_access_from_usage(usage); + /* Buffers are always readable. */ + if (pool != D3DPOOL_DEFAULT) + desc.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; + if (desc.access & WINED3D_RESOURCE_ACCESS_GPU) + { + desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; + parent_ops = &d3d8_vertexbuffer_wined3d_parent_ops; + } + wined3d_mutex_lock(); - hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, - &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer); + hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer); + if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, + &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->draw_buffer))) + wined3d_buffer_decref(buffer->wined3d_buffer); + } wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -354,7 +386,10 @@ static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface) { IDirect3DDevice8_AddRef(buffer->parent_device); wined3d_mutex_lock(); - wined3d_buffer_incref(buffer->wined3d_buffer); + if (buffer->draw_buffer) + wined3d_buffer_incref(buffer->draw_buffer); + else + wined3d_buffer_incref(buffer->wined3d_buffer); wined3d_mutex_unlock(); } @@ -370,10 +405,14 @@ static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface) if (!refcount) { + struct wined3d_buffer *draw_buffer = buffer->draw_buffer; IDirect3DDevice8 *device = buffer->parent_device; wined3d_mutex_lock(); - wined3d_buffer_decref(buffer->wined3d_buffer); + if (draw_buffer) + wined3d_buffer_decref(draw_buffer); + else + wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ @@ -480,6 +519,7 @@ static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT o BYTE **data, DWORD flags) { struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface); + struct wined3d_resource *wined3d_resource; struct wined3d_map_desc wined3d_map_desc; struct wined3d_box wined3d_box = {0}; HRESULT hr; @@ -490,8 +530,9 @@ static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT o wined3d_box.left = offset; wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), - 0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags)); + wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer); + hr = wined3d_resource_map(wined3d_resource, 0, &wined3d_map_desc, &wined3d_box, + wined3dmapflags_from_d3dmapflags(flags, buffer->usage)); wined3d_mutex_unlock(); *data = wined3d_map_desc.data; @@ -527,7 +568,7 @@ static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface, desc->Format = d3dformat_from_wined3dformat(buffer->format); desc->Type = D3DRTYPE_INDEXBUFFER; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = buffer->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; @@ -558,6 +599,9 @@ static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl = static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent) { struct d3d8_indexbuffer *buffer = parent; + + if (buffer->draw_buffer) + wined3d_buffer_decref(buffer->wined3d_buffer); d3d8_resource_cleanup(&buffer->resource); heap_free(buffer); } @@ -570,26 +614,48 @@ static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops = HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device, UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool) { + const struct wined3d_parent_ops *parent_ops = &d3d8_null_wined3d_parent_ops; struct wined3d_buffer_desc desc; HRESULT hr; + if (pool == D3DPOOL_SCRATCH) + return D3DERR_INVALIDCALL; + + /* In d3d8, buffers can't be used as rendertarget or depth/stencil buffer. */ + if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + return D3DERR_INVALIDCALL; + desc.byte_width = size; desc.usage = (usage & WINED3DUSAGE_MASK) | WINED3DUSAGE_STATICDECL; - if (pool == D3DPOOL_SCRATCH) - desc.usage |= WINED3DUSAGE_SCRATCH; - desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = 0; + desc.access = wined3daccess_from_d3dpool(pool, usage) | map_access_from_usage(usage); + /* Buffers are always readable. */ + if (pool != D3DPOOL_DEFAULT) + desc.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; + if (desc.access & WINED3D_RESOURCE_ACCESS_GPU) + { + desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; + parent_ops = &d3d8_indexbuffer_wined3d_parent_ops; + } + buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl; d3d8_resource_init(&buffer->resource); buffer->format = wined3dformat_from_d3dformat(format); + buffer->usage = usage; wined3d_mutex_lock(); - hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, - &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer); + hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer); + if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, + &d3d8_indexbuffer_wined3d_parent_ops, &buffer->draw_buffer))) + wined3d_buffer_decref(buffer->wined3d_buffer); + } wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dll/directx/wine/d3d8/d3d8.spec b/dll/directx/wine/d3d8/d3d8.spec index 4f125a9c1c1..8f3ff6c93e5 100644 --- a/dll/directx/wine/d3d8/d3d8.spec +++ b/dll/directx/wine/d3d8/d3d8.spec @@ -2,4 +2,4 @@ @ stdcall DebugSetMute() @ stdcall Direct3DCreate8(long) @ stdcall ValidatePixelShader(ptr ptr long ptr) -@ stdcall ValidateVertexShader(ptr ptr ptr long ptr) +@ stdcall ValidateVertexShader(ptr ptr long ptr) diff --git a/dll/directx/wine/d3d8/d3d8_main.c b/dll/directx/wine/d3d8/d3d8_main.c index 0e686308f05..345531f7700 100644 --- a/dll/directx/wine/d3d8/d3d8_main.c +++ b/dll/directx/wine/d3d8/d3d8_main.c @@ -19,7 +19,6 @@ * */ -#include "config.h" #include "initguid.h" #include "d3d8_private.h" #include "wine/debug.h" @@ -59,36 +58,47 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version) /*********************************************************************** * ValidateVertexShader (D3D8.@) */ -HRESULT WINAPI ValidateVertexShader(DWORD *vertexshader, DWORD *reserved1, DWORD *reserved2, - BOOL return_error, char **errors) +HRESULT WINAPI ValidateVertexShader(const DWORD *ps_code, + const D3DCAPS8 *caps, BOOL return_error, char **errors) { const char *message = ""; + SIZE_T message_size; HRESULT hr = E_FAIL; - TRACE("(%p %p %p %d %p): semi-stub\n", vertexshader, reserved1, reserved2, return_error, errors); + TRACE("ps_code %p, caps %p, return_error %#x, errors %p.\n", + ps_code, caps, return_error, errors); - if (!vertexshader) - { - message = "(Global Validation Error) Version Token: Code pointer cannot be NULL.\n"; - goto done; - } + if (!ps_code) + return E_FAIL; - switch (*vertexshader) + switch (*ps_code) { - case 0xFFFE0101: - case 0xFFFE0100: - hr = S_OK; + case D3DPS_VERSION(1, 4): + case D3DPS_VERSION(1, 3): + case D3DPS_VERSION(1, 2): + case D3DPS_VERSION(1, 1): + case D3DPS_VERSION(1, 0): break; default: - WARN("Invalid shader version token %#x.\n", *vertexshader); - message = "(Global Validation Error) Version Token: Unsupported vertex shader version.\n"; + message = "Unsupported shader version.\n"; + goto done; + } + + if (caps && *ps_code > caps->PixelShaderVersion) + { + message = "Shader version not supported by caps.\n"; + goto done; } + hr = S_OK; + done: - if (!return_error) message = ""; - if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1))) - strcpy(*errors, message); + if (!return_error) + message = ""; + message_size = strlen(message) + 1; + if (errors && (*errors = heap_alloc(message_size))) + memcpy(*errors, message, message_size); return hr; } @@ -96,12 +106,12 @@ HRESULT WINAPI ValidateVertexShader(DWORD *vertexshader, DWORD *reserved1, DWORD /*********************************************************************** * ValidatePixelShader (D3D8.@) */ -HRESULT WINAPI ValidatePixelShader(DWORD *pixelshader, DWORD *reserved1, BOOL return_error, char **errors) +HRESULT WINAPI ValidatePixelShader(DWORD *pixelshader, DWORD *reserved1, BOOL boolean, char **errors) { const char *message = ""; HRESULT hr = E_FAIL; - TRACE("(%p %p %d %p): semi-stub\n", pixelshader, reserved1, return_error, errors); + TRACE("(%p %p %d %p): semi-stub\n", pixelshader, reserved1, boolean, errors); if (!pixelshader) return E_FAIL; @@ -120,7 +130,7 @@ HRESULT WINAPI ValidatePixelShader(DWORD *pixelshader, DWORD *reserved1, BOOL re message = "(Global Validation Error) Version Token: Unsupported pixel shader version.\n"; } - if (!return_error) message = ""; + if (!boolean) message = ""; if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1))) strcpy(*errors, message); diff --git a/dll/directx/wine/d3d8/d3d8_private.h b/dll/directx/wine/d3d8/d3d8_private.h index cba5dd647b4..f262d12fc7a 100644 --- a/dll/directx/wine/d3d8/d3d8_private.h +++ b/dll/directx/wine/d3d8/d3d8_private.h @@ -39,10 +39,15 @@ #define D3DPRESENTFLAGS_MASK 0x00000fffu +#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256 +#define D3D8_MAX_STREAMS 16 + /* CreateVertexShader can return > 0xFFFF */ #define VS_HIGHESTFIXEDFXF 0xF0000000 -void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN; +extern const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops DECLSPEC_HIDDEN; + +void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const struct wined3d_caps *wined3d_caps) DECLSPEC_HIDDEN; struct d3d8 { @@ -118,12 +123,16 @@ struct d3d8_device UINT index_buffer_pos; LONG device_state; - /* Avoids recursion with nested ReleaseRef to 0 */ - BOOL inDestruction; + DWORD sysmem_vb : 16; /* D3D8_MAX_STREAMS */ + DWORD sysmem_ib : 1; + DWORD in_destruction : 1; + DWORD padding : 14; /* The d3d8 API supports only one implicit swapchain (no D3DCREATE_ADAPTERGROUP_DEVICE, * no GetSwapchain, GetBackBuffer doesn't accept a swapchain number). */ - struct d3d8_swapchain *implicit_swapchain; + struct wined3d_swapchain *implicit_swapchain; + + struct wined3d_stateblock *recording, *state, *update_state; }; HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter, @@ -166,10 +175,11 @@ struct d3d8_swapchain LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice8 *parent_device; + unsigned int swap_interval; }; HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc, - struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN; + unsigned int swap_interval, struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN; struct d3d8_surface { @@ -198,7 +208,8 @@ struct d3d8_vertexbuffer struct d3d8_resource resource; struct wined3d_buffer *wined3d_buffer; IDirect3DDevice8 *parent_device; - DWORD fvf; + struct wined3d_buffer *draw_buffer; + DWORD fvf, usage; }; HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device, @@ -211,7 +222,9 @@ struct d3d8_indexbuffer struct d3d8_resource resource; struct wined3d_buffer *wined3d_buffer; IDirect3DDevice8 *parent_device; + struct wined3d_buffer *draw_buffer; enum wined3d_format_id format; + DWORD usage; }; HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device, @@ -239,6 +252,7 @@ struct d3d8_vertex_declaration { DWORD *elements; DWORD elements_size; /* Size of elements, in bytes */ + DWORD stream_map; struct wined3d_vertex_declaration *wined3d_vertex_declaration; DWORD shader_handle; }; @@ -259,8 +273,6 @@ void d3d8_vertex_shader_destroy(struct d3d8_vertex_shader *shader) DECLSPEC_HIDD HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_device *device, const DWORD *declaration, const DWORD *byte_code, DWORD shader_handle, DWORD usage) DECLSPEC_HIDDEN; -#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256 - struct d3d8_pixel_shader { DWORD handle; @@ -273,13 +285,18 @@ HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_dev D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN; -unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN; +unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags, unsigned int usage) DECLSPEC_HIDDEN; void load_local_constants(const DWORD *d3d8_elements, struct wined3d_shader *wined3d_vertex_shader) DECLSPEC_HIDDEN; size_t parse_token(const DWORD *pToken) DECLSPEC_HIDDEN; -static inline DWORD d3dusage_from_wined3dusage(unsigned int usage) +static inline DWORD d3dusage_from_wined3dusage(unsigned int wined3d_usage, unsigned int bind_flags) { - return usage & WINED3DUSAGE_MASK; + DWORD usage = wined3d_usage & WINED3DUSAGE_MASK; + if (bind_flags & WINED3D_BIND_RENDER_TARGET) + usage |= D3DUSAGE_RENDERTARGET; + if (bind_flags & WINED3D_BIND_DEPTH_STENCIL) + usage |= D3DUSAGE_DEPTHSTENCIL; + return usage; } static inline D3DPOOL d3dpool_from_wined3daccess(unsigned int access, unsigned int usage) @@ -298,23 +315,47 @@ static inline D3DPOOL d3dpool_from_wined3daccess(unsigned int access, unsigned i } } +static inline unsigned int map_access_from_usage(unsigned int usage) +{ + if (usage & D3DUSAGE_WRITEONLY) + return WINED3D_RESOURCE_ACCESS_MAP_W; + return WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; +} + static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool, unsigned int usage) { + unsigned int access; + switch (pool) { case D3DPOOL_DEFAULT: - if (usage & D3DUSAGE_DYNAMIC) - return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - return WINED3D_RESOURCE_ACCESS_GPU; + access = WINED3D_RESOURCE_ACCESS_GPU; + break; case D3DPOOL_MANAGED: - return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU; + break; case D3DPOOL_SYSTEMMEM: case D3DPOOL_SCRATCH: - return WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + access = WINED3D_RESOURCE_ACCESS_CPU; + break; default: - return 0; + access = 0; } + if (pool != D3DPOOL_DEFAULT || usage & D3DUSAGE_DYNAMIC) + access |= map_access_from_usage(usage); + return access; +} + +static inline unsigned int wined3d_bind_flags_from_d3d8_usage(DWORD usage) +{ + unsigned int bind_flags = 0; + + if (usage & D3DUSAGE_RENDERTARGET) + bind_flags |= WINED3D_BIND_RENDER_TARGET; + if (usage & D3DUSAGE_DEPTHSTENCIL) + bind_flags |= WINED3D_BIND_DEPTH_STENCIL; + + return bind_flags; } #endif /* __WINE_D3DX8_PRIVATE_H */ diff --git a/dll/directx/wine/d3d8/device.c b/dll/directx/wine/d3d8/device.c index 5daf6f46c2a..cc1409d5c1d 100644 --- a/dll/directx/wine/d3d8/device.c +++ b/dll/directx/wine/d3d8/device.c @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -36,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d8); static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {} -static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops = +const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops = { d3d8_null_wined3d_object_destroyed, }; @@ -141,7 +139,7 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) } } -unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) +unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags, unsigned int usage) { static const unsigned int handled = D3DLOCK_NOSYSLOCK | D3DLOCK_NOOVERWRITE @@ -150,12 +148,12 @@ unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) unsigned int wined3d_flags; wined3d_flags = flags & handled; - if (!(flags & (D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD))) + if (~usage & D3DUSAGE_WRITEONLY && !(flags & (D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD))) wined3d_flags |= WINED3D_MAP_READ; if (!(flags & D3DLOCK_READONLY)) wined3d_flags |= WINED3D_MAP_WRITE; if (!(wined3d_flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE))) - wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE; + wined3d_flags |= WINED3D_MAP_WRITE; flags &= ~(handled | D3DLOCK_READONLY); if (flags) @@ -209,7 +207,7 @@ static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effe } static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, - const struct wined3d_swapchain_desc *swapchain_desc) + const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) { present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height; @@ -224,7 +222,7 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; - present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval; + present_parameters->FullScreen_PresentationInterval = presentation_interval; } static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect) @@ -245,6 +243,27 @@ static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFE } } +static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval) +{ + switch (interval) + { + case D3DPRESENT_INTERVAL_IMMEDIATE: + return WINED3D_SWAP_INTERVAL_IMMEDIATE; + case D3DPRESENT_INTERVAL_ONE: + return WINED3D_SWAP_INTERVAL_ONE; + case D3DPRESENT_INTERVAL_TWO: + return WINED3D_SWAP_INTERVAL_TWO; + case D3DPRESENT_INTERVAL_THREE: + return WINED3D_SWAP_INTERVAL_THREE; + case D3DPRESENT_INTERVAL_FOUR: + return WINED3D_SWAP_INTERVAL_FOUR; + default: + FIXME("Unhandled presentation interval %#x.\n", interval); + case D3DPRESENT_INTERVAL_DEFAULT: + return WINED3D_SWAP_INTERVAL_DEFAULT; + } +} + static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, const D3DPRESENT_PARAMETERS *present_parameters) { @@ -261,12 +280,26 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); return FALSE; } + switch (present_parameters->FullScreen_PresentationInterval) + { + case D3DPRESENT_INTERVAL_DEFAULT: + case D3DPRESENT_INTERVAL_ONE: + case D3DPRESENT_INTERVAL_TWO: + case D3DPRESENT_INTERVAL_THREE: + case D3DPRESENT_INTERVAL_FOUR: + case D3DPRESENT_INTERVAL_IMMEDIATE: + break; + default: + WARN("Invalid presentation interval %#x.\n", + present_parameters->FullScreen_PresentationInterval); + return FALSE; + } swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat); swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount); - swapchain_desc->backbuffer_usage = WINED3DUSAGE_RENDERTARGET; + swapchain_desc->backbuffer_bind_flags = WINED3D_BIND_RENDER_TARGET; swapchain_desc->multisample_type = present_parameters->MultiSampleType; swapchain_desc->multisample_quality = 0; /* d3d9 only */ swapchain_desc->swap_effect = wined3dswapeffect_from_d3dswapeffect(present_parameters->SwapEffect); @@ -278,7 +311,6 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->flags = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; - swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) @@ -287,14 +319,14 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch return TRUE; } -void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) +void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const struct wined3d_caps *wined3d_caps) { caps->DeviceType = (D3DDEVTYPE)wined3d_caps->DeviceType; caps->AdapterOrdinal = wined3d_caps->AdapterOrdinal; caps->Caps = wined3d_caps->Caps; caps->Caps2 = wined3d_caps->Caps2; caps->Caps3 = wined3d_caps->Caps3; - caps->PresentationIntervals = wined3d_caps->PresentationIntervals; + caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE; caps->CursorCaps = wined3d_caps->CursorCaps; caps->DevCaps = wined3d_caps->DevCaps; caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; @@ -343,6 +375,59 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion; caps->MaxPixelShaderValue = wined3d_caps->PixelShader1xMaxValue; + caps->Caps2 &= D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_CANRENDERWINDOWED + | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA + | D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_RESERVED; + caps->Caps3 &= D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_RESERVED; + caps->PrimitiveMiscCaps &= D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP + | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW + | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS + | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP + | D3DPMISCCAPS_NULLREFERENCE; + caps->RasterCaps &= D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST + | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_ANTIALIASEDGES + | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR + | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER + | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE + | D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE | WINED3DPRASTERCAPS_DEPTHBIAS; + if (caps->RasterCaps & WINED3DPRASTERCAPS_DEPTHBIAS) + caps->RasterCaps = (caps->RasterCaps | D3DPRASTERCAPS_ZBIAS) & ~WINED3DPRASTERCAPS_DEPTHBIAS; + caps->SrcBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR + | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA + | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR + | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA + | D3DPBLENDCAPS_BOTHINVSRCALPHA; + caps->DestBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR + | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA + | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR + | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA + | D3DPBLENDCAPS_BOTHINVSRCALPHA; + caps->TextureCaps &= D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA + | D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE + | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL + | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP + | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP + | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2; + caps->TextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR + | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT + | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR + | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC + | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; + caps->CubeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR + | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT + | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR + | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC + | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; + caps->VolumeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR + | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT + | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR + | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC + | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC; + caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; + caps->VertexProcessingCaps &= D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 + | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER + | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_NO_VSDT_UBYTE4; + /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */ if (caps->PixelShaderVersion) caps->PixelShaderVersion = D3DPS_VERSION(1, 4); @@ -353,8 +438,6 @@ void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) else caps->VertexShaderVersion = D3DVS_VERSION(0, 0); caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); - - caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; } /* Handle table functions */ @@ -481,7 +564,7 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface) struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); ULONG ref; - if (device->inDestruction) + if (device->in_destruction) return 0; ref = InterlockedDecrement(&device->ref); @@ -497,7 +580,7 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface) wined3d_mutex_lock(); - device->inDestruction = TRUE; + device->in_destruction = TRUE; for (i = 0; i < device->numConvertedDecls; ++i) { @@ -510,7 +593,11 @@ static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface) if (device->index_buffer) wined3d_buffer_decref(device->index_buffer); - wined3d_device_uninit_3d(device->wined3d_device); + if (device->recording) + wined3d_stateblock_decref(device->recording); + wined3d_stateblock_decref(device->state); + + wined3d_swapchain_decref(device->implicit_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); heap_free(device->handle_table.entries); @@ -588,7 +675,7 @@ static HRESULT WINAPI d3d8_device_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *caps) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - WINED3DCAPS wined3d_caps; + struct wined3d_caps wined3d_caps; HRESULT hr; TRACE("iface %p, caps %p.\n", iface, caps); @@ -698,7 +785,8 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct wined3d_swapchain_desc desc; struct d3d8_swapchain *object; - UINT i, count; + unsigned int swap_interval; + unsigned int i, count; HRESULT hr; TRACE("iface %p, present_parameters %p, swapchain %p.\n", @@ -730,15 +818,19 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters)) return D3DERR_INVALIDCALL; - if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object))) + swap_interval = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval); + if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, swap_interval, &object))) *swapchain = &object->IDirect3DSwapChain8_iface; - present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); + present_parameters_from_wined3d_swapchain_desc(present_parameters, + &desc, present_parameters->FullScreen_PresentationInterval); return hr; } static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) { + struct d3d8_vertexbuffer *vertex_buffer; + struct d3d8_indexbuffer *index_buffer; struct wined3d_resource_desc desc; IDirect3DBaseTexture8 *texture; struct d3d8_surface *surface; @@ -750,6 +842,19 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D) { + if (desc.bind_flags & WINED3D_BIND_VERTEX_BUFFER) + { + vertex_buffer = wined3d_resource_get_parent(resource); + if (vertex_buffer && vertex_buffer->draw_buffer) + return D3D_OK; + } + if (desc.bind_flags & WINED3D_BIND_INDEX_BUFFER) + { + index_buffer = wined3d_resource_get_parent(resource); + if (index_buffer && index_buffer->draw_buffer) + return D3D_OK; + } + WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); return D3DERR_DEVICELOST; } @@ -775,6 +880,7 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct wined3d_swapchain_desc swapchain_desc; + struct d3d8_swapchain *implicit_swapchain; HRESULT hr; TRACE("iface %p, present_parameters %p.\n", iface, present_parameters); @@ -786,6 +892,7 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, } if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters)) return D3DERR_INVALIDCALL; + swapchain_desc.flags |= WINED3D_SWAPCHAIN_IMPLICIT; wined3d_mutex_lock(); @@ -805,7 +912,14 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, NULL, reset_enum_callback, TRUE))) { + if (device->recording) + wined3d_stateblock_decref(device->recording); + device->recording = NULL; + device->update_state = device->state; present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; + implicit_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchain); + implicit_swapchain->swap_interval + = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); @@ -824,6 +938,7 @@ static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *s const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + struct d3d8_swapchain *implicit_swapchain; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n", iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region); @@ -833,7 +948,8 @@ static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *s * shows a framerate on Windows in applications that only call the device * method, like e.g. the dx8 sdk samples. The conclusion is that native * calls the swapchain's public method from the device. */ - return IDirect3DSwapChain8_Present(&device->implicit_swapchain->IDirect3DSwapChain8_iface, + implicit_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchain); + return IDirect3DSwapChain8_Present(&implicit_swapchain->IDirect3DSwapChain8_iface, src_rect, dst_rect, dst_window_override, dirty_region); } @@ -841,7 +957,6 @@ static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface, UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - struct wined3d_swapchain *wined3d_swapchain; struct wined3d_texture *wined3d_texture; struct d3d8_surface *surface_impl; @@ -853,8 +968,7 @@ static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface, /* No need to check for backbuffer == NULL, Windows crashes in that case. */ wined3d_mutex_lock(); - wined3d_swapchain = device->implicit_swapchain->wined3d_swapchain; - if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(wined3d_swapchain, backbuffer_idx))) + if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(device->implicit_swapchain, backbuffer_idx))) { wined3d_mutex_unlock(); *backbuffer = NULL; @@ -1056,29 +1170,26 @@ static HRESULT WINAPI d3d8_device_CreateIndexBuffer(IDirect3DDevice8 *iface, UIN return D3D_OK; } -static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width, UINT height, - D3DFORMAT format, DWORD flags, IDirect3DSurface8 **surface, UINT usage, D3DPOOL pool, - D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) +static HRESULT d3d8_device_create_surface(struct d3d8_device *device, enum wined3d_format_id format, + enum wined3d_multisample_type multisample_type, unsigned int bind_flags, unsigned int access, + unsigned int width, unsigned int height, IDirect3DSurface8 **surface) { struct wined3d_resource_desc desc; struct d3d8_surface *surface_impl; struct wined3d_texture *texture; HRESULT hr; - TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p, " - "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n", - device, width, height, format, flags, surface, - usage, pool, multisample_type, multisample_quality); + TRACE("device %p, format %#x, multisample_type %#x, bind_flags %#x, " + "access %#x, width %u, height %u, surface %p.\n", + device, format, multisample_type, bind_flags, access, width, height, surface); desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = wined3dformat_from_d3dformat(format); + desc.format = format; desc.multisample_type = multisample_type; - desc.multisample_quality = multisample_quality; - desc.usage = usage & WINED3DUSAGE_MASK; - if (pool == D3DPOOL_SCRATCH) - desc.usage |= WINED3DUSAGE_SCRATCH; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.multisample_quality = 0; + desc.usage = 0; + desc.bind_flags = bind_flags; + desc.access = access; desc.width = width; desc.height = height; desc.depth = 1; @@ -1087,7 +1198,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width wined3d_mutex_lock(); if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, - 1, 1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture))) + 1, 1, 0, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); WARN("Failed to create texture, hr %#x.\n", hr); @@ -1110,7 +1221,7 @@ static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UI IDirect3DSurface8 **surface) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - DWORD flags = 0; + unsigned int access = WINED3D_RESOURCE_ACCESS_GPU; TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n", iface, width, height, format, multisample_type, lockable, surface); @@ -1120,10 +1231,10 @@ static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UI *surface = NULL; if (lockable) - flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - return d3d8_device_create_surface(device, width, height, format, flags, surface, - D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0); + return d3d8_device_create_surface(device, wined3dformat_from_d3dformat(format), + multisample_type, WINED3D_BIND_RENDER_TARGET, access, width, height, surface); } static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *iface, @@ -1140,9 +1251,9 @@ static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *if *surface = NULL; - /* TODO: Verify that Discard is false */ - return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE, - surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0); + return d3d8_device_create_surface(device, wined3dformat_from_d3dformat(format), + multisample_type, WINED3D_BIND_DEPTH_STENCIL, + WINED3D_RESOURCE_ACCESS_GPU, width, height, surface); } /* IDirect3DDevice8Impl::CreateImageSurface returns surface with pool type SYSTEMMEM */ @@ -1150,14 +1261,16 @@ static HRESULT WINAPI d3d8_device_CreateImageSurface(IDirect3DDevice8 *iface, UI UINT height, D3DFORMAT format, IDirect3DSurface8 **surface) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + unsigned int access = WINED3D_RESOURCE_ACCESS_CPU + | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n", iface, width, height, format, surface); *surface = NULL; - return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE, - surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0); + return d3d8_device_create_surface(device, wined3dformat_from_d3dformat(format), + WINED3D_MULTISAMPLE_NONE, 0, access, width, height, surface); } static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, @@ -1178,7 +1291,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, wined3d_mutex_lock(); wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &wined3d_desc); - if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) + if (wined3d_desc.bind_flags & WINED3D_BIND_DEPTH_STENCIL) { WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", src_surface); wined3d_mutex_unlock(); @@ -1189,7 +1302,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, src_h = wined3d_desc.height; wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &wined3d_desc); - if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) + if (wined3d_desc.bind_flags & WINED3D_BIND_DEPTH_STENCIL) { WARN("Destination %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", dst_surface); wined3d_mutex_unlock(); @@ -1283,7 +1396,7 @@ static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirec } wined3d_mutex_lock(); - hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain->wined3d_swapchain, + hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain, dst_impl->wined3d_texture, dst_impl->sub_resource_idx); wined3d_mutex_unlock(); @@ -1350,12 +1463,15 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, original_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device); rtv = ds_impl ? d3d8_surface_acquire_rendertarget_view(ds_impl) : NULL; - wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); + hr = wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); d3d8_surface_release_rendertarget_view(ds_impl, rtv); - rtv = render_target ? d3d8_surface_acquire_rendertarget_view(rt_impl) : NULL; - if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0, rtv, TRUE))) - wined3d_device_set_depth_stencil_view(device->wined3d_device, original_dsv); - d3d8_surface_release_rendertarget_view(rt_impl, rtv); + if (SUCCEEDED(hr)) + { + rtv = render_target ? d3d8_surface_acquire_rendertarget_view(rt_impl) : NULL; + if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0, rtv, TRUE))) + wined3d_device_set_depth_stencil_view(device->wined3d_device, original_dsv); + d3d8_surface_release_rendertarget_view(rt_impl, rtv); + } wined3d_mutex_unlock(); @@ -1531,10 +1647,30 @@ static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface, static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; + struct d3d8_surface *surface; struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); + wined3d_mutex_lock(); + if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + { + wined3d_mutex_unlock(); + return D3DERR_NOTFOUND; + } + surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); + + if (viewport->X > rt_desc.width || viewport->Width > rt_desc.width - viewport->X + || viewport->Y > rt_desc.height || viewport->Height > rt_desc.height - viewport->Y) + { + WARN("Invalid viewport, returning D3DERR_INVALIDCALL.\n"); + wined3d_mutex_unlock(); + return D3DERR_INVALIDCALL; + } + vp.x = viewport->X; vp.y = viewport->Y; vp.width = viewport->Width; @@ -1542,8 +1678,7 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3D vp.min_z = viewport->MinZ; vp.max_z = viewport->MaxZ; - wined3d_mutex_lock(); - wined3d_device_set_viewport(device->wined3d_device, &vp); + wined3d_device_set_viewports(device->wined3d_device, 1, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -1557,7 +1692,7 @@ static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPO TRACE("iface %p, viewport %p.\n", iface, viewport); wined3d_mutex_lock(); - wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); + wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport); wined3d_mutex_unlock(); viewport->X = wined3d_viewport.x; @@ -1692,15 +1827,11 @@ static HRESULT WINAPI d3d8_device_SetRenderState(IDirect3DDevice8 *iface, TRACE("iface %p, state %#x, value %#x.\n", iface, state, value); wined3d_mutex_lock(); - switch (state) - { - case D3DRS_ZBIAS: - wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, value); - break; - - default: - wined3d_device_set_render_state(device->wined3d_device, state, value); - } + if (state == D3DRS_ZBIAS) + state = WINED3D_RS_DEPTHBIAS; + wined3d_stateblock_set_render_state(device->update_state, state, value); + if (!device->recording) + wined3d_device_set_render_state(device->wined3d_device, state, value); wined3d_mutex_unlock(); return D3D_OK; @@ -1731,12 +1862,14 @@ static HRESULT WINAPI d3d8_device_GetRenderState(IDirect3DDevice8 *iface, static HRESULT WINAPI d3d8_device_BeginStateBlock(IDirect3DDevice8 *iface) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + struct wined3d_stateblock *stateblock; HRESULT hr; TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_device_begin_stateblock(device->wined3d_device); + if (SUCCEEDED(hr = wined3d_device_begin_stateblock(device->wined3d_device, &stateblock))) + device->update_state = device->recording = stateblock; wined3d_mutex_unlock(); return hr; @@ -1754,13 +1887,16 @@ static HRESULT WINAPI d3d8_device_EndStateBlock(IDirect3DDevice8 *iface, DWORD * * of memory later and cause locking problems) */ wined3d_mutex_lock(); - hr = wined3d_device_end_stateblock(device->wined3d_device, &stateblock); + hr = wined3d_device_end_stateblock(device->wined3d_device); if (FAILED(hr)) { WARN("Failed to end the state block, %#x.\n", hr); wined3d_mutex_unlock(); return hr; } + stateblock = device->recording; + device->recording = NULL; + device->update_state = device->state; *token = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB); wined3d_mutex_unlock(); @@ -1784,6 +1920,11 @@ static HRESULT WINAPI d3d8_device_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct wined3d_stateblock *stateblock; + struct wined3d_buffer *wined3d_buffer; + struct d3d8_vertexbuffer *buffer; + unsigned int i, offset, stride; + enum wined3d_format_id format; + HRESULT hr; TRACE("iface %p, token %#x.\n", iface, token); @@ -1791,6 +1932,12 @@ static HRESULT WINAPI d3d8_device_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD return D3D_OK; wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to apply stateblock while recording, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB); if (!stateblock) { @@ -1799,6 +1946,19 @@ static HRESULT WINAPI d3d8_device_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD return D3DERR_INVALIDCALL; } wined3d_stateblock_apply(stateblock); + device->sysmem_vb = 0; + for (i = 0; i < D3D8_MAX_STREAMS; ++i) + { + if (FAILED(hr = wined3d_device_get_stream_source(device->wined3d_device, + i, &wined3d_buffer, &offset, &stride))) + continue; + if (!wined3d_buffer || !(buffer = wined3d_buffer_get_parent(wined3d_buffer))) + continue; + if (buffer->draw_buffer) + device->sysmem_vb |= 1u << i; + } + device->sysmem_ib = (wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &format, &offset)) + && (buffer = wined3d_buffer_get_parent(wined3d_buffer)) && buffer->draw_buffer; wined3d_mutex_unlock(); return D3D_OK; @@ -1812,6 +1972,12 @@ static HRESULT WINAPI d3d8_device_CaptureStateBlock(IDirect3DDevice8 *iface, DWO TRACE("iface %p, token %#x.\n", iface, token); wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to capture stateblock while recording, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB); if (!stateblock) { @@ -1869,6 +2035,12 @@ static HRESULT WINAPI d3d8_device_CreateStateBlock(IDirect3DDevice8 *iface, } wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to create a stateblock while recording, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } hr = wined3d_stateblock_create(device->wined3d_device, (enum wined3d_stateblock_type)type, &stateblock); if (FAILED(hr)) { @@ -1955,18 +2127,17 @@ static HRESULT WINAPI d3d8_device_SetTexture(IDirect3DDevice8 *iface, DWORD stag { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_texture *texture_impl; - HRESULT hr; TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); texture_impl = unsafe_impl_from_IDirect3DBaseTexture8(texture); wined3d_mutex_lock(); - hr = wined3d_device_set_texture(device->wined3d_device, stage, + wined3d_device_set_texture(device->wined3d_device, stage, texture_impl ? texture_impl->wined3d_texture : NULL); wined3d_mutex_unlock(); - return hr; + return D3D_OK; } static const struct tss_lookup @@ -2019,7 +2190,7 @@ static HRESULT WINAPI d3d8_device_GetTextureStageState(IDirect3DDevice8 *iface, TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, Type, value); - if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup)) + if (Type >= ARRAY_SIZE(tss_lookup)) { WARN("Invalid Type %#x passed.\n", Type); return D3D_OK; @@ -2045,7 +2216,7 @@ static HRESULT WINAPI d3d8_device_SetTextureStageState(IDirect3DDevice8 *iface, TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, type, value); - if (type >= sizeof(tss_lookup) / sizeof(*tss_lookup)) + if (type >= ARRAY_SIZE(tss_lookup)) { WARN("Invalid type %#x passed.\n", type); return D3D_OK; @@ -2080,9 +2251,11 @@ static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface, DWORD info_id, void *info, DWORD info_size) { - FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size); + TRACE("iface %p, info_id %#x, info %p, info_size %u.\n", iface, info_id, info, info_size); - return D3D_OK; + if (info_id < 4) + return E_FAIL; + return S_FALSE; } static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface, @@ -2118,19 +2291,90 @@ static HRESULT WINAPI d3d8_device_GetCurrentTexturePalette(IDirect3DDevice8 *ifa return D3DERR_INVALIDCALL; } +static void d3d8_device_upload_sysmem_vertex_buffers(struct d3d8_device *device, + unsigned int start_vertex, unsigned int vertex_count) +{ + struct wined3d_vertex_declaration *wined3d_decl; + struct wined3d_box box = {0, 0, 0, 1, 0, 1}; + struct d3d8_vertexbuffer *d3d8_buffer; + struct wined3d_resource *dst_resource; + struct d3d8_vertex_declaration *decl; + unsigned int i, offset, stride, map; + struct wined3d_buffer *dst_buffer; + struct wined3d_resource_desc desc; + HRESULT hr; + + if (!device->sysmem_vb) + return; + + wined3d_decl = wined3d_device_get_vertex_declaration(device->wined3d_device); + if (!wined3d_decl) + return; + + decl = wined3d_vertex_declaration_get_parent(wined3d_decl); + map = decl->stream_map & device->sysmem_vb; + while (map) + { + i = wined3d_bit_scan(&map); + + if (FAILED(hr = wined3d_device_get_stream_source(device->wined3d_device, i, &dst_buffer, &offset, &stride))) + ERR("Failed to get stream source.\n"); + d3d8_buffer = wined3d_buffer_get_parent(dst_buffer); + dst_resource = wined3d_buffer_get_resource(dst_buffer); + wined3d_resource_get_desc(dst_resource, &desc); + box.left = offset + start_vertex * stride; + box.right = min(box.left + vertex_count * stride, desc.size); + if (FAILED(hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, + dst_resource, 0, box.left, 0, 0, + wined3d_buffer_get_resource(d3d8_buffer->wined3d_buffer), 0, &box, 0))) + ERR("Failed to update buffer.\n"); + } +} + +static void d3d8_device_upload_sysmem_index_buffer(struct d3d8_device *device, + unsigned int start_idx, unsigned int idx_count) +{ + struct wined3d_box box = {0, 0, 0, 1, 0, 1}; + struct wined3d_resource *dst_resource; + struct d3d8_indexbuffer *d3d8_buffer; + struct wined3d_buffer *dst_buffer; + struct wined3d_resource_desc desc; + enum wined3d_format_id format; + unsigned int offset, idx_size; + HRESULT hr; + + if (!device->sysmem_ib) + return; + + if (!(dst_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &format, &offset))) + ERR("Failed to get index buffer.\n"); + d3d8_buffer = wined3d_buffer_get_parent(dst_buffer); + dst_resource = wined3d_buffer_get_resource(dst_buffer); + wined3d_resource_get_desc(dst_resource, &desc); + idx_size = format == WINED3DFMT_R16_UINT ? 2 : 4; + box.left = offset + start_idx * idx_size; + box.right = min(box.left + idx_count * idx_size, desc.size); + if (FAILED(hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, + dst_resource, 0, box.left, 0, 0, + wined3d_buffer_get_resource(d3d8_buffer->wined3d_buffer), 0, &box, 0))) + ERR("Failed to update buffer.\n"); +} + static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface, D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + unsigned int vertex_count; HRESULT hr; TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n", iface, primitive_type, start_vertex, primitive_count); + vertex_count = vertex_count_from_primitive_count(primitive_type, primitive_count); wined3d_mutex_lock(); + d3d8_device_upload_sysmem_vertex_buffers(device, start_vertex, vertex_count); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); - hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, - vertex_count_from_primitive_count(primitive_type, primitive_count)); + hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count); wined3d_mutex_unlock(); return hr; @@ -2141,15 +2385,20 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface, UINT start_idx, UINT primitive_count) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + unsigned int index_count; + int base_vertex_index; HRESULT hr; TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n", iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count); + index_count = vertex_count_from_primitive_count(primitive_type, primitive_count); wined3d_mutex_lock(); + base_vertex_index = wined3d_device_get_base_vertex_index(device->wined3d_device); + d3d8_device_upload_sysmem_vertex_buffers(device, base_vertex_index + min_vertex_idx, vertex_count); + d3d8_device_upload_sysmem_index_buffer(device, start_idx, index_count); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); - hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, - vertex_count_from_primitive_count(primitive_type, primitive_count)); + hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, index_count); wined3d_mutex_unlock(); return hr; @@ -2169,9 +2418,9 @@ static HRESULT d3d8_device_prepare_vertex_buffer(struct d3d8_device *device, UIN TRACE("Growing vertex buffer to %u bytes\n", size); desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY; + desc.usage = WINED3DUSAGE_DYNAMIC; desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -2208,9 +2457,9 @@ static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface, TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n", iface, primitive_type, primitive_count, data, stride); - if (!primitive_count) + if (!primitive_count || !stride) { - WARN("primitive_count is 0, returning D3D_OK\n"); + WARN("primitive_count or stride is 0, returning D3D_OK.\n"); return D3D_OK; } @@ -2264,9 +2513,9 @@ static HRESULT d3d8_device_prepare_index_buffer(struct d3d8_device *device, UINT TRACE("Growing index buffer to %u bytes\n", size); desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL; + desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_STATICDECL; desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -2308,9 +2557,9 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface iface, primitive_type, min_vertex_idx, vertex_count, primitive_count, index_data, index_format, vertex_data, vertex_stride); - if (!primitive_count) + if (!primitive_count || !vertex_stride) { - WARN("primitive_count is 0, returning D3D_OK\n"); + WARN("primitive_count or vertex_stride is 0, returning D3D_OK.\n"); return D3D_OK; } @@ -2385,14 +2634,52 @@ static HRESULT WINAPI d3d8_device_ProcessVertices(IDirect3DDevice8 *iface, UINT { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_vertexbuffer *dst = unsafe_impl_from_IDirect3DVertexBuffer8(dst_buffer); + struct d3d8_vertexbuffer *d3d8_buffer; + struct wined3d_buffer *wined3d_buffer; + unsigned int i, offset, stride, map; HRESULT hr; TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, flags %#x.\n", iface, src_start_idx, dst_idx, vertex_count, dst_buffer, flags); wined3d_mutex_lock(); + + /* Note that an alternative approach would be to simply create these + * buffers with WINED3D_RESOURCE_ACCESS_MAP_R and update them here like we + * do for draws. In some regards that would be easier, but it seems less + * than optimal to upload data to the GPU only to subsequently download it + * again. */ + map = device->sysmem_vb; + while (map) + { + i = wined3d_bit_scan(&map); + + if (FAILED(wined3d_device_get_stream_source(device->wined3d_device, + i, &wined3d_buffer, &offset, &stride))) + ERR("Failed to get stream source.\n"); + d3d8_buffer = wined3d_buffer_get_parent(wined3d_buffer); + if (FAILED(wined3d_device_set_stream_source(device->wined3d_device, + i, d3d8_buffer->wined3d_buffer, offset, stride))) + ERR("Failed to set stream source.\n"); + } + hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, vertex_count, dst->wined3d_buffer, NULL, flags, dst->fvf); + + map = device->sysmem_vb; + while (map) + { + i = wined3d_bit_scan(&map); + + if (FAILED(wined3d_device_get_stream_source(device->wined3d_device, + i, &wined3d_buffer, &offset, &stride))) + ERR("Failed to get stream source.\n"); + d3d8_buffer = wined3d_buffer_get_parent(wined3d_buffer); + if (FAILED(wined3d_device_set_stream_source(device->wined3d_device, + i, d3d8_buffer->draw_buffer, offset, stride))) + ERR("Failed to set stream source.\n"); + } + wined3d_mutex_unlock(); return hr; @@ -2523,9 +2810,15 @@ static HRESULT WINAPI d3d8_device_SetVertexShader(IDirect3DDevice8 *iface, DWORD TRACE("Setting FVF, %#x\n", shader); wined3d_mutex_lock(); - wined3d_device_set_vertex_declaration(device->wined3d_device, + wined3d_stateblock_set_vertex_declaration(device->update_state, d3d8_device_get_fvf_declaration(device, shader)->wined3d_vertex_declaration); - wined3d_device_set_vertex_shader(device->wined3d_device, NULL); + wined3d_stateblock_set_vertex_shader(device->update_state, NULL); + if (!device->recording) + { + wined3d_device_set_vertex_declaration(device->wined3d_device, + d3d8_device_get_fvf_declaration(device, shader)->wined3d_vertex_declaration); + wined3d_device_set_vertex_shader(device->wined3d_device, NULL); + } wined3d_mutex_unlock(); return D3D_OK; @@ -2542,9 +2835,15 @@ static HRESULT WINAPI d3d8_device_SetVertexShader(IDirect3DDevice8 *iface, DWORD return D3DERR_INVALIDCALL; } - wined3d_device_set_vertex_declaration(device->wined3d_device, + wined3d_stateblock_set_vertex_declaration(device->update_state, shader_impl->vertex_declaration->wined3d_vertex_declaration); - wined3d_device_set_vertex_shader(device->wined3d_device, shader_impl->wined3d_shader); + wined3d_stateblock_set_vertex_shader(device->update_state, shader_impl->wined3d_shader); + if (!device->recording) + { + wined3d_device_set_vertex_declaration(device->wined3d_device, + shader_impl->vertex_declaration->wined3d_vertex_declaration); + wined3d_device_set_vertex_shader(device->wined3d_device, shader_impl->wined3d_shader); + } wined3d_mutex_unlock(); return D3D_OK; @@ -2619,7 +2918,9 @@ static HRESULT WINAPI d3d8_device_SetVertexShaderConstant(IDirect3DDevice8 *ifac } wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, count, data); + hr = wined3d_stateblock_set_vs_consts_f(device->update_state, start_register, count, data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, count, data); wined3d_mutex_unlock(); return hr; @@ -2723,9 +3024,17 @@ static HRESULT WINAPI d3d8_device_SetIndices(IDirect3DDevice8 *iface, { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer8(buffer); + struct wined3d_buffer *wined3d_buffer; TRACE("iface %p, buffer %p, base_vertex_idx %u.\n", iface, buffer, base_vertex_idx); + if (!ib) + wined3d_buffer = NULL; + else if (ib->draw_buffer) + wined3d_buffer = ib->draw_buffer; + else + wined3d_buffer = ib->wined3d_buffer; + /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large * vertex buffers can't be created to address them with an index that requires the 32nd bit @@ -2734,8 +3043,9 @@ static HRESULT WINAPI d3d8_device_SetIndices(IDirect3DDevice8 *iface, */ wined3d_mutex_lock(); wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); - wined3d_device_set_index_buffer(device->wined3d_device, - ib ? ib->wined3d_buffer : NULL, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); + wined3d_device_set_index_buffer(device->wined3d_device, wined3d_buffer, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); + if (!device->recording) + device->sysmem_ib = ib && ib->draw_buffer; wined3d_mutex_unlock(); return D3D_OK; @@ -2830,7 +3140,9 @@ static HRESULT WINAPI d3d8_device_SetPixelShader(IDirect3DDevice8 *iface, DWORD if (!shader) { - wined3d_device_set_pixel_shader(device->wined3d_device, NULL); + wined3d_stateblock_set_pixel_shader(device->update_state, NULL); + if (!device->recording) + wined3d_device_set_pixel_shader(device->wined3d_device, NULL); wined3d_mutex_unlock(); return D3D_OK; } @@ -2843,7 +3155,9 @@ static HRESULT WINAPI d3d8_device_SetPixelShader(IDirect3DDevice8 *iface, DWORD } TRACE("Setting shader %p.\n", shader_impl); - wined3d_device_set_pixel_shader(device->wined3d_device, shader_impl->wined3d_shader); + wined3d_stateblock_set_pixel_shader(device->update_state, shader_impl->wined3d_shader); + if (!device->recording) + wined3d_device_set_pixel_shader(device->wined3d_device, shader_impl->wined3d_shader); wined3d_mutex_unlock(); return D3D_OK; @@ -2913,7 +3227,9 @@ static HRESULT WINAPI d3d8_device_SetPixelShaderConstant(IDirect3DDevice8 *iface iface, start_register, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, count, data); + hr = wined3d_stateblock_set_ps_consts_f(device->update_state, start_register, count, data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, count, data); wined3d_mutex_unlock(); return hr; @@ -2987,14 +3303,34 @@ static HRESULT WINAPI d3d8_device_SetStreamSource(IDirect3DDevice8 *iface, { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer8(buffer); + struct wined3d_buffer *wined3d_buffer; HRESULT hr; TRACE("iface %p, stream_idx %u, buffer %p, stride %u.\n", iface, stream_idx, buffer, stride); wined3d_mutex_lock(); - hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx, - buffer_impl ? buffer_impl->wined3d_buffer : NULL, 0, stride); + + if (!buffer_impl) + { + wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, + NULL, &stride); + wined3d_buffer = NULL; + } + else if (buffer_impl->draw_buffer) + wined3d_buffer = buffer_impl->draw_buffer; + else + wined3d_buffer = buffer_impl->wined3d_buffer; + + hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx, wined3d_buffer, 0, stride); + if (SUCCEEDED(hr) && !device->recording) + { + if (buffer_impl && buffer_impl->draw_buffer) + device->sysmem_vb |= (1u << stream_idx); + else + device->sysmem_vb &= ~(1u << stream_idx); + } + wined3d_mutex_unlock(); return hr; @@ -3162,40 +3498,40 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_NOT_RESET, D3D8_DEVICE_STATE_LOST); } -static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, +static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, + enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { - struct d3d8_surface *d3d_surface; - - TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); - if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) - return E_OUTOFMEMORY; - - surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_surface; - TRACE("Created surface %p.\n", d3d_surface); - - return D3D_OK; -} + if (type == WINED3D_RTYPE_TEXTURE_2D) + { + struct d3d8_surface *d3d_surface; -static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - void **parent, const struct wined3d_parent_ops **parent_ops) -{ - struct d3d8_volume *d3d_volume; + if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) + return E_OUTOFMEMORY; - TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_surface; + TRACE("Created surface %p.\n", d3d_surface); + } + else if (type == WINED3D_RTYPE_TEXTURE_3D) + { + struct d3d8_volume *d3d_volume; - if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) - return E_OUTOFMEMORY; + if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) + return E_OUTOFMEMORY; - volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_volume; - TRACE("Created volume %p.\n", d3d_volume); + volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_volume; + TRACE("Created volume %p.\n", d3d_volume); + } + else + { + ERR("Unhandled resource type %#x.\n", type); + return E_FAIL; + } return D3D_OK; } @@ -3211,9 +3547,8 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", device_parent, container_parent, desc, texture_flags, texture); - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, - texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, - &d3d8_null_wined3d_parent_ops, texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, texture_flags, + NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; @@ -3225,38 +3560,13 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct d3d8_device *device = device_from_device_parent(device_parent); - struct d3d8_swapchain *d3d_swapchain; - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); - - if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain))) - { - WARN("Failed to create swapchain, hr %#x.\n", hr); - *swapchain = NULL; - return hr; - } - - *swapchain = d3d_swapchain->wined3d_swapchain; - wined3d_swapchain_incref(*swapchain); - IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface); - - return hr; -} - static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops = { device_parent_wined3d_device_created, device_parent_mode_changed, device_parent_activate, - device_parent_surface_created, - device_parent_volume_created, + device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; static void setup_fpu(void) @@ -3281,8 +3591,17 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine { struct wined3d_swapchain_desc swapchain_desc; struct wined3d_swapchain *wined3d_swapchain; + struct d3d8_swapchain *d3d_swapchain; HRESULT hr; + static const enum wined3d_feature_level feature_levels[] = + { + WINED3D_FEATURE_LEVEL_8, + WINED3D_FEATURE_LEVEL_7, + WINED3D_FEATURE_LEVEL_6, + WINED3D_FEATURE_LEVEL_5, + }; + device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl; device->device_parent.ops = &d3d8_wined3d_device_parent_ops; device->ref = 1; @@ -3297,9 +3616,9 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); wined3d_mutex_lock(); - hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4, - &device->device_parent, &device->wined3d_device); - if (FAILED(hr)) + if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, + focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels), + &device->device_parent, &device->wined3d_device))) { WARN("Failed to create wined3d device, hr %#x.\n", hr); wined3d_mutex_unlock(); @@ -3307,12 +3626,19 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine return hr; } - if (!parameters->Windowed) + if (FAILED(hr = wined3d_stateblock_create(device->wined3d_device, WINED3D_SBT_PRIMARY, &device->state))) { - HWND device_window = parameters->hDeviceWindow; + ERR("Failed to create primary stateblock, hr %#x.\n", hr); + wined3d_device_decref(device->wined3d_device); + wined3d_mutex_unlock(); + return hr; + } + device->update_state = device->state; + if (!parameters->Windowed) + { if (!focus_window) - focus_window = device_window; + focus_window = parameters->hDeviceWindow; if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window))) { ERR("Failed to acquire focus window, hr %#x.\n", hr); @@ -3321,12 +3647,6 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine heap_free(device->handle_table.entries); return hr; } - - if (!device_window) - device_window = focus_window; - wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window, - parameters->BackBufferWidth, - parameters->BackBufferHeight); } if (flags & D3DCREATE_MULTITHREADED) @@ -3340,10 +3660,12 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine heap_free(device->handle_table.entries); return D3DERR_INVALIDCALL; } + swapchain_desc.flags |= WINED3D_SWAPCHAIN_IMPLICIT; - if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc))) + if (FAILED(hr = d3d8_swapchain_create(device, &swapchain_desc, + wined3dswapinterval_from_d3d(parameters->FullScreen_PresentationInterval), &d3d_swapchain))) { - WARN("Failed to initialize 3D, hr %#x.\n", hr); + WARN("Failed to create implicit swapchain, hr %#x.\n", hr); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); @@ -3351,12 +3673,17 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine return hr; } + wined3d_swapchain = d3d_swapchain->wined3d_swapchain; + wined3d_swapchain_incref(wined3d_swapchain); + IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); wined3d_mutex_unlock(); - present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc); + present_parameters_from_wined3d_swapchain_desc(parameters, + &swapchain_desc, parameters->FullScreen_PresentationInterval); device->declArraySize = 16; if (!(device->decls = heap_alloc(device->declArraySize * sizeof(*device->decls)))) @@ -3366,8 +3693,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine goto err; } - wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0); - device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); + device->implicit_swapchain = wined3d_swapchain; device->d3d_parent = &parent->IDirect3D8_iface; IDirect3D8_AddRef(device->d3d_parent); @@ -3376,7 +3702,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine err: wined3d_mutex_lock(); - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(wined3d_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); diff --git a/dll/directx/wine/d3d8/directx.c b/dll/directx/wine/d3d8/directx.c index 6e8f93a25c6..c5239844c3d 100644 --- a/dll/directx/wine/d3d8/directx.c +++ b/dll/directx/wine/d3d8/directx.c @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include "windef.h" @@ -29,7 +27,6 @@ #include "wingdi.h" #include "winuser.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "d3d8_private.h" @@ -132,17 +129,16 @@ static HRESULT WINAPI d3d8_GetAdapterIdentifier(IDirect3D8 *iface, UINT adapter, adapter_id.device_name = NULL; /* d3d9 only */ adapter_id.device_name_size = 0; /* d3d9 only */ - wined3d_mutex_lock(); - hr = wined3d_get_adapter_identifier(d3d8->wined3d, adapter, flags, &adapter_id); - wined3d_mutex_unlock(); - - identifier->DriverVersion = adapter_id.driver_version; - identifier->VendorId = adapter_id.vendor_id; - identifier->DeviceId = adapter_id.device_id; - identifier->SubSysId = adapter_id.subsystem_id; - identifier->Revision = adapter_id.revision; - memcpy(&identifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(identifier->DeviceIdentifier)); - identifier->WHQLLevel = adapter_id.whql_level; + if (SUCCEEDED(hr = wined3d_get_adapter_identifier(d3d8->wined3d, adapter, flags, &adapter_id))) + { + identifier->DriverVersion = adapter_id.driver_version; + identifier->VendorId = adapter_id.vendor_id; + identifier->DeviceId = adapter_id.device_id; + identifier->SubSysId = adapter_id.subsystem_id; + identifier->Revision = adapter_id.revision; + memcpy(&identifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(identifier->DeviceIdentifier)); + identifier->WHQLLevel = adapter_id.whql_level; + } return hr; } @@ -236,31 +232,34 @@ static HRESULT WINAPI d3d8_CheckDeviceFormat(IDirect3D8 *iface, UINT adapter, D3 { struct d3d8 *d3d8 = impl_from_IDirect3D8(iface); enum wined3d_resource_type wined3d_rtype; + unsigned int bind_flags; HRESULT hr; TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n", iface, adapter, device_type, adapter_format, usage, resource_type, format); - if (!adapter_format) + if (adapter_format != D3DFMT_X8R8G8B8 && adapter_format != D3DFMT_R5G6B5 + && adapter_format != D3DFMT_X1R5G5B5) { WARN("Invalid adapter format.\n"); - return D3DERR_INVALIDCALL; + return adapter_format ? D3DERR_NOTAVAILABLE : D3DERR_INVALIDCALL; } + bind_flags = wined3d_bind_flags_from_d3d8_usage(usage); usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { case D3DRTYPE_CUBETEXTURE: usage |= WINED3DUSAGE_LEGACY_CUBEMAP; case D3DRTYPE_TEXTURE: - usage |= WINED3DUSAGE_TEXTURE; + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; case D3DRTYPE_SURFACE: wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; break; case D3DRTYPE_VOLUMETEXTURE: case D3DRTYPE_VOLUME: - usage |= WINED3DUSAGE_TEXTURE; + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; wined3d_rtype = WINED3D_RTYPE_TEXTURE_3D; break; @@ -276,7 +275,7 @@ static HRESULT WINAPI d3d8_CheckDeviceFormat(IDirect3D8 *iface, UINT adapter, D3 wined3d_mutex_lock(); hr = wined3d_check_device_format(d3d8->wined3d, adapter, device_type, wined3dformat_from_d3dformat(adapter_format), - usage, wined3d_rtype, wined3dformat_from_d3dformat(format)); + usage, bind_flags, wined3d_rtype, wined3dformat_from_d3dformat(format)); wined3d_mutex_unlock(); return hr; @@ -324,7 +323,7 @@ static HRESULT WINAPI d3d8_CheckDepthStencilMatch(IDirect3D8 *iface, UINT adapte static HRESULT WINAPI d3d8_GetDeviceCaps(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type, D3DCAPS8 *caps) { struct d3d8 *d3d8 = impl_from_IDirect3D8(iface); - WINED3DCAPS wined3d_caps; + struct wined3d_caps wined3d_caps; HRESULT hr; TRACE("iface %p, adapter %u, device_type %#x, caps %p.\n", iface, adapter, device_type, caps); @@ -417,7 +416,7 @@ BOOL d3d8_init(struct d3d8 *d3d8) DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART - | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT; + | WINED3D_LEGACY_CUBEMAP_FILTERING; d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl; d3d8->refcount = 1; diff --git a/dll/directx/wine/d3d8/shader.c b/dll/directx/wine/d3d8/shader.c index 8192b238ebd..d88f4b9a9ab 100644 --- a/dll/directx/wine/d3d8/shader.c +++ b/dll/directx/wine/d3d8/shader.c @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -117,11 +116,6 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d desc.byte_code = byte_code; desc.byte_code_size = ~(size_t)0; - desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; - desc.input_signature.element_count = 0; - desc.output_signature.element_count = 0; - desc.patch_constant_signature.element_count = 0; - desc.max_version = 1; wined3d_mutex_lock(); hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader, @@ -169,11 +163,6 @@ HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_dev desc.byte_code = byte_code; desc.byte_code_size = ~(size_t)0; - desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; - desc.input_signature.element_count = 0; - desc.output_signature.element_count = 0; - desc.patch_constant_signature.element_count = 0; - desc.max_version = 1; wined3d_mutex_lock(); hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader, diff --git a/dll/directx/wine/d3d8/surface.c b/dll/directx/wine/d3d8/surface.c index fff47f5ca15..bbd7e38338b 100644 --- a/dll/directx/wine/d3d8/surface.c +++ b/dll/directx/wine/d3d8/surface.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -191,7 +190,7 @@ static HRESULT WINAPI d3d8_surface_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->MultiSampleType = wined3d_desc.multisample_type; @@ -244,7 +243,7 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface, } hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, - &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags)); + &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags, 0)); wined3d_mutex_unlock(); if (SUCCEEDED(hr)) @@ -258,6 +257,8 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface, locked_rect->pBits = NULL; } + if (hr == E_INVALIDARG) + return D3DERR_INVALIDCALL; return hr; } diff --git a/dll/directx/wine/d3d8/swapchain.c b/dll/directx/wine/d3d8/swapchain.c index 3a588b5e8c2..f08a19ca238 100644 --- a/dll/directx/wine/d3d8/swapchain.c +++ b/dll/directx/wine/d3d8/swapchain.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -57,9 +56,7 @@ static ULONG WINAPI d3d8_swapchain_AddRef(IDirect3DSwapChain8 *iface) { if (swapchain->parent_device) IDirect3DDevice8_AddRef(swapchain->parent_device); - wined3d_mutex_lock(); wined3d_swapchain_incref(swapchain->wined3d_swapchain); - wined3d_mutex_unlock(); } return ref; @@ -76,9 +73,7 @@ static ULONG WINAPI d3d8_swapchain_Release(IDirect3DSwapChain8 *iface) { IDirect3DDevice8 *parent_device = swapchain->parent_device; - wined3d_mutex_lock(); wined3d_swapchain_decref(swapchain->wined3d_swapchain); - wined3d_mutex_unlock(); if (parent_device) IDirect3DDevice8_Release(parent_device); @@ -92,7 +87,6 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai { struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface); struct d3d8_device *device = impl_from_IDirect3DDevice8(swapchain->parent_device); - HRESULT hr; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n", iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region); @@ -103,12 +97,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai if (dirty_region) FIXME("Ignoring dirty_region %p.\n", dirty_region); - wined3d_mutex_lock(); - hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0, 0); - wined3d_mutex_unlock(); - - return hr; + return wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0); } static HRESULT WINAPI d3d8_swapchain_GetBackBuffer(IDirect3DSwapChain8 *iface, @@ -167,19 +157,16 @@ static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops = }; static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device, - struct wined3d_swapchain_desc *desc) + struct wined3d_swapchain_desc *desc, unsigned int swap_interval) { HRESULT hr; swapchain->refcount = 1; swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl; + swapchain->swap_interval = swap_interval; - wined3d_mutex_lock(); - hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, - &d3d8_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain); - wined3d_mutex_unlock(); - - if (FAILED(hr)) + if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, + &d3d8_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) { WARN("Failed to create wined3d swapchain, hr %#x.\n", hr); return hr; @@ -192,7 +179,7 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi } HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc, - struct d3d8_swapchain **swapchain) + unsigned int swap_interval, struct d3d8_swapchain **swapchain) { struct d3d8_swapchain *object; HRESULT hr; @@ -200,7 +187,7 @@ HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapcha if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = swapchain_init(object, device, desc))) + if (FAILED(hr = swapchain_init(object, device, desc, swap_interval))) { WARN("Failed to initialize swapchain, hr %#x.\n", hr); heap_free(object); diff --git a/dll/directx/wine/d3d8/texture.c b/dll/directx/wine/d3d8/texture.c index 87a2575cb1c..2bc6f964874 100644 --- a/dll/directx/wine/d3d8/texture.c +++ b/dll/directx/wine/d3d8/texture.c @@ -16,7 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -253,7 +252,7 @@ static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UIN { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->MultiSampleType = wined3d_desc.multisample_type; @@ -600,7 +599,7 @@ static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *ifac { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->MultiSampleType = wined3d_desc.multisample_type; @@ -945,7 +944,7 @@ static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *ifac { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_VOLUME; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->Width = wined3d_desc.width; @@ -1107,18 +1106,20 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; - desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = wined3d_bind_flags_from_d3d8_usage(usage) | WINED3D_BIND_SHADER_RESOURCE; + desc.access = wined3daccess_from_d3dpool(pool, usage); desc.width = width; desc.height = height; desc.depth = 1; desc.size = 0; - if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + if (usage & D3DUSAGE_WRITEONLY) + { + WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flag, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (!levels) levels = wined3d_log2i(max(width, height)) + 1; @@ -1155,18 +1156,21 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; - desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; + desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = wined3d_bind_flags_from_d3d8_usage(usage) | WINED3D_BIND_SHADER_RESOURCE; + desc.access = wined3daccess_from_d3dpool(pool, usage); desc.width = edge_length; desc.height = edge_length; desc.depth = 1; desc.size = 0; - if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + if (usage & D3DUSAGE_WRITEONLY) + { + WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flag, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (!levels) levels = wined3d_log2i(edge_length) + 1; @@ -1193,6 +1197,10 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev struct wined3d_resource_desc desc; HRESULT hr; + /* In d3d8, 3D textures can't be used as rendertarget or depth/stencil buffer. */ + if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + return D3DERR_INVALIDCALL; + texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl; d3d8_resource_init(&texture->resource); list_init(&texture->rtv_list); @@ -1202,15 +1210,21 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; - desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; + desc.bind_flags = wined3d_bind_flags_from_d3d8_usage(usage) | WINED3D_BIND_SHADER_RESOURCE; desc.access = wined3daccess_from_d3dpool(pool, usage); desc.width = width; desc.height = height; desc.depth = depth; desc.size = 0; + if (usage & D3DUSAGE_WRITEONLY) + { + WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } + if (!levels) levels = wined3d_log2i(max(max(width, height), depth)) + 1; diff --git a/dll/directx/wine/d3d8/vertexdeclaration.c b/dll/directx/wine/d3d8/vertexdeclaration.c index 0cae3cd8c6c..a43fb26f950 100644 --- a/dll/directx/wine/d3d8/vertexdeclaration.c +++ b/dll/directx/wine/d3d8/vertexdeclaration.c @@ -1,6 +1,4 @@ /* - * IDirect3DVertexDeclaration8 implementation - * * Copyright 2007 Henri Verbeet * * This library is free software; you can redistribute it and/or @@ -18,10 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* IDirect3DVertexDeclaration8 is internal to our implementation. - * It's not visible in the API. */ - -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -254,7 +248,7 @@ wined3d_usage_lookup[] = /* TODO: find out where rhw (or positionT) is for declaration8 */ static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size, - struct wined3d_vertex_element **wined3d_elements) + struct wined3d_vertex_element **wined3d_elements, DWORD *stream_map) { struct wined3d_vertex_element *element; const DWORD *token = d3d8_elements; @@ -265,6 +259,7 @@ static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3 TRACE("d3d8_elements %p, d3d8_elements_size %p, wined3d_elements %p\n", d3d8_elements, d3d8_elements_size, wined3d_elements); + *stream_map = 0; /* 128 should be enough for anyone... */ *wined3d_elements = heap_alloc_zero(128 * sizeof(**wined3d_elements)); while (D3DVSD_END() != *token) @@ -292,6 +287,8 @@ static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3 element->usage = wined3d_usage_lookup[reg].usage; element->usage_idx = wined3d_usage_lookup[reg].usage_idx; + *stream_map |= 1u << stream; + offset += wined3d_type_sizes[type]; } else if (token_type == D3DVSD_TOKEN_STREAMDATA && (*token & D3DVSD_DATALOADTYPEMASK)) { TRACE(" 0x%08x SKIP(%u)\n", token_type, ((token_type & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT)); @@ -341,7 +338,8 @@ HRESULT d3d8_vertex_declaration_init(struct d3d8_vertex_declaration *declaration declaration->shader_handle = shader_handle; - wined3d_element_count = convert_to_wined3d_declaration(elements, &declaration->elements_size, &wined3d_elements); + wined3d_element_count = convert_to_wined3d_declaration(elements, &declaration->elements_size, + &wined3d_elements, &declaration->stream_map); if (!(declaration->elements = heap_alloc(declaration->elements_size))) { ERR("Failed to allocate vertex declaration elements memory.\n"); @@ -373,6 +371,7 @@ HRESULT d3d8_vertex_declaration_init_fvf(struct d3d8_vertex_declaration *declara declaration->elements = NULL; declaration->elements_size = 0; + declaration->stream_map = 1; declaration->shader_handle = fvf; hr = wined3d_vertex_declaration_create_from_fvf(device->wined3d_device, fvf, declaration, diff --git a/dll/directx/wine/d3d8/volume.c b/dll/directx/wine/d3d8/volume.c index 89aa84fdb50..9dc68e850d4 100644 --- a/dll/directx/wine/d3d8/volume.c +++ b/dll/directx/wine/d3d8/volume.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d8); @@ -125,7 +124,7 @@ static HRESULT WINAPI d3d8_volume_GetDesc(IDirect3DVolume8 *iface, D3DVOLUME_DES desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_VOLUME; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->Width = wined3d_desc.width; @@ -148,7 +147,7 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface, wined3d_mutex_lock(); if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, - wined3dmapflags_from_d3dmapflags(flags)))) + wined3dmapflags_from_d3dmapflags(flags, 0)))) map_desc.data = NULL; wined3d_mutex_unlock(); diff --git a/dll/directx/wine/d3d9/buffer.c b/dll/directx/wine/d3d9/buffer.c index 36a6ae3f902..7af652e7d1a 100644 --- a/dll/directx/wine/d3d9/buffer.c +++ b/dll/directx/wine/d3d9/buffer.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -58,7 +57,10 @@ static ULONG WINAPI d3d9_vertexbuffer_AddRef(IDirect3DVertexBuffer9 *iface) { IDirect3DDevice9Ex_AddRef(buffer->parent_device); wined3d_mutex_lock(); - wined3d_buffer_incref(buffer->wined3d_buffer); + if (buffer->draw_buffer) + wined3d_buffer_incref(buffer->draw_buffer); + else + wined3d_buffer_incref(buffer->wined3d_buffer); wined3d_mutex_unlock(); } @@ -74,10 +76,14 @@ static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface) if (!refcount) { + struct wined3d_buffer *draw_buffer = buffer->draw_buffer; IDirect3DDevice9Ex *device = buffer->parent_device; wined3d_mutex_lock(); - wined3d_buffer_decref(buffer->wined3d_buffer); + if (draw_buffer) + wined3d_buffer_decref(draw_buffer); + else + wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ @@ -183,6 +189,7 @@ static HRESULT WINAPI d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9 *iface, UINT void **data, DWORD flags) { struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface); + struct wined3d_resource *wined3d_resource; struct wined3d_map_desc wined3d_map_desc; struct wined3d_box wined3d_box = {0}; HRESULT hr; @@ -193,8 +200,9 @@ static HRESULT WINAPI d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9 *iface, UINT wined3d_box.left = offset; wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), - 0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags)); + wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer); + hr = wined3d_resource_map(wined3d_resource, 0, &wined3d_map_desc, &wined3d_box, + wined3dmapflags_from_d3dmapflags(flags, buffer->usage)); wined3d_mutex_unlock(); *data = wined3d_map_desc.data; @@ -230,7 +238,7 @@ static HRESULT WINAPI d3d9_vertexbuffer_GetDesc(IDirect3DVertexBuffer9 *iface, desc->Format = D3DFMT_VERTEXDATA; desc->Type = D3DRTYPE_VERTEXBUFFER; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = buffer->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; desc->FVF = buffer->fvf; @@ -262,6 +270,9 @@ static const IDirect3DVertexBuffer9Vtbl d3d9_vertexbuffer_vtbl = static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *parent) { struct d3d9_vertexbuffer *buffer = parent; + + if (buffer->draw_buffer) + wined3d_buffer_decref(buffer->wined3d_buffer); d3d9_resource_cleanup(&buffer->resource); heap_free(buffer); } @@ -274,6 +285,7 @@ static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops = HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device *device, UINT size, UINT usage, DWORD fvf, D3DPOOL pool) { + const struct wined3d_parent_ops *parent_ops = &d3d9_null_wined3d_parent_ops; struct wined3d_buffer_desc desc; HRESULT hr; @@ -283,21 +295,47 @@ HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device * return D3DERR_INVALIDCALL; } + if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended) + { + WARN("Managed resources are not supported by d3d9ex devices.\n"); + return D3DERR_INVALIDCALL; + } + + /* In d3d9, buffers can't be used as rendertarget or depth/stencil buffer. */ + if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + return D3DERR_INVALIDCALL; + buffer->IDirect3DVertexBuffer9_iface.lpVtbl = &d3d9_vertexbuffer_vtbl; buffer->fvf = fvf; + buffer->usage = usage; d3d9_resource_init(&buffer->resource); desc.byte_width = size; desc.usage = usage & WINED3DUSAGE_MASK; - desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = 0; + desc.access = wined3daccess_from_d3dpool(pool, usage) | map_access_from_usage(usage); + /* Buffers are always readable. */ + if (pool != D3DPOOL_DEFAULT) + desc.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; + if (desc.access & WINED3D_RESOURCE_ACCESS_GPU) + { + desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; + parent_ops = &d3d9_vertexbuffer_wined3d_parent_ops; + } + wined3d_mutex_lock(); - hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, - &d3d9_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer); + hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer); + if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, + &d3d9_vertexbuffer_wined3d_parent_ops, &buffer->draw_buffer))) + wined3d_buffer_decref(buffer->wined3d_buffer); + } wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -355,7 +393,10 @@ static ULONG WINAPI d3d9_indexbuffer_AddRef(IDirect3DIndexBuffer9 *iface) { IDirect3DDevice9Ex_AddRef(buffer->parent_device); wined3d_mutex_lock(); - wined3d_buffer_incref(buffer->wined3d_buffer); + if (buffer->draw_buffer) + wined3d_buffer_incref(buffer->draw_buffer); + else + wined3d_buffer_incref(buffer->wined3d_buffer); wined3d_mutex_unlock(); } @@ -371,10 +412,14 @@ static ULONG WINAPI d3d9_indexbuffer_Release(IDirect3DIndexBuffer9 *iface) if (!refcount) { + struct wined3d_buffer *draw_buffer = buffer->draw_buffer; IDirect3DDevice9Ex *device = buffer->parent_device; wined3d_mutex_lock(); - wined3d_buffer_decref(buffer->wined3d_buffer); + if (draw_buffer) + wined3d_buffer_decref(draw_buffer); + else + wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ @@ -480,6 +525,7 @@ static HRESULT WINAPI d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9 *iface, UINT offset, UINT size, void **data, DWORD flags) { struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface); + struct wined3d_resource *wined3d_resource; struct wined3d_map_desc wined3d_map_desc; struct wined3d_box wined3d_box = {0}; HRESULT hr; @@ -490,8 +536,9 @@ static HRESULT WINAPI d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9 *iface, wined3d_box.left = offset; wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), - 0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags)); + wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer); + hr = wined3d_resource_map(wined3d_resource, 0, &wined3d_map_desc, &wined3d_box, + wined3dmapflags_from_d3dmapflags(flags, buffer->usage)); wined3d_mutex_unlock(); *data = wined3d_map_desc.data; @@ -526,7 +573,7 @@ static HRESULT WINAPI d3d9_indexbuffer_GetDesc(IDirect3DIndexBuffer9 *iface, D3D desc->Format = d3dformat_from_wined3dformat(buffer->format); desc->Type = D3DRTYPE_INDEXBUFFER; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = buffer->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Size = wined3d_desc.size; @@ -557,6 +604,9 @@ static const IDirect3DIndexBuffer9Vtbl d3d9_indexbuffer_vtbl = static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *parent) { struct d3d9_indexbuffer *buffer = parent; + + if (buffer->draw_buffer) + wined3d_buffer_decref(buffer->wined3d_buffer); d3d9_resource_cleanup(&buffer->resource); heap_free(buffer); } @@ -569,26 +619,54 @@ static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops = HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device, UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool) { + const struct wined3d_parent_ops *parent_ops = &d3d9_null_wined3d_parent_ops; struct wined3d_buffer_desc desc; HRESULT hr; + if (pool == D3DPOOL_SCRATCH) + return D3DERR_INVALIDCALL; + + if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended) + { + WARN("Managed resources are not supported by d3d9ex devices.\n"); + return D3DERR_INVALIDCALL; + } + + /* In d3d9, buffers can't be used as rendertarget or depth/stencil buffer. */ + if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + return D3DERR_INVALIDCALL; + desc.byte_width = size; desc.usage = (usage & WINED3DUSAGE_MASK) | WINED3DUSAGE_STATICDECL; - if (pool == D3DPOOL_SCRATCH) - desc.usage |= WINED3DUSAGE_SCRATCH; - desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = 0; + desc.access = wined3daccess_from_d3dpool(pool, usage) | map_access_from_usage(usage); + /* Buffers are always readable. */ + if (pool != D3DPOOL_DEFAULT) + desc.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; + if (desc.access & WINED3D_RESOURCE_ACCESS_GPU) + { + desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; + parent_ops = &d3d9_indexbuffer_wined3d_parent_ops; + } + buffer->IDirect3DIndexBuffer9_iface.lpVtbl = &d3d9_indexbuffer_vtbl; buffer->format = wined3dformat_from_d3dformat(format); + buffer->usage = usage; d3d9_resource_init(&buffer->resource); wined3d_mutex_lock(); - hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, - &d3d9_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer); + hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer); + if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, + &d3d9_indexbuffer_wined3d_parent_ops, &buffer->draw_buffer))) + wined3d_buffer_decref(buffer->wined3d_buffer); + } wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dll/directx/wine/d3d9/d3d9_main.c b/dll/directx/wine/d3d9/d3d9_main.c index c23fa54d99b..21df2a34cd2 100644 --- a/dll/directx/wine/d3d9/d3d9_main.c +++ b/dll/directx/wine/d3d9/d3d9_main.c @@ -21,7 +21,6 @@ * */ -#include "config.h" #include "initguid.h" #include "d3d9_private.h" diff --git a/dll/directx/wine/d3d9/d3d9_private.h b/dll/directx/wine/d3d9/d3d9_private.h index 094707a0d16..03d804a61c9 100644 --- a/dll/directx/wine/d3d9/d3d9_private.h +++ b/dll/directx/wine/d3d9/d3d9_private.h @@ -35,13 +35,14 @@ #include "winuser.h" #include "wine/debug.h" #include "wine/heap.h" -#include "wine/unicode.h" #include "d3d9.h" #include "wine/wined3d.h" #define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 +#define D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP 8192 #define D3D9_MAX_TEXTURE_UNITS 20 +#define D3D9_MAX_STREAMS 16 #define D3DPRESENTFLAGS_MASK 0x00000fffu @@ -53,10 +54,10 @@ HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLS D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN; -unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN; +unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags, unsigned int usage) DECLSPEC_HIDDEN; void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, - const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN; -void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN; + const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) DECLSPEC_HIDDEN; +void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps, DWORD flags) DECLSPEC_HIDDEN; struct d3d9 { @@ -99,18 +100,24 @@ struct d3d9_device UINT index_buffer_size; UINT index_buffer_pos; - struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS]; struct d3d9_surface *render_targets[D3D_MAX_SIMULTANEOUS_RENDERTARGETS]; LONG device_state; - BOOL in_destruction; - BOOL in_scene; - BOOL has_vertex_declaration; + DWORD sysmem_vb : 16; /* D3D9_MAX_STREAMS */ + DWORD sysmem_ib : 1; + DWORD in_destruction : 1; + DWORD in_scene : 1; + DWORD has_vertex_declaration : 1; + DWORD padding : 12; + + DWORD auto_mipmaps; /* D3D9_MAX_TEXTURE_UNITS */ unsigned int max_user_clip_planes; UINT implicit_swapchain_count; - struct d3d9_swapchain **implicit_swapchains; + struct wined3d_swapchain **implicit_swapchains; + + struct wined3d_stateblock *recording, *state, *update_state; }; HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d, @@ -149,10 +156,11 @@ struct d3d9_swapchain LONG refcount; struct wined3d_swapchain *wined3d_swapchain; IDirect3DDevice9Ex *parent_device; + unsigned int swap_interval; }; HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc, - struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN; + unsigned int swap_interval, struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN; struct d3d9_surface { @@ -181,7 +189,8 @@ struct d3d9_vertexbuffer struct d3d9_resource resource; struct wined3d_buffer *wined3d_buffer; IDirect3DDevice9Ex *parent_device; - DWORD fvf; + struct wined3d_buffer *draw_buffer; + DWORD fvf, usage; }; HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device *device, @@ -194,7 +203,9 @@ struct d3d9_indexbuffer struct d3d9_resource resource; struct wined3d_buffer *wined3d_buffer; IDirect3DDevice9Ex *parent_device; + struct wined3d_buffer *draw_buffer; enum wined3d_format_id format; + DWORD usage; }; HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device, @@ -241,6 +252,7 @@ struct d3d9_vertex_declaration LONG refcount; D3DVERTEXELEMENT9 *elements; UINT element_count; + DWORD stream_map; struct wined3d_vertex_declaration *wined3d_declaration; DWORD fvf; IDirect3DDevice9Ex *parent_device; @@ -291,9 +303,14 @@ static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9E return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface); } -static inline DWORD d3dusage_from_wined3dusage(unsigned int usage) +static inline DWORD d3dusage_from_wined3dusage(unsigned int wined3d_usage, unsigned int bind_flags) { - return usage & WINED3DUSAGE_MASK; + DWORD usage = wined3d_usage & WINED3DUSAGE_MASK; + if (bind_flags & WINED3D_BIND_RENDER_TARGET) + usage |= D3DUSAGE_RENDERTARGET; + if (bind_flags & WINED3D_BIND_DEPTH_STENCIL) + usage |= D3DUSAGE_DEPTHSTENCIL; + return usage; } static inline D3DPOOL d3dpool_from_wined3daccess(unsigned int access, unsigned int usage) @@ -312,23 +329,47 @@ static inline D3DPOOL d3dpool_from_wined3daccess(unsigned int access, unsigned i } } +static inline unsigned int map_access_from_usage(unsigned int usage) +{ + if (usage & D3DUSAGE_WRITEONLY) + return WINED3D_RESOURCE_ACCESS_MAP_W; + return WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; +} + static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool, unsigned int usage) { + unsigned int access; + switch (pool) { case D3DPOOL_DEFAULT: - if (usage & D3DUSAGE_DYNAMIC) - return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - return WINED3D_RESOURCE_ACCESS_GPU; + access = WINED3D_RESOURCE_ACCESS_GPU; + break; case D3DPOOL_MANAGED: - return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU; + break; case D3DPOOL_SYSTEMMEM: case D3DPOOL_SCRATCH: - return WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + access = WINED3D_RESOURCE_ACCESS_CPU; + break; default: - return 0; + access = 0; } + if (pool != D3DPOOL_DEFAULT || usage & D3DUSAGE_DYNAMIC) + access |= map_access_from_usage(usage); + return access; +} + +static inline unsigned int wined3d_bind_flags_from_d3d9_usage(DWORD usage) +{ + unsigned int bind_flags = 0; + + if (usage & D3DUSAGE_RENDERTARGET) + bind_flags |= WINED3D_BIND_RENDER_TARGET; + if (usage & D3DUSAGE_DEPTHSTENCIL) + bind_flags |= WINED3D_BIND_DEPTH_STENCIL; + + return bind_flags; } static inline DWORD wined3dusage_from_d3dusage(unsigned int usage) diff --git a/dll/directx/wine/d3d9/device.c b/dll/directx/wine/d3d9/device.c index bc73699e525..c7bbb9e860b 100644 --- a/dll/directx/wine/d3d9/device.c +++ b/dll/directx/wine/d3d9/device.c @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -32,6 +31,14 @@ const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops = d3d9_null_wined3d_object_destroyed, }; +static void wined3d_color_from_d3dcolor(struct wined3d_color *wined3d_colour, D3DCOLOR d3d_colour) +{ + wined3d_colour->r = ((d3d_colour >> 16) & 0xff) / 255.0f; + wined3d_colour->g = ((d3d_colour >> 8) & 0xff) / 255.0f; + wined3d_colour->b = (d3d_colour & 0xff) / 255.0f; + wined3d_colour->a = ((d3d_colour >> 24) & 0xff) / 255.0f; +} + D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) { BYTE *c = (BYTE *)&format; @@ -160,7 +167,7 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) } } -unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) +unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags, unsigned int usage) { static const unsigned int handled = D3DLOCK_NOSYSLOCK | D3DLOCK_NOOVERWRITE @@ -170,12 +177,12 @@ unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) unsigned int wined3d_flags; wined3d_flags = flags & handled; - if (!(flags & (D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD))) + if (~usage & D3DUSAGE_WRITEONLY && !(flags & (D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD))) wined3d_flags |= WINED3D_MAP_READ; if (!(flags & D3DLOCK_READONLY)) wined3d_flags |= WINED3D_MAP_WRITE; if (!(wined3d_flags & (WINED3D_MAP_READ | WINED3D_MAP_WRITE))) - wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE; + wined3d_flags |= WINED3D_MAP_WRITE; flags &= ~(handled | D3DLOCK_READONLY); if (flags) @@ -231,7 +238,7 @@ static D3DSWAPEFFECT d3dswapeffect_from_wined3dswapeffect(enum wined3d_swap_effe } void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, - const struct wined3d_swapchain_desc *swapchain_desc) + const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) { present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height; @@ -247,7 +254,7 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; - present_parameters->PresentationInterval = swapchain_desc->swap_interval; + present_parameters->PresentationInterval = presentation_interval; } static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect) @@ -270,6 +277,27 @@ static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFE } } +static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval) +{ + switch (interval) + { + case D3DPRESENT_INTERVAL_IMMEDIATE: + return WINED3D_SWAP_INTERVAL_IMMEDIATE; + case D3DPRESENT_INTERVAL_ONE: + return WINED3D_SWAP_INTERVAL_ONE; + case D3DPRESENT_INTERVAL_TWO: + return WINED3D_SWAP_INTERVAL_TWO; + case D3DPRESENT_INTERVAL_THREE: + return WINED3D_SWAP_INTERVAL_THREE; + case D3DPRESENT_INTERVAL_FOUR: + return WINED3D_SWAP_INTERVAL_FOUR; + default: + FIXME("Unhandled presentation interval %#x.\n", interval); + case D3DPRESENT_INTERVAL_DEFAULT: + return WINED3D_SWAP_INTERVAL_DEFAULT; + } +} + static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended) { @@ -288,12 +316,25 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); return FALSE; } + switch (present_parameters->PresentationInterval) + { + case D3DPRESENT_INTERVAL_DEFAULT: + case D3DPRESENT_INTERVAL_ONE: + case D3DPRESENT_INTERVAL_TWO: + case D3DPRESENT_INTERVAL_THREE: + case D3DPRESENT_INTERVAL_FOUR: + case D3DPRESENT_INTERVAL_IMMEDIATE: + break; + default: + WARN("Invalid presentation interval %#x.\n", present_parameters->PresentationInterval); + return FALSE; + } swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat); swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount); - swapchain_desc->backbuffer_usage = WINED3DUSAGE_RENDERTARGET; + swapchain_desc->backbuffer_bind_flags = WINED3D_BIND_RENDER_TARGET; swapchain_desc->multisample_type = present_parameters->MultiSampleType; swapchain_desc->multisample_quality = present_parameters->MultiSampleQuality; swapchain_desc->swap_effect = wined3dswapeffect_from_d3dswapeffect(present_parameters->SwapEffect); @@ -304,8 +345,13 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat); swapchain_desc->flags = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; + if ((present_parameters->Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER) + && (is_gdi_compat_wined3dformat(swapchain_desc->backbuffer_format) + /* WINED3DFMT_UNKNOWN creates the swapchain with the current + * display format, which is always GDI-compatible. */ + || swapchain_desc->backbuffer_format == WINED3DFMT_UNKNOWN)) + swapchain_desc->flags |= WINED3D_SWAPCHAIN_GDI_COMPATIBLE; swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; - swapchain_desc->swap_interval = present_parameters->PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) @@ -314,7 +360,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch return TRUE; } -void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) +void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps, DWORD creation_flags) { static const DWORD ps_minor_version[] = {0, 4, 0, 0}; static const DWORD vs_minor_version[] = {0, 1, 0, 0}; @@ -330,7 +376,7 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) caps->Caps = wined3d_caps->Caps; caps->Caps2 = wined3d_caps->Caps2; caps->Caps3 = wined3d_caps->Caps3; - caps->PresentationIntervals = wined3d_caps->PresentationIntervals; + caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE; caps->CursorCaps = wined3d_caps->CursorCaps; caps->DevCaps = wined3d_caps->DevCaps; caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; @@ -452,7 +498,10 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; - caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); + if (creation_flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP, caps->MaxVertexShaderConst); + else + caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); caps->NumSimultaneousRTs = min(D3D_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs); if (caps->PixelShaderVersion > 3) @@ -551,9 +600,16 @@ static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *if if (device->index_buffer) wined3d_buffer_decref(device->index_buffer); + for (i = 0; i < device->implicit_swapchain_count; ++i) + { + wined3d_swapchain_decref(device->implicit_swapchains[i]); + } heap_free(device->implicit_swapchains); - wined3d_device_uninit_3d(device->wined3d_device); + if (device->recording) + wined3d_stateblock_decref(device->recording); + wined3d_stateblock_decref(device->state); + wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); @@ -631,7 +687,8 @@ static HRESULT WINAPI d3d9_device_GetDirect3D(IDirect3DDevice9Ex *iface, IDirect static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *caps) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - WINED3DCAPS wined3d_caps; + struct wined3d_device_creation_parameters creation_parameters; + struct wined3d_caps wined3d_caps; HRESULT hr; TRACE("iface %p, caps %p.\n", iface, caps); @@ -639,13 +696,15 @@ static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCA if (!caps) return D3DERR_INVALIDCALL; + wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters); + memset(caps, 0, sizeof(*caps)); wined3d_mutex_lock(); hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); wined3d_mutex_unlock(); - d3dcaps_from_wined3dcaps(caps, &wined3d_caps); + d3dcaps_from_wined3dcaps(caps, &wined3d_caps, creation_parameters.flags); return hr; } @@ -743,7 +802,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct wined3d_swapchain_desc desc; struct d3d9_swapchain *object; - UINT i, count; + unsigned int swap_interval; + unsigned int i, count; HRESULT hr; TRACE("iface %p, present_parameters %p, swapchain %p.\n", @@ -776,9 +836,11 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters, device->d3d_parent->extended)) return D3DERR_INVALIDCALL; - if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object))) + swap_interval = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval); + if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, swap_interval, &object))) *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface; - present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); + present_parameters_from_wined3d_swapchain_desc(present_parameters, + &desc, present_parameters->PresentationInterval); return hr; } @@ -787,6 +849,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice UINT swapchain_idx, IDirect3DSwapChain9 **swapchain) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct d3d9_swapchain *d3d9_swapchain; HRESULT hr; TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain); @@ -794,7 +857,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice wined3d_mutex_lock(); if (swapchain_idx < device->implicit_swapchain_count) { - *swapchain = (IDirect3DSwapChain9 *)&device->implicit_swapchains[swapchain_idx]->IDirect3DSwapChain9Ex_iface; + d3d9_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[swapchain_idx]); + *swapchain = (IDirect3DSwapChain9 *)&d3d9_swapchain->IDirect3DSwapChain9Ex_iface; IDirect3DSwapChain9Ex_AddRef(*swapchain); hr = D3D_OK; } @@ -824,6 +888,8 @@ static UINT WINAPI d3d9_device_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface) static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) { + struct d3d9_vertexbuffer *vertex_buffer; + struct d3d9_indexbuffer *index_buffer; struct wined3d_resource_desc desc; IDirect3DBaseTexture9 *texture; struct d3d9_surface *surface; @@ -835,6 +901,19 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D) { + if (desc.bind_flags & WINED3D_BIND_VERTEX_BUFFER) + { + vertex_buffer = wined3d_resource_get_parent(resource); + if (vertex_buffer && vertex_buffer->draw_buffer) + return D3D_OK; + } + if (desc.bind_flags & WINED3D_BIND_INDEX_BUFFER) + { + index_buffer = wined3d_resource_get_parent(resource); + if (index_buffer && index_buffer->draw_buffer) + return D3D_OK; + } + WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); return D3DERR_INVALIDCALL; } @@ -858,15 +937,13 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) static HRESULT d3d9_device_get_swapchains(struct d3d9_device *device) { UINT i, new_swapchain_count = wined3d_device_get_swapchain_count(device->wined3d_device); - struct wined3d_swapchain *wined3d_swapchain; if (!(device->implicit_swapchains = heap_alloc(new_swapchain_count * sizeof(*device->implicit_swapchains)))) return E_OUTOFMEMORY; for (i = 0; i < new_swapchain_count; ++i) { - wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i); - device->implicit_swapchains[i] = wined3d_swapchain_get_parent(wined3d_swapchain); + device->implicit_swapchains[i] = wined3d_device_get_swapchain(device->wined3d_device, i); } device->implicit_swapchain_count = new_swapchain_count; @@ -880,6 +957,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, struct wined3d_swapchain_desc swapchain_desc; struct wined3d_display_mode wined3d_mode; struct wined3d_rendertarget_view *rtv; + struct d3d9_swapchain *d3d9_swapchain; unsigned int i; HRESULT hr; @@ -900,6 +978,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters, extended)) return D3DERR_INVALIDCALL; + swapchain_desc.flags |= WINED3D_SWAPCHAIN_IMPLICIT; wined3d_mutex_lock(); @@ -924,6 +1003,11 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, if (!extended) { + if (device->recording) + wined3d_stateblock_decref(device->recording); + device->recording = NULL; + device->update_state = device->state; + device->auto_mipmaps = 0; wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); } @@ -934,7 +1018,10 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, } else { - wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); + d3d9_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[0]); + d3d9_swapchain->swap_interval + = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval); + wined3d_swapchain_get_desc(d3d9_swapchain->wined3d_swapchain, &swapchain_desc); present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width; present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height; present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc.backbuffer_format); @@ -943,10 +1030,6 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, device->device_state = D3D9_DEVICE_STATE_OK; } - if (!device->d3d_parent->extended) - for (i = 0; i < ARRAY_SIZE(device->textures); ++i) - device->textures[i] = NULL; - rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0); device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv); for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i) @@ -976,11 +1059,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - UINT i; + struct d3d9_swapchain *swapchain; + unsigned int i; HRESULT hr; - TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n", - iface, src_rect, dst_rect, dst_window_override, dirty_region); + TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n", + iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region); if (device->device_state != D3D9_DEVICE_STATE_OK) return device->d3d_parent->extended ? S_PRESENT_OCCLUDED : D3DERR_DEVICELOST; @@ -991,8 +1075,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0, 0))) + swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[i]); + if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0))) { wined3d_mutex_unlock(); return hr; @@ -1007,6 +1092,7 @@ static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct d3d9_swapchain *d3d9_swapchain; HRESULT hr; TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", @@ -1025,7 +1111,8 @@ static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT return D3DERR_INVALIDCALL; } - hr = IDirect3DSwapChain9Ex_GetBackBuffer(&device->implicit_swapchains[swapchain]->IDirect3DSwapChain9Ex_iface, + d3d9_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[swapchain]); + hr = IDirect3DSwapChain9Ex_GetBackBuffer(&d3d9_swapchain->IDirect3DSwapChain9Ex_iface, backbuffer_idx, backbuffer_type, backbuffer); wined3d_mutex_unlock(); @@ -1327,29 +1414,28 @@ static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, U return D3D_OK; } -static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width, UINT height, - D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool, - D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, void *user_mem) +static HRESULT d3d9_device_create_surface(struct d3d9_device *device, unsigned int flags, + enum wined3d_format_id format, enum wined3d_multisample_type multisample_type, + unsigned int multisample_quality, unsigned int usage, unsigned int bind_flags, unsigned int access, + unsigned int width, unsigned int height, void *user_mem, IDirect3DSurface9 **surface) { struct wined3d_resource_desc desc; struct d3d9_surface *surface_impl; struct wined3d_texture *texture; HRESULT hr; - TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p.\n" - "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n", - device, width, height, format, flags, surface, usage, pool, - multisample_type, multisample_quality); + TRACE("device %p, flags %#x, format %#x, multisample_type %#x, multisample_quality %u, " + "usage %#x, bind_flags %#x, access %#x, width %u, height %u, user_mem %p, surface %p.\n", + device, flags, format, multisample_type, multisample_quality, usage, + bind_flags, access, width, height, user_mem, surface); desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = wined3dformat_from_d3dformat(format); + desc.format = format; desc.multisample_type = multisample_type; desc.multisample_quality = multisample_quality; - desc.usage = usage & WINED3DUSAGE_MASK; - if (pool == D3DPOOL_SCRATCH) - desc.usage |= WINED3DUSAGE_SCRATCH; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.usage = usage; + desc.bind_flags = bind_flags; + desc.access = access; desc.width = width; desc.height = height; desc.depth = 1; @@ -1407,7 +1493,7 @@ static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - DWORD flags = 0; + unsigned int access = WINED3D_RESOURCE_ACCESS_GPU; TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n" "lockable %#x, surface %p, shared_handle %p.\n", @@ -1427,10 +1513,10 @@ static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, } if (lockable) - flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - return d3d9_device_create_surface(device, width, height, format, flags, surface, - D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); + return d3d9_device_create_surface(device, 0, wined3dformat_from_d3dformat(format), multisample_type, + multisample_quality, 0, WINED3D_BIND_RENDER_TARGET, access, width, height, NULL, surface); } static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface, UINT width, UINT height, @@ -1438,7 +1524,7 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex * BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; + DWORD flags = 0; TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n" "discard %#x, surface %p, shared_handle %p.\n", @@ -1460,8 +1546,9 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex * if (discard) flags |= WINED3D_TEXTURE_CREATE_DISCARD; - return d3d9_device_create_surface(device, width, height, format, flags, surface, - D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); + return d3d9_device_create_surface(device, flags, wined3dformat_from_d3dformat(format), + multisample_type, multisample_quality, 0, WINED3D_BIND_DEPTH_STENCIL, + WINED3D_RESOURCE_ACCESS_GPU, width, height, NULL, surface); } @@ -1476,8 +1563,8 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, struct wined3d_box src_box; HRESULT hr; - TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n", - iface, src_surface, src_rect, dst_surface, dst_point); + TRACE("iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %p.\n", + iface, src_surface, wine_dbgstr_rect(src_rect), dst_surface, dst_point); wined3d_mutex_lock(); @@ -1500,7 +1587,7 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0, dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture), - src->sub_resource_idx, &src_box); + src->sub_resource_idx, &src_box, 0); if (SUCCEEDED(hr) && dst->texture) d3d9_texture_flag_auto_gen_mipmap(dst->texture); @@ -1577,7 +1664,7 @@ static HRESULT WINAPI d3d9_device_GetFrontBufferData(IDirect3DDevice9Ex *iface, wined3d_mutex_lock(); if (swapchain < device->implicit_swapchain_count) - hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchains[swapchain]->wined3d_swapchain, + hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchains[swapchain], dst_impl->wined3d_texture, dst_impl->sub_resource_idx); wined3d_mutex_unlock(); @@ -1594,8 +1681,8 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect HRESULT hr = D3DERR_INVALIDCALL; RECT d, s; - TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n", - iface, src_surface, src_rect, dst_surface, dst_rect, filter); + TRACE("iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_rect %s, filter %#x.\n", + iface, src_surface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), filter); wined3d_mutex_lock(); wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &dst_desc); @@ -1623,13 +1710,13 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect goto done; } - if (dst->texture && !(dst_desc.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))) + if (dst->texture && !(dst_desc.bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL))) { WARN("Destination is a regular texture.\n"); goto done; } - if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) + if (src_desc.bind_flags & WINED3D_BIND_DEPTH_STENCIL) { if (device->in_scene) { @@ -1690,6 +1777,9 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, surface, rect, color); + if (!surface) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); if (FAILED(wined3d_texture_get_sub_resource_desc(surface_impl->wined3d_texture, @@ -1705,13 +1795,13 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, WARN("Colour fills are not allowed on surfaces with resource access %#x.\n", desc.access); return D3DERR_INVALIDCALL; } - if ((desc.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_TEXTURE)) == WINED3DUSAGE_TEXTURE) + if ((desc.bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_SHADER_RESOURCE)) == WINED3D_BIND_SHADER_RESOURCE) { wined3d_mutex_unlock(); WARN("Colorfill is not allowed on non-RT textures, returning D3DERR_INVALIDCALL.\n"); return D3DERR_INVALIDCALL; } - if (desc.usage & WINED3DUSAGE_DEPTHSTENCIL) + if (desc.bind_flags & WINED3D_BIND_DEPTH_STENCIL) { wined3d_mutex_unlock(); WARN("Colorfill is not allowed on depth stencil surfaces, returning D3DERR_INVALIDCALL.\n"); @@ -1735,6 +1825,7 @@ static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex HANDLE *shared_handle) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + unsigned int usage, access; void *user_mem = NULL; TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n", @@ -1768,11 +1859,14 @@ static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex } } - /* FIXME: Offscreen surfaces are supposed to be always lockable, - * regardless of the pool they're created in. Should we set dynamic usage - * here? */ - return d3d9_device_create_surface(device, width, height, format, - WINED3D_TEXTURE_CREATE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0, user_mem); + usage = 0; + if (pool == D3DPOOL_SCRATCH) + usage |= WINED3DUSAGE_SCRATCH; + access = wined3daccess_from_d3dpool(pool, usage) + | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + + return d3d9_device_create_surface(device, 0, wined3dformat_from_d3dformat(format), + WINED3D_MULTISAMPLE_NONE, 0, usage, 0, access, width, height, user_mem, surface); } static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface) @@ -1855,16 +1949,17 @@ static HRESULT WINAPI d3d9_device_SetDepthStencilSurface(IDirect3DDevice9Ex *ifa struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_surface *ds_impl = unsafe_impl_from_IDirect3DSurface9(depth_stencil); struct wined3d_rendertarget_view *rtv; + HRESULT hr; TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil); wined3d_mutex_lock(); rtv = ds_impl ? d3d9_surface_acquire_rendertarget_view(ds_impl) : NULL; - wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); + hr = wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); d3d9_surface_release_rendertarget_view(ds_impl, rtv); wined3d_mutex_unlock(); - return D3D_OK; + return hr; } static HRESULT WINAPI d3d9_device_GetDepthStencilSurface(IDirect3DDevice9Ex *iface, IDirect3DSurface9 **depth_stencil) @@ -1944,14 +2039,8 @@ static void d3d9_rts_flag_auto_gen_mipmap(struct d3d9_device *device) static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) { - const struct wined3d_color c = - { - ((color >> 16) & 0xff) / 255.0f, - ((color >> 8) & 0xff) / 255.0f, - (color & 0xff) / 255.0f, - ((color >> 24) & 0xff) / 255.0f, - }; struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_color c; HRESULT hr; TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n", @@ -1963,6 +2052,7 @@ static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_co rect_count = 0; } + wined3d_color_from_d3dcolor(&c, color); wined3d_mutex_lock(); hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); if (SUCCEEDED(hr)) @@ -2032,7 +2122,7 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D vp.max_z = viewport->MaxZ; wined3d_mutex_lock(); - wined3d_device_set_viewport(device->wined3d_device, &vp); + wined3d_device_set_viewports(device->wined3d_device, 1, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -2046,7 +2136,7 @@ static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEW TRACE("iface %p, viewport %p.\n", iface, viewport); wined3d_mutex_lock(); - wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); + wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport); wined3d_mutex_unlock(); viewport->X = wined3d_viewport.x; @@ -2181,11 +2271,26 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetRenderState(IDirect3DDevi D3DRENDERSTATETYPE state, DWORD value) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_color factor; TRACE("iface %p, state %#x, value %#x.\n", iface, state, value); + if (state == D3DRS_BLENDFACTOR) + { + wined3d_color_from_d3dcolor(&factor, value); + wined3d_mutex_lock(); + wined3d_stateblock_set_blend_factor(device->update_state, &factor); + if (!device->recording) + wined3d_device_set_blend_state(device->wined3d_device, NULL, &factor); + wined3d_mutex_unlock(); + + return D3D_OK; + } + wined3d_mutex_lock(); - wined3d_device_set_render_state(device->wined3d_device, state, value); + wined3d_stateblock_set_render_state(device->update_state, state, value); + if (!device->recording) + wined3d_device_set_render_state(device->wined3d_device, state, value); wined3d_mutex_unlock(); return D3D_OK; @@ -2195,9 +2300,20 @@ static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface, D3DRENDERSTATETYPE state, DWORD *value) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_color factor; TRACE("iface %p, state %#x, value %p.\n", iface, state, value); + if (state == D3DRS_BLENDFACTOR) + { + wined3d_mutex_lock(); + wined3d_device_get_blend_state(device->wined3d_device, &factor); + wined3d_mutex_unlock(); + *value = D3DCOLOR_COLORVALUE(factor.r, factor.g, factor.b, factor.a); + + return D3D_OK; + } + wined3d_mutex_lock(); *value = wined3d_device_get_render_state(device->wined3d_device, state); wined3d_mutex_unlock(); @@ -2220,6 +2336,15 @@ static HRESULT WINAPI d3d9_device_CreateStateBlock(IDirect3DDevice9Ex *iface, return D3DERR_INVALIDCALL; } + wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to create a stateblock while recording, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_unlock(); + if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -2240,12 +2365,14 @@ static HRESULT WINAPI d3d9_device_CreateStateBlock(IDirect3DDevice9Ex *iface, static HRESULT WINAPI d3d9_device_BeginStateBlock(IDirect3DDevice9Ex *iface) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_stateblock *stateblock; HRESULT hr; TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_device_begin_stateblock(device->wined3d_device); + if (SUCCEEDED(hr = wined3d_device_begin_stateblock(device->wined3d_device, &stateblock))) + device->update_state = device->recording = stateblock; wined3d_mutex_unlock(); return hr; @@ -2261,13 +2388,17 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire TRACE("iface %p, stateblock %p.\n", iface, stateblock); wined3d_mutex_lock(); - hr = wined3d_device_end_stateblock(device->wined3d_device, &wined3d_stateblock); - wined3d_mutex_unlock(); + hr = wined3d_device_end_stateblock(device->wined3d_device); if (FAILED(hr)) { - WARN("Failed to end the state block, hr %#x.\n", hr); - return hr; + wined3d_mutex_unlock(); + WARN("Failed to end the stateblock, hr %#x.\n", hr); + return hr; } + wined3d_stateblock = device->recording; + device->recording = NULL; + device->update_state = device->state; + wined3d_mutex_unlock(); if (!(object = heap_alloc_zero(sizeof(*object)))) { @@ -2353,25 +2484,30 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_texture *texture_impl; - HRESULT hr; TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); texture_impl = unsafe_impl_from_IDirect3DBaseTexture9(texture); wined3d_mutex_lock(); - hr = wined3d_device_set_texture(device->wined3d_device, stage, + wined3d_device_set_texture(device->wined3d_device, stage, texture_impl ? texture_impl->wined3d_texture : NULL); - if (SUCCEEDED(hr)) + if (!device->recording) { - unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage; + unsigned int i = stage < 16 || (stage >= D3DVERTEXTEXTURESAMPLER0 && stage <= D3DVERTEXTEXTURESAMPLER3) + ? stage < 16 ? stage : stage - D3DVERTEXTEXTURESAMPLER0 + 16 : ~0u; - if (stage < ARRAY_SIZE(device->textures)) - device->textures[i] = texture_impl; + if (i < D3D9_MAX_TEXTURE_UNITS) + { + if (texture_impl && texture_impl->usage & D3DUSAGE_AUTOGENMIPMAP) + device->auto_mipmaps |= 1u << i; + else + device->auto_mipmaps &= ~(1u << i); + } } wined3d_mutex_unlock(); - return hr; + return D3D_OK; } static const enum wined3d_texture_stage_state tss_lookup[] = @@ -2535,7 +2671,7 @@ static HRESULT WINAPI d3d9_device_SetScissorRect(IDirect3DDevice9Ex *iface, cons TRACE("iface %p, rect %p.\n", iface, rect); wined3d_mutex_lock(); - wined3d_device_set_scissor_rect(device->wined3d_device, rect); + wined3d_device_set_scissor_rects(device->wined3d_device, 1, rect); wined3d_mutex_unlock(); return D3D_OK; @@ -2548,7 +2684,7 @@ static HRESULT WINAPI d3d9_device_GetScissorRect(IDirect3DDevice9Ex *iface, RECT TRACE("iface %p, rect %p.\n", iface, rect); wined3d_mutex_lock(); - wined3d_device_get_scissor_rect(device->wined3d_device, rect); + wined3d_device_get_scissor_rects(device->wined3d_device, NULL, rect); wined3d_mutex_unlock(); return D3D_OK; @@ -2612,17 +2748,98 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) /* wined3d critical section must be taken by the caller. */ static void d3d9_generate_auto_mipmaps(struct d3d9_device *device) { - unsigned int i; + struct wined3d_texture *texture; + unsigned int i, stage, map; - for (i = 0; i < ARRAY_SIZE(device->textures); ++i) - if (device->textures[i]) - d3d9_texture_gen_auto_mipmap(device->textures[i]); + map = device->auto_mipmaps; + while (map) + { + i = wined3d_bit_scan(&map); + + stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i; + if ((texture = wined3d_device_get_texture(device->wined3d_device, stage))) + d3d9_texture_gen_auto_mipmap(wined3d_texture_get_parent(texture)); + } +} + +static void d3d9_device_upload_sysmem_vertex_buffers(struct d3d9_device *device, + int base_vertex, unsigned int start_vertex, unsigned int vertex_count) +{ + struct wined3d_vertex_declaration *wined3d_decl; + struct wined3d_box box = {0, 0, 0, 1, 0, 1}; + struct d3d9_vertexbuffer *d3d9_buffer; + struct wined3d_resource *dst_resource; + struct d3d9_vertex_declaration *decl; + unsigned int i, offset, stride, map; + struct wined3d_buffer *dst_buffer; + struct wined3d_resource_desc desc; + HRESULT hr; + + if (!device->sysmem_vb) + return; + wined3d_decl = wined3d_device_get_vertex_declaration(device->wined3d_device); + if (!wined3d_decl) + return; + + if (base_vertex >= 0 || start_vertex >= -base_vertex) + start_vertex += base_vertex; + else + FIXME("System memory vertex data offset is negative.\n"); + + decl = wined3d_vertex_declaration_get_parent(wined3d_decl); + map = decl->stream_map & device->sysmem_vb; + while (map) + { + i = wined3d_bit_scan(&map); + + if (FAILED(hr = wined3d_device_get_stream_source(device->wined3d_device, i, &dst_buffer, &offset, &stride))) + ERR("Failed to get stream source.\n"); + d3d9_buffer = wined3d_buffer_get_parent(dst_buffer); + dst_resource = wined3d_buffer_get_resource(dst_buffer); + wined3d_resource_get_desc(dst_resource, &desc); + box.left = offset + start_vertex * stride; + box.right = min(box.left + vertex_count * stride, desc.size); + if (FAILED(hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, + dst_resource, 0, box.left, 0, 0, + wined3d_buffer_get_resource(d3d9_buffer->wined3d_buffer), 0, &box, 0))) + ERR("Failed to update buffer.\n"); + } +} + +static void d3d9_device_upload_sysmem_index_buffer(struct d3d9_device *device, + unsigned int start_idx, unsigned int idx_count) +{ + struct wined3d_box box = {0, 0, 0, 1, 0, 1}; + struct wined3d_resource *dst_resource; + struct d3d9_indexbuffer *d3d9_buffer; + struct wined3d_buffer *dst_buffer; + struct wined3d_resource_desc desc; + enum wined3d_format_id format; + unsigned int offset, idx_size; + HRESULT hr; + + if (!device->sysmem_ib) + return; + + if (!(dst_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &format, &offset))) + ERR("Failed to get index buffer.\n"); + d3d9_buffer = wined3d_buffer_get_parent(dst_buffer); + dst_resource = wined3d_buffer_get_resource(dst_buffer); + wined3d_resource_get_desc(dst_resource, &desc); + idx_size = format == WINED3DFMT_R16_UINT ? 2 : 4; + box.left = offset + start_idx * idx_size; + box.right = min(box.left + idx_count * idx_size, desc.size); + if (FAILED(hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, + dst_resource, 0, box.left, 0, 0, + wined3d_buffer_get_resource(d3d9_buffer->wined3d_buffer), 0, &box, 0))) + ERR("Failed to update buffer.\n"); } static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + unsigned int vertex_count; HRESULT hr; TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n", @@ -2635,10 +2852,11 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, WARN("Called without a valid vertex declaration set.\n"); return D3DERR_INVALIDCALL; } + vertex_count = vertex_count_from_primitive_count(primitive_type, primitive_count); + d3d9_device_upload_sysmem_vertex_buffers(device, 0, start_vertex, vertex_count); d3d9_generate_auto_mipmaps(device); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); - hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, - vertex_count_from_primitive_count(primitive_type, primitive_count)); + hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count); if (SUCCEEDED(hr)) d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock(); @@ -2651,6 +2869,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface UINT vertex_count, UINT start_idx, UINT primitive_count) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + unsigned int index_count; HRESULT hr; TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u, " @@ -2665,11 +2884,13 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface WARN("Called without a valid vertex declaration set.\n"); return D3DERR_INVALIDCALL; } + index_count = vertex_count_from_primitive_count(primitive_type, primitive_count); + d3d9_device_upload_sysmem_vertex_buffers(device, base_vertex_idx, min_vertex_idx, vertex_count); + d3d9_device_upload_sysmem_index_buffer(device, start_idx, index_count); d3d9_generate_auto_mipmaps(device); wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); - hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, - vertex_count_from_primitive_count(primitive_type, primitive_count)); + hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, index_count); if (SUCCEEDED(hr)) d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock(); @@ -2691,9 +2912,9 @@ static HRESULT d3d9_device_prepare_vertex_buffer(struct d3d9_device *device, UIN TRACE("Growing vertex buffer to %u bytes.\n", size); desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY; + desc.usage = WINED3DUSAGE_DYNAMIC; desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -2729,9 +2950,14 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n", iface, primitive_type, primitive_count, data, stride); + if (!stride) + { + WARN("stride is 0, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (!primitive_count) { - WARN("primitive_count is 0, returning D3D_OK\n"); + WARN("primitive_count is 0, returning D3D_OK.\n"); return D3D_OK; } @@ -2796,9 +3022,9 @@ static HRESULT d3d9_device_prepare_index_buffer(struct d3d9_device *device, UINT TRACE("Growing index buffer to %u bytes.\n", size); desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL; + desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_STATICDECL; desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -2840,6 +3066,11 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa iface, primitive_type, min_vertex_idx, vertex_count, primitive_count, index_data, index_format, vertex_data, vertex_stride); + if (!vertex_stride) + { + WARN("vertex_stride is 0, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (!primitive_count) { WARN("primitive_count is 0, returning D3D_OK.\n"); @@ -2913,7 +3144,6 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); - wined3d_device_set_base_vertex_index(device->wined3d_device, 0); if (SUCCEEDED(hr)) d3d9_rts_flag_auto_gen_mipmap(device); @@ -2930,15 +3160,53 @@ static HRESULT WINAPI d3d9_device_ProcessVertices(IDirect3DDevice9Ex *iface, struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_vertexbuffer *dst_impl = unsafe_impl_from_IDirect3DVertexBuffer9(dst_buffer); struct d3d9_vertex_declaration *decl_impl = unsafe_impl_from_IDirect3DVertexDeclaration9(declaration); + struct d3d9_vertexbuffer *d3d9_buffer; + struct wined3d_buffer *wined3d_buffer; + unsigned int i, offset, stride, map; HRESULT hr; TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n", iface, src_start_idx, dst_idx, vertex_count, dst_buffer, declaration, flags); wined3d_mutex_lock(); + + /* Note that an alternative approach would be to simply create these + * buffers with WINED3D_RESOURCE_ACCESS_MAP_R and update them here like we + * do for draws. In some regards that would be easier, but it seems less + * than optimal to upload data to the GPU only to subsequently download it + * again. */ + map = device->sysmem_vb; + while (map) + { + i = wined3d_bit_scan(&map); + + if (FAILED(wined3d_device_get_stream_source(device->wined3d_device, + i, &wined3d_buffer, &offset, &stride))) + ERR("Failed to get stream source.\n"); + d3d9_buffer = wined3d_buffer_get_parent(wined3d_buffer); + if (FAILED(wined3d_device_set_stream_source(device->wined3d_device, + i, d3d9_buffer->wined3d_buffer, offset, stride))) + ERR("Failed to set stream source.\n"); + } + hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, vertex_count, dst_impl->wined3d_buffer, decl_impl ? decl_impl->wined3d_declaration : NULL, flags, dst_impl->fvf); + + map = device->sysmem_vb; + while (map) + { + i = wined3d_bit_scan(&map); + + if (FAILED(wined3d_device_get_stream_source(device->wined3d_device, + i, &wined3d_buffer, &offset, &stride))) + ERR("Failed to get stream source.\n"); + d3d9_buffer = wined3d_buffer_get_parent(wined3d_buffer); + if (FAILED(wined3d_device_set_stream_source(device->wined3d_device, + i, d3d9_buffer->draw_buffer, offset, stride))) + ERR("Failed to set stream source.\n"); + } + wined3d_mutex_unlock(); return hr; @@ -2974,8 +3242,11 @@ static HRESULT WINAPI d3d9_device_SetVertexDeclaration(IDirect3DDevice9Ex *iface TRACE("iface %p, declaration %p.\n", iface, declaration); wined3d_mutex_lock(); - wined3d_device_set_vertex_declaration(device->wined3d_device, + wined3d_stateblock_set_vertex_declaration(device->update_state, decl_impl ? decl_impl->wined3d_declaration : NULL); + if (!device->recording) + wined3d_device_set_vertex_declaration(device->wined3d_device, + decl_impl ? decl_impl->wined3d_declaration : NULL); device->has_vertex_declaration = !!decl_impl; wined3d_mutex_unlock(); @@ -3098,7 +3369,9 @@ static HRESULT WINAPI d3d9_device_SetFVF(IDirect3DDevice9Ex *iface, DWORD fvf) return D3DERR_DRIVERINTERNALERROR; } - wined3d_device_set_vertex_declaration(device->wined3d_device, decl); + wined3d_stateblock_set_vertex_declaration(device->update_state, decl); + if (!device->recording) + wined3d_device_set_vertex_declaration(device->wined3d_device, decl); device->has_vertex_declaration = TRUE; wined3d_mutex_unlock(); @@ -3164,8 +3437,11 @@ static HRESULT WINAPI d3d9_device_SetVertexShader(IDirect3DDevice9Ex *iface, IDi TRACE("iface %p, shader %p.\n", iface, shader); wined3d_mutex_lock(); - wined3d_device_set_vertex_shader(device->wined3d_device, + wined3d_stateblock_set_vertex_shader(device->update_state, shader_obj ? shader_obj->wined3d_shader : NULL); + if (!device->recording) + wined3d_device_set_vertex_shader(device->wined3d_device, + shader_obj ? shader_obj->wined3d_shader : NULL); wined3d_mutex_unlock(); return D3D_OK; @@ -3201,20 +3477,31 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantF(IDirect3DDevice9Ex *i UINT reg_idx, const float *data, UINT count) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_device_creation_parameters creation_parameters; + unsigned int max_constants; HRESULT hr; TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); - if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF) + wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters); + max_constants = creation_parameters.flags + & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) + ? D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP : D3D9_MAX_VERTEX_SHADER_CONSTANTF; + if (reg_idx + count > max_constants) { WARN("Trying to access %u constants, but d3d9 only supports %u\n", - reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF); + reg_idx + count, max_constants); return D3DERR_INVALIDCALL; } wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_f(device->wined3d_device, - reg_idx, count, (const struct wined3d_vec4 *)data); + hr = wined3d_stateblock_set_vs_consts_f(device->update_state, reg_idx, + count, (const struct wined3d_vec4 *)data); + if (SUCCEEDED(hr) && !device->recording) + { + hr = wined3d_device_set_vs_consts_f(device->wined3d_device, + reg_idx, count, (const struct wined3d_vec4 *)data); + } wined3d_mutex_unlock(); return hr; @@ -3224,14 +3511,20 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *i UINT reg_idx, float *data, UINT count) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_device_creation_parameters creation_parameters; + unsigned int max_constants; HRESULT hr; TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); - if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF) + wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters); + max_constants = creation_parameters.flags + & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) + ? D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP : D3D9_MAX_VERTEX_SHADER_CONSTANTF; + if (reg_idx + count > max_constants) { WARN("Trying to access %u constants, but d3d9 only supports %u\n", - reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF); + reg_idx + count, max_constants); return D3DERR_INVALIDCALL; } @@ -3252,8 +3545,11 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantI(IDirect3DDevice9Ex *i TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_i(device->wined3d_device, + hr = wined3d_stateblock_set_vs_consts_i(device->update_state, reg_idx, count, (const struct wined3d_ivec4 *)data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_vs_consts_i(device->wined3d_device, + reg_idx, count, (const struct wined3d_ivec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3284,7 +3580,9 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantB(IDirect3DDevice9Ex *i TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_b(device->wined3d_device, reg_idx, count, data); + hr = wined3d_stateblock_set_vs_consts_b(device->update_state, reg_idx, count, data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_vs_consts_b(device->wined3d_device, reg_idx, count, data); wined3d_mutex_unlock(); return hr; @@ -3310,14 +3608,33 @@ static HRESULT WINAPI d3d9_device_SetStreamSource(IDirect3DDevice9Ex *iface, { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer9(buffer); + struct wined3d_buffer *wined3d_buffer; HRESULT hr; TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n", iface, stream_idx, buffer, offset, stride); wined3d_mutex_lock(); - hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx, - buffer_impl ? buffer_impl->wined3d_buffer : NULL, offset, stride); + if (!buffer_impl) + wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, + &offset, &stride); + + if (!buffer_impl) + wined3d_buffer = NULL; + else if (buffer_impl->draw_buffer) + wined3d_buffer = buffer_impl->draw_buffer; + else + wined3d_buffer = buffer_impl->wined3d_buffer; + + hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx, wined3d_buffer, offset, stride); + if (SUCCEEDED(hr) && !device->recording) + { + if (buffer_impl && buffer_impl->draw_buffer) + device->sysmem_vb |= (1u << stream_idx); + else + device->sysmem_vb &= ~(1u << stream_idx); + } + wined3d_mutex_unlock(); return hr; @@ -3388,12 +3705,21 @@ static HRESULT WINAPI d3d9_device_SetIndices(IDirect3DDevice9Ex *iface, IDirect3 { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer9(buffer); + struct wined3d_buffer *wined3d_buffer; TRACE("iface %p, buffer %p.\n", iface, buffer); + if (!ib) + wined3d_buffer = NULL; + else if (ib->draw_buffer) + wined3d_buffer = ib->draw_buffer; + else + wined3d_buffer = ib->wined3d_buffer; + wined3d_mutex_lock(); - wined3d_device_set_index_buffer(device->wined3d_device, - ib ? ib->wined3d_buffer : NULL, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); + wined3d_device_set_index_buffer(device->wined3d_device, wined3d_buffer, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); + if (!device->recording) + device->sysmem_ib = ib && ib->draw_buffer; wined3d_mutex_unlock(); return D3D_OK; @@ -3464,8 +3790,11 @@ static HRESULT WINAPI d3d9_device_SetPixelShader(IDirect3DDevice9Ex *iface, IDir TRACE("iface %p, shader %p.\n", iface, shader); wined3d_mutex_lock(); - wined3d_device_set_pixel_shader(device->wined3d_device, + wined3d_stateblock_set_pixel_shader(device->update_state, shader_obj ? shader_obj->wined3d_shader : NULL); + if (!device->recording) + wined3d_device_set_pixel_shader(device->wined3d_device, + shader_obj ? shader_obj->wined3d_shader : NULL); wined3d_mutex_unlock(); return D3D_OK; @@ -3508,8 +3837,11 @@ static HRESULT WINAPI d3d9_device_SetPixelShaderConstantF(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_f(device->wined3d_device, + hr = wined3d_stateblock_set_ps_consts_f(device->update_state, reg_idx, count, (const struct wined3d_vec4 *)data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_ps_consts_f(device->wined3d_device, + reg_idx, count, (const struct wined3d_vec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3540,8 +3872,11 @@ static HRESULT WINAPI d3d9_device_SetPixelShaderConstantI(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_i(device->wined3d_device, + hr = wined3d_stateblock_set_ps_consts_i(device->update_state, reg_idx, count, (const struct wined3d_ivec4 *)data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_ps_consts_i(device->wined3d_device, + reg_idx, count, (const struct wined3d_ivec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3572,7 +3907,9 @@ static HRESULT WINAPI d3d9_device_SetPixelShaderConstantB(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_b(device->wined3d_device, reg_idx, count, data); + hr = wined3d_stateblock_set_ps_consts_b(device->update_state, reg_idx, count, data); + if (SUCCEEDED(hr) && !device->recording) + hr = wined3d_device_set_ps_consts_b(device->wined3d_device, reg_idx, count, data); wined3d_mutex_unlock(); return hr; @@ -3667,7 +4004,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex const RGNDATA *dirty_region, DWORD flags) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - UINT i; + struct d3d9_swapchain *swapchain; + unsigned int i; HRESULT hr; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", @@ -3683,8 +4021,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0, flags))) + swapchain = wined3d_swapchain_get_parent(device->implicit_swapchains[i]); + if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags))) { wined3d_mutex_unlock(); return hr; @@ -3727,21 +4066,31 @@ static HRESULT WINAPI d3d9_device_CheckResourceResidency(IDirect3DDevice9Ex *ifa static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency) { + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + TRACE("iface %p, max_latency %u.\n", iface, max_latency); - if (max_latency) - FIXME("Ignoring max_latency %u.\n", max_latency); + if (max_latency > 30) + return D3DERR_INVALIDCALL; + + wined3d_mutex_lock(); + wined3d_device_set_max_frame_latency(device->wined3d_device, max_latency); + wined3d_mutex_unlock(); return S_OK; } static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency) { - FIXME("iface %p, max_latency %p stub!\n", iface, max_latency); + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - *max_latency = 2; + TRACE("iface %p, max_latency %p.\n", iface, max_latency); - return E_NOTIMPL; + wined3d_mutex_lock(); + *max_latency = wined3d_device_get_max_frame_latency(device->wined3d_device); + wined3d_mutex_unlock(); + + return S_OK; } static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window) @@ -3752,7 +4101,7 @@ static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HW TRACE("iface %p, dst_window %p.\n", iface, dst_window); wined3d_mutex_lock(); - wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); + wined3d_swapchain_get_desc(device->implicit_swapchains[0], &swapchain_desc); wined3d_mutex_unlock(); if (swapchain_desc.windowed) @@ -3770,16 +4119,31 @@ static HRESULT WINAPI d3d9_device_CreateRenderTargetEx(IDirect3DDevice9Ex *iface UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) { - FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " - "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n", + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + unsigned int access = WINED3D_RESOURCE_ACCESS_GPU; + + TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " + "lockable %#x, surface %p, shared_handle %p, usage %#x.\n", iface, width, height, format, multisample_type, multisample_quality, lockable, surface, shared_handle, usage); *surface = NULL; + + if (usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)) + { + WARN("Invalid usage %#x.\n", usage); + return D3DERR_INVALIDCALL; + } + if (shared_handle) FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); - return E_NOTIMPL; + if (lockable) + access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + + return d3d9_device_create_surface(device, 0, wined3dformat_from_d3dformat(format), + multisample_type, multisample_quality, usage & WINED3DUSAGE_MASK, + WINED3D_BIND_RENDER_TARGET, access, width, height, NULL, surface); } static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface, @@ -3797,14 +4161,14 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; + DWORD flags = 0; TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " "discard %#x, surface %p, shared_handle %p, usage %#x.\n", iface, width, height, format, multisample_type, multisample_quality, discard, surface, shared_handle, usage); - if (usage & D3DUSAGE_DEPTHSTENCIL) + if (usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)) { WARN("Invalid usage %#x.\n", usage); return D3DERR_INVALIDCALL; @@ -3817,8 +4181,9 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex flags |= WINED3D_TEXTURE_CREATE_DISCARD; *surface = NULL; - return d3d9_device_create_surface(device, width, height, format, flags, surface, - D3DUSAGE_DEPTHSTENCIL | usage, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); + return d3d9_device_create_surface(device, flags, wined3dformat_from_d3dformat(format), + multisample_type, multisample_quality, usage & WINED3DUSAGE_MASK, WINED3D_BIND_DEPTH_STENCIL, + WINED3D_RESOURCE_ACCESS_GPU, width, height, NULL, surface); } static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_ResetEx(IDirect3DDevice9Ex *iface, @@ -4050,40 +4415,40 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_NOT_RESET, D3D9_DEVICE_STATE_LOST); } -static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, +static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, + enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { - struct d3d9_surface *d3d_surface; + TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); - TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); - - if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) - return E_OUTOFMEMORY; - - surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_surface; - TRACE("Created surface %p.\n", d3d_surface); - - return D3D_OK; -} + if (type == WINED3D_RTYPE_TEXTURE_2D) + { + struct d3d9_surface *d3d_surface; -static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - void **parent, const struct wined3d_parent_ops **parent_ops) -{ - struct d3d9_volume *d3d_volume; + if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) + return E_OUTOFMEMORY; - TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_surface; + TRACE("Created surface %p.\n", d3d_surface); + } + else if (type == WINED3D_RTYPE_TEXTURE_3D) + { + struct d3d9_volume *d3d_volume; - if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) - return E_OUTOFMEMORY; + if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume)))) + return E_OUTOFMEMORY; - volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); - *parent = d3d_volume; - TRACE("Created volume %p.\n", d3d_volume); + volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); + *parent = d3d_volume; + TRACE("Created volume %p.\n", d3d_volume); + } + else + { + ERR("Unhandled resource type %#x.\n", type); + return E_FAIL; + } return D3D_OK; } @@ -4102,12 +4467,8 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic if (container_parent == device_parent) container_parent = &device->IDirect3DDevice9Ex_iface; - if (is_gdi_compat_wined3dformat(desc->format)) - texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC; - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, - texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent, - &d3d9_null_wined3d_parent_ops, texture))) + texture_flags, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; @@ -4119,39 +4480,13 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return hr; } -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct d3d9_device *device = device_from_device_parent(device_parent); - struct d3d9_swapchain *d3d_swapchain; - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain); - - hr = d3d9_swapchain_create(device, desc, &d3d_swapchain); - if (FAILED(hr)) - { - WARN("Failed to create swapchain, hr %#x.\n", hr); - *swapchain = NULL; - return hr; - } - - *swapchain = d3d_swapchain->wined3d_swapchain; - wined3d_swapchain_incref(*swapchain); - IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface); - - return hr; -} - static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops = { device_parent_wined3d_device_created, device_parent_mode_changed, device_parent_activate, - device_parent_surface_created, - device_parent_volume_created, + device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; static void setup_fpu(void) @@ -4176,10 +4511,22 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode) { struct wined3d_swapchain_desc *swapchain_desc; + struct d3d9_swapchain *d3d_swapchain; + struct wined3d_caps caps; unsigned i, count = 1; - WINED3DCAPS caps; HRESULT hr; + static const enum wined3d_feature_level feature_levels[] = + { + WINED3D_FEATURE_LEVEL_9_3, + WINED3D_FEATURE_LEVEL_9_2, + WINED3D_FEATURE_LEVEL_9_1, + WINED3D_FEATURE_LEVEL_8, + WINED3D_FEATURE_LEVEL_7, + WINED3D_FEATURE_LEVEL_6, + WINED3D_FEATURE_LEVEL_5, + }; + if (mode) FIXME("Ignoring display mode.\n"); @@ -4190,7 +4537,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); wined3d_mutex_lock(); - if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4, + if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, + focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels), &device->device_parent, &device->wined3d_device))) { WARN("Failed to create wined3d device, hr %#x.\n", hr); @@ -4203,6 +4551,15 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine if (flags & D3DCREATE_ADAPTERGROUP_DEVICE) count = caps.NumberOfAdaptersInGroup; + if (FAILED(hr = wined3d_stateblock_create(device->wined3d_device, WINED3D_SBT_PRIMARY, &device->state))) + { + ERR("Failed to create the primary stateblock, hr %#x.\n", hr); + wined3d_device_decref(device->wined3d_device); + wined3d_mutex_unlock(); + return hr; + } + device->update_state = device->state; + if (flags & D3DCREATE_MULTITHREADED) wined3d_device_set_multithreaded(device->wined3d_device); @@ -4217,16 +4574,6 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine wined3d_mutex_unlock(); return hr; } - - for (i = 0; i < count; ++i) - { - HWND device_window = parameters[i].hDeviceWindow; - - if (!device_window) device_window = focus_window; - wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window, - parameters[i].BackBufferWidth, - parameters[i].BackBufferHeight); - } } if (!(swapchain_desc = heap_alloc(sizeof(*swapchain_desc) * count))) @@ -4249,11 +4596,13 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } + swapchain_desc[i].flags |= WINED3D_SWAPCHAIN_IMPLICIT; } - if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc))) + if (FAILED(hr = d3d9_swapchain_create(device, swapchain_desc, + wined3dswapinterval_from_d3d(parameters->PresentationInterval), &d3d_swapchain))) { - WARN("Failed to initialize 3D, hr %#x.\n", hr); + WARN("Failed to create swapchain, hr %#x.\n", hr); wined3d_device_release_focus_window(device->wined3d_device); heap_free(swapchain_desc); wined3d_device_decref(device->wined3d_device); @@ -4261,21 +4610,26 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine return hr; } + wined3d_swapchain_incref(d3d_swapchain->wined3d_swapchain); + IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc->enable_auto_depth_stencil); if (FAILED(hr = d3d9_device_get_swapchains(device))) { - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(d3d_swapchain->wined3d_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); + heap_free(swapchain_desc); wined3d_mutex_unlock(); return E_OUTOFMEMORY; } for (i = 0; i < count; ++i) { - present_parameters_from_wined3d_swapchain_desc(¶meters[i], &swapchain_desc[i]); + present_parameters_from_wined3d_swapchain_desc(¶meters[i], + &swapchain_desc[i], parameters[i].PresentationInterval); } wined3d_mutex_unlock(); @@ -4289,7 +4643,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine ERR("Failed to allocate FVF vertex declaration map memory.\n"); wined3d_mutex_lock(); heap_free(device->implicit_swapchains); - wined3d_device_uninit_3d(device->wined3d_device); + wined3d_swapchain_decref(d3d_swapchain->wined3d_swapchain); wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c index 644766c2e97..3a3d02ce852 100644 --- a/dll/directx/wine/d3d9/directx.c +++ b/dll/directx/wine/d3d9/directx.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -137,17 +136,16 @@ static HRESULT WINAPI d3d9_GetAdapterIdentifier(IDirect3D9Ex *iface, UINT adapte adapter_id.device_name = identifier->DeviceName; adapter_id.device_name_size = sizeof(identifier->DeviceName); - wined3d_mutex_lock(); - hr = wined3d_get_adapter_identifier(d3d9->wined3d, adapter, flags, &adapter_id); - wined3d_mutex_unlock(); - - identifier->DriverVersion = adapter_id.driver_version; - identifier->VendorId = adapter_id.vendor_id; - identifier->DeviceId = adapter_id.device_id; - identifier->SubSysId = adapter_id.subsystem_id; - identifier->Revision = adapter_id.revision; - memcpy(&identifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(identifier->DeviceIdentifier)); - identifier->WHQLLevel = adapter_id.whql_level; + if (SUCCEEDED(hr = wined3d_get_adapter_identifier(d3d9->wined3d, adapter, flags, &adapter_id))) + { + identifier->DriverVersion = adapter_id.driver_version; + identifier->VendorId = adapter_id.vendor_id; + identifier->DeviceId = adapter_id.device_id; + identifier->SubSysId = adapter_id.subsystem_id; + identifier->Revision = adapter_id.revision; + memcpy(&identifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(identifier->DeviceIdentifier)); + identifier->WHQLLevel = adapter_id.whql_level; + } return hr; } @@ -249,25 +247,34 @@ static HRESULT WINAPI d3d9_CheckDeviceFormat(IDirect3D9Ex *iface, UINT adapter, { struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface); enum wined3d_resource_type wined3d_rtype; + unsigned int bind_flags; HRESULT hr; TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n", iface, adapter, device_type, adapter_format, usage, resource_type, format); + if (adapter_format != D3DFMT_X8R8G8B8 && adapter_format != D3DFMT_R5G6B5 + && adapter_format != D3DFMT_X1R5G5B5) + { + WARN("Invalid adapter format.\n"); + return adapter_format ? D3DERR_NOTAVAILABLE : D3DERR_INVALIDCALL; + } + + bind_flags = wined3d_bind_flags_from_d3d9_usage(usage); usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { case D3DRTYPE_CUBETEXTURE: usage |= WINED3DUSAGE_LEGACY_CUBEMAP; case D3DRTYPE_TEXTURE: - usage |= WINED3DUSAGE_TEXTURE; + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; case D3DRTYPE_SURFACE: wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; break; case D3DRTYPE_VOLUMETEXTURE: case D3DRTYPE_VOLUME: - usage |= WINED3DUSAGE_TEXTURE; + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; wined3d_rtype = WINED3D_RTYPE_TEXTURE_3D; break; @@ -283,7 +290,7 @@ static HRESULT WINAPI d3d9_CheckDeviceFormat(IDirect3D9Ex *iface, UINT adapter, wined3d_mutex_lock(); hr = wined3d_check_device_format(d3d9->wined3d, adapter, device_type, wined3dformat_from_d3dformat(adapter_format), - usage, wined3d_rtype, wined3dformat_from_d3dformat(format)); + usage, bind_flags, wined3d_rtype, wined3dformat_from_d3dformat(format)); wined3d_mutex_unlock(); return hr; @@ -349,7 +356,7 @@ static HRESULT WINAPI d3d9_CheckDeviceFormatConversion(IDirect3D9Ex *iface, UINT static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type, D3DCAPS9 *caps) { struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface); - WINED3DCAPS wined3d_caps; + struct wined3d_caps wined3d_caps; HRESULT hr; TRACE("iface %p, adapter %u, device_type %#x, caps %p.\n", iface, adapter, device_type, caps); @@ -363,7 +370,7 @@ static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DD hr = wined3d_get_device_caps(d3d9->wined3d, adapter, device_type, &wined3d_caps); wined3d_mutex_unlock(); - d3dcaps_from_wined3dcaps(caps, &wined3d_caps); + d3dcaps_from_wined3dcaps(caps, &wined3d_caps, 0); return hr; } @@ -536,11 +543,8 @@ static HRESULT WINAPI d3d9_GetAdapterLUID(IDirect3D9Ex *iface, UINT adapter, LUI adapter_id.description_size = 0; adapter_id.device_name_size = 0; - wined3d_mutex_lock(); - hr = wined3d_get_adapter_identifier(d3d9->wined3d, adapter, 0, &adapter_id); - wined3d_mutex_unlock(); - - memcpy(luid, &adapter_id.adapter_luid, sizeof(*luid)); + if (SUCCEEDED(hr = wined3d_get_adapter_identifier(d3d9->wined3d, adapter, 0, &adapter_id))) + *luid = adapter_id.adapter_luid; return hr; } @@ -579,7 +583,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING - | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LIMIT_VIEWPORT; + | WINED3D_NORMALIZED_DEPTH_BIAS; if (!extended) flags |= WINED3D_VIDMEM_ACCOUNTING; diff --git a/dll/directx/wine/d3d9/query.c b/dll/directx/wine/d3d9/query.c index 12ff95b5a06..e9180fb481f 100644 --- a/dll/directx/wine/d3d9/query.c +++ b/dll/directx/wine/d3d9/query.c @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); diff --git a/dll/directx/wine/d3d9/shader.c b/dll/directx/wine/d3d9/shader.c index 9cb398388b9..838c7de2cf0 100644 --- a/dll/directx/wine/d3d9/shader.c +++ b/dll/directx/wine/d3d9/shader.c @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -144,11 +143,6 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device * desc.byte_code = byte_code; desc.byte_code_size = ~(size_t)0; - desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; - desc.input_signature.element_count = 0; - desc.output_signature.element_count = 0; - desc.patch_constant_signature.element_count = 0; - desc.max_version = 3; wined3d_mutex_lock(); hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader, @@ -298,11 +292,6 @@ HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *de desc.byte_code = byte_code; desc.byte_code_size = ~(size_t)0; - desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; - desc.input_signature.element_count = 0; - desc.output_signature.element_count = 0; - desc.patch_constant_signature.element_count = 0; - desc.max_version = 3; wined3d_mutex_lock(); hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader, diff --git a/dll/directx/wine/d3d9/stateblock.c b/dll/directx/wine/d3d9/stateblock.c index 62b3bacb28d..02213280181 100644 --- a/dll/directx/wine/d3d9/stateblock.c +++ b/dll/directx/wine/d3d9/stateblock.c @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -95,10 +94,18 @@ static HRESULT WINAPI d3d9_stateblock_GetDevice(IDirect3DStateBlock9 *iface, IDi static HRESULT WINAPI d3d9_stateblock_Capture(IDirect3DStateBlock9 *iface) { struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); + struct d3d9_device *device; TRACE("iface %p.\n", iface); wined3d_mutex_lock(); + device = impl_from_IDirect3DDevice9Ex(stateblock->parent_device); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to capture stateblock while recording, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } wined3d_stateblock_capture(stateblock->wined3d_stateblock); wined3d_mutex_unlock(); @@ -108,11 +115,51 @@ static HRESULT WINAPI d3d9_stateblock_Capture(IDirect3DStateBlock9 *iface) static HRESULT WINAPI d3d9_stateblock_Apply(IDirect3DStateBlock9 *iface) { struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); + struct wined3d_texture *wined3d_texture; + unsigned int i, offset, stride, stage; + struct wined3d_buffer *wined3d_buffer; + struct d3d9_vertexbuffer *buffer; + enum wined3d_format_id format; + struct d3d9_texture *texture; + struct d3d9_device *device; + HRESULT hr; TRACE("iface %p.\n", iface); wined3d_mutex_lock(); + device = impl_from_IDirect3DDevice9Ex(stateblock->parent_device); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to apply stateblock while recording, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } wined3d_stateblock_apply(stateblock->wined3d_stateblock); + device->sysmem_vb = 0; + for (i = 0; i < D3D9_MAX_STREAMS; ++i) + { + if (FAILED(hr = wined3d_device_get_stream_source(device->wined3d_device, + i, &wined3d_buffer, &offset, &stride))) + continue; + if (!wined3d_buffer || !(buffer = wined3d_buffer_get_parent(wined3d_buffer))) + continue; + if (buffer->draw_buffer) + device->sysmem_vb |= 1u << i; + } + device->sysmem_ib = (wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &format, &offset)) + && (buffer = wined3d_buffer_get_parent(wined3d_buffer)) && buffer->draw_buffer; + device->auto_mipmaps = 0; + for (i = 0; i < D3D9_MAX_TEXTURE_UNITS; ++i) + { + stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i; + + if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage)) + && (texture = wined3d_texture_get_parent(wined3d_texture)) + && texture->usage & D3DUSAGE_AUTOGENMIPMAP) + device->auto_mipmaps |= 1u << i; + else + device->auto_mipmaps &= ~(1u << i); + } wined3d_mutex_unlock(); return D3D_OK; diff --git a/dll/directx/wine/d3d9/surface.c b/dll/directx/wine/d3d9/surface.c index 0605e7142a3..b74f6cacf7e 100644 --- a/dll/directx/wine/d3d9/surface.c +++ b/dll/directx/wine/d3d9/surface.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -223,7 +222,7 @@ static HRESULT WINAPI d3d9_surface_GetDesc(IDirect3DSurface9 *iface, D3DSURFACE_ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->MultiSampleType = wined3d_desc.multisample_type; desc->MultiSampleQuality = wined3d_desc.multisample_quality; @@ -249,7 +248,7 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface, wined3d_mutex_lock(); hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, - &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags)); + &map_desc, rect ? &box : NULL, wined3dmapflags_from_d3dmapflags(flags, 0)); wined3d_mutex_unlock(); if (SUCCEEDED(hr)) @@ -258,6 +257,8 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface, locked_rect->pBits = map_desc.data; } + if (hr == E_INVALIDARG) + return D3DERR_INVALIDCALL; return hr; } diff --git a/dll/directx/wine/d3d9/swapchain.c b/dll/directx/wine/d3d9/swapchain.c index dbb3f45b91d..be9c55ac3ef 100644 --- a/dll/directx/wine/d3d9/swapchain.c +++ b/dll/directx/wine/d3d9/swapchain.c @@ -20,11 +20,31 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); +static DWORD d3dpresentationinterval_from_wined3dswapinterval(enum wined3d_swap_interval interval) +{ + switch (interval) + { + case WINED3D_SWAP_INTERVAL_IMMEDIATE: + return D3DPRESENT_INTERVAL_IMMEDIATE; + case WINED3D_SWAP_INTERVAL_ONE: + return D3DPRESENT_INTERVAL_ONE; + case WINED3D_SWAP_INTERVAL_TWO: + return D3DPRESENT_INTERVAL_TWO; + case WINED3D_SWAP_INTERVAL_THREE: + return D3DPRESENT_INTERVAL_THREE; + case WINED3D_SWAP_INTERVAL_FOUR: + return D3DPRESENT_INTERVAL_FOUR; + default: + ERR("Invalid swap interval %#x.\n", interval); + case WINED3D_SWAP_INTERVAL_DEFAULT: + return D3DPRESENT_INTERVAL_DEFAULT; + } +} + static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface) { return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface); @@ -79,9 +99,7 @@ static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9Ex *iface) if (swapchain->parent_device) IDirect3DDevice9Ex_AddRef(swapchain->parent_device); - wined3d_mutex_lock(); wined3d_swapchain_incref(swapchain->wined3d_swapchain); - wined3d_mutex_unlock(); } return refcount; @@ -105,9 +123,7 @@ static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface) { IDirect3DDevice9Ex *parent_device = swapchain->parent_device; - wined3d_mutex_lock(); wined3d_swapchain_decref(swapchain->wined3d_swapchain); - wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ if (parent_device) @@ -123,7 +139,6 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(swapchain->parent_device); - HRESULT hr; TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), @@ -135,12 +150,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai if (dirty_region) FIXME("Ignoring dirty_region %p.\n", dirty_region); - wined3d_mutex_lock(); - hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, - src_rect, dst_rect, dst_window_override, 0, flags); - wined3d_mutex_unlock(); - - return hr; + return wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags); } static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9Ex *iface, IDirect3DSurface9 *surface) @@ -251,13 +262,15 @@ static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9Ex { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); struct wined3d_swapchain_desc desc; + DWORD presentation_interval; TRACE("iface %p, parameters %p.\n", iface, parameters); wined3d_mutex_lock(); wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &desc); + presentation_interval = d3dpresentationinterval_from_wined3dswapinterval(swapchain->swap_interval); wined3d_mutex_unlock(); - present_parameters_from_wined3d_swapchain_desc(parameters, &desc); + present_parameters_from_wined3d_swapchain_desc(parameters, &desc, presentation_interval); return D3D_OK; } @@ -344,19 +357,16 @@ static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops = }; static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_device *device, - struct wined3d_swapchain_desc *desc) + struct wined3d_swapchain_desc *desc, unsigned int swap_interval) { HRESULT hr; swapchain->refcount = 1; swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl; + swapchain->swap_interval = swap_interval; - wined3d_mutex_lock(); - hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, - &d3d9_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain); - wined3d_mutex_unlock(); - - if (FAILED(hr)) + if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, + &d3d9_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) { WARN("Failed to create wined3d swapchain, hr %#x.\n", hr); return hr; @@ -369,7 +379,7 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi } HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc, - struct d3d9_swapchain **swapchain) + unsigned int swap_interval, struct d3d9_swapchain **swapchain) { struct d3d9_swapchain *object; HRESULT hr; @@ -377,7 +387,7 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = swapchain_init(object, device, desc))) + if (FAILED(hr = swapchain_init(object, device, desc, swap_interval))) { WARN("Failed to initialize swapchain, hr %#x.\n", hr); heap_free(object); diff --git a/dll/directx/wine/d3d9/texture.c b/dll/directx/wine/d3d9/texture.c index c97fa6b0219..5c30e4cd18a 100644 --- a/dll/directx/wine/d3d9/texture.c +++ b/dll/directx/wine/d3d9/texture.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -1301,6 +1300,12 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, DWORD flags = 0; HRESULT hr; + if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended) + { + WARN("Managed resources are not supported by d3d9ex devices.\n"); + return D3DERR_INVALIDCALL; + } + texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); @@ -1311,22 +1316,23 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = wined3dusage_from_d3dusage(usage); - desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE; + desc.access = wined3daccess_from_d3dpool(pool, usage); desc.width = width; desc.height = height; desc.depth = 1; desc.size = 0; - if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; - if (is_gdi_compat_wined3dformat(desc.format)) flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (usage & D3DUSAGE_WRITEONLY) + { + WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (usage & D3DUSAGE_AUTOGENMIPMAP) { if (pool == D3DPOOL_SYSTEMMEM) @@ -1339,9 +1345,23 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels); return D3DERR_INVALIDCALL; } - flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + wined3d_mutex_lock(); + hr = wined3d_check_device_format(device->d3d_parent->wined3d, WINED3DADAPTER_DEFAULT, + WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_QUERY_GENMIPMAP, + WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format)); + wined3d_mutex_unlock(); + if (hr == D3D_OK) + { + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + levels = 0; + } + else + { + WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture " + "with a single level.\n", format); + levels = 1; + } texture->autogen_filter_type = D3DTEXF_LINEAR; - levels = 0; } else { @@ -1373,6 +1393,12 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic DWORD flags = 0; HRESULT hr; + if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended) + { + WARN("Managed resources are not supported by d3d9ex devices.\n"); + return D3DERR_INVALIDCALL; + } + texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); @@ -1383,22 +1409,24 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = wined3dusage_from_d3dusage(usage); - desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; + desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; - desc.access = wined3daccess_from_d3dpool(pool, usage) - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE; + desc.access = wined3daccess_from_d3dpool(pool, usage); desc.width = edge_length; desc.height = edge_length; desc.depth = 1; desc.size = 0; - if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; - if (is_gdi_compat_wined3dformat(desc.format)) flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (usage & D3DUSAGE_WRITEONLY) + { + WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (usage & D3DUSAGE_AUTOGENMIPMAP) { if (pool == D3DPOOL_SYSTEMMEM) @@ -1444,6 +1472,16 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev struct wined3d_resource_desc desc; HRESULT hr; + if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended) + { + WARN("Managed resources are not supported by d3d9ex devices.\n"); + return D3DERR_INVALIDCALL; + } + + /* In d3d9, 3D textures can't be used as rendertarget or depth/stencil buffer. */ + if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + return D3DERR_INVALIDCALL; + texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); @@ -1454,15 +1492,20 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = wined3dusage_from_d3dusage(usage); - desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; + desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE; desc.access = wined3daccess_from_d3dpool(pool, usage); desc.width = width; desc.height = height; desc.depth = depth; desc.size = 0; + if (usage & D3DUSAGE_WRITEONLY) + { + WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } if (usage & D3DUSAGE_AUTOGENMIPMAP) { WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n"); diff --git a/dll/directx/wine/d3d9/vertexdeclaration.c b/dll/directx/wine/d3d9/vertexdeclaration.c index 5075309638f..c30a84313fb 100644 --- a/dll/directx/wine/d3d9/vertexdeclaration.c +++ b/dll/directx/wine/d3d9/vertexdeclaration.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -320,7 +319,7 @@ static const struct wined3d_parent_ops d3d9_vertexdeclaration_wined3d_parent_ops }; static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elements, - struct wined3d_vertex_element **wined3d_elements, UINT *element_count) + struct wined3d_vertex_element **wined3d_elements, UINT *element_count, DWORD *stream_map) { const D3DVERTEXELEMENT9* element; UINT count = 1; @@ -328,6 +327,8 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elem TRACE("d3d9_elements %p, wined3d_elements %p, element_count %p\n", d3d9_elements, wined3d_elements, element_count); + *stream_map = 0; + element = d3d9_elements; while (element++->Stream != 0xff && count++ < 128); @@ -359,6 +360,7 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elem (*wined3d_elements)[i].method = d3d9_elements[i].Method; (*wined3d_elements)[i].usage = d3d9_elements[i].Usage; (*wined3d_elements)[i].usage_idx = d3d9_elements[i].UsageIndex; + *stream_map |= 1u << d3d9_elements[i].Stream; } *element_count = count; @@ -374,7 +376,8 @@ static HRESULT vertexdeclaration_init(struct d3d9_vertex_declaration *declaratio UINT element_count; HRESULT hr; - hr = convert_to_wined3d_declaration(elements, &wined3d_elements, &wined3d_element_count); + hr = convert_to_wined3d_declaration(elements, &wined3d_elements, &wined3d_element_count, + &declaration->stream_map); if (FAILED(hr)) { WARN("Failed to create wined3d vertex declaration elements, hr %#x.\n", hr); diff --git a/dll/directx/wine/d3d9/volume.c b/dll/directx/wine/d3d9/volume.c index f4c43bc589a..39caa8fb08e 100644 --- a/dll/directx/wine/d3d9/volume.c +++ b/dll/directx/wine/d3d9/volume.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); @@ -126,7 +125,7 @@ static HRESULT WINAPI d3d9_volume_GetDesc(IDirect3DVolume9 *iface, D3DVOLUME_DES desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_VOLUME; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags); desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Width = wined3d_desc.width; desc->Height = wined3d_desc.height; @@ -148,7 +147,7 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface, wined3d_mutex_lock(); if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, - wined3dmapflags_from_d3dmapflags(flags)))) + wined3dmapflags_from_d3dmapflags(flags, 0)))) map_desc.data = NULL; wined3d_mutex_unlock(); diff --git a/dll/directx/wine/ddraw/clipper.c b/dll/directx/wine/ddraw/clipper.c index 01cac40ec6e..760b22d303b 100644 --- a/dll/directx/wine/ddraw/clipper.c +++ b/dll/directx/wine/ddraw/clipper.c @@ -19,24 +19,47 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl; + static inline struct ddraw_clipper *impl_from_IDirectDrawClipper(IDirectDrawClipper *iface) { return CONTAINING_RECORD(iface, struct ddraw_clipper, IDirectDrawClipper_iface); } +BOOL ddraw_clipper_is_valid(const struct ddraw_clipper *clipper) +{ + /* Native is very lenient when you invoke the clipper methods with a clipper pointer that + * points to something that is either not accessible or not a clipper, or if you break + * a clipper after assigning it to a surface. Deus Ex: Goty depends on this. */ + + if (IsBadReadPtr(clipper, sizeof(*clipper))) + { + WARN("The application gave us an invalid clipper pointer %p.\n", clipper); + return FALSE; + } + if (clipper->IDirectDrawClipper_iface.lpVtbl != &ddraw_clipper_vtbl) + { + WARN("The clipper vtable is modified: %p, expected %p.\n", + clipper->IDirectDrawClipper_iface.lpVtbl, &ddraw_clipper_vtbl); + return FALSE; + } + + return TRUE; +} + static HRESULT WINAPI ddraw_clipper_QueryInterface(IDirectDrawClipper *iface, REFIID iid, void **object) { struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface); TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + if (IsEqualGUID(&IID_IDirectDrawClipper, iid) || IsEqualGUID(&IID_IUnknown, iid)) { @@ -54,17 +77,31 @@ static HRESULT WINAPI ddraw_clipper_QueryInterface(IDirectDrawClipper *iface, RE static ULONG WINAPI ddraw_clipper_AddRef(IDirectDrawClipper *iface) { struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface); - ULONG refcount = InterlockedIncrement(&clipper->ref); + ULONG refcount; - TRACE("%p increasing refcount to %u.\n", clipper, refcount); + if (!ddraw_clipper_is_valid(clipper)) + { + WARN("Invalid clipper, returning 0.\n"); + return 0; + } + refcount = InterlockedIncrement(&clipper->ref); + TRACE("%p increasing refcount to %u.\n", clipper, refcount); return refcount; } static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface) { struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface); - ULONG refcount = InterlockedDecrement(&clipper->ref); + ULONG refcount; + + if (!ddraw_clipper_is_valid(clipper)) + { + WARN("Invalid clipper, returning 0.\n"); + return 0; + } + + refcount = InterlockedDecrement(&clipper->ref); TRACE("%p decreasing refcount to %u.\n", clipper, refcount); @@ -72,6 +109,7 @@ static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface) { if (clipper->region) DeleteObject(clipper->region); + clipper->IDirectDrawClipper_iface.lpVtbl = NULL; /* Should help with detecting freed clippers. */ heap_free(clipper); } @@ -84,6 +122,9 @@ static HRESULT WINAPI ddraw_clipper_SetHWnd(IDirectDrawClipper *iface, DWORD fla TRACE("iface %p, flags %#x, window %p.\n", iface, flags, window); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + if (flags) { FIXME("flags %#x, not supported.\n", flags); @@ -161,6 +202,9 @@ static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n", iface, wine_dbgstr_rect(rect), clip_list, clip_list_size); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); if (clipper->window) @@ -238,6 +282,9 @@ static HRESULT WINAPI ddraw_clipper_SetClipList(IDirectDrawClipper *iface, RGNDA TRACE("iface %p, region %p, flags %#x.\n", iface, region, flags); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); if (clipper->window) @@ -268,6 +315,9 @@ static HRESULT WINAPI ddraw_clipper_GetHWnd(IDirectDrawClipper *iface, HWND *win TRACE("iface %p, window %p.\n", iface, window); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); *window = clipper->window; wined3d_mutex_unlock(); @@ -282,6 +332,9 @@ static HRESULT WINAPI ddraw_clipper_Initialize(IDirectDrawClipper *iface, TRACE("iface %p, ddraw %p, flags %#x.\n", iface, ddraw, flags); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); if (clipper->initialized) { @@ -297,8 +350,13 @@ static HRESULT WINAPI ddraw_clipper_Initialize(IDirectDrawClipper *iface, static HRESULT WINAPI ddraw_clipper_IsClipListChanged(IDirectDrawClipper *iface, BOOL *changed) { + struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface); + FIXME("iface %p, changed %p stub!\n", iface, changed); + if (!ddraw_clipper_is_valid(clipper)) + return DDERR_INVALIDPARAMS; + /* XXX What is safest? */ *changed = FALSE; diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c index e5acf2caff5..38848f207a5 100644 --- a/dll/directx/wine/ddraw/ddraw.c +++ b/dll/directx/wine/ddraw/ddraw.c @@ -21,10 +21,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" +#include "ddrawi.h" +#include "d3dhal.h" #include "wine/exception.h" @@ -45,37 +44,80 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier = 0 }; +#define D3D_VERSION(x) (1 << (x)) + static struct enum_device_entry { - char interface_name[100]; + unsigned int version_mask; + /* Some games (Motoracer 2 demo) have the bad idea to modify the device + * name/description strings. Let's put the strings in sufficiently sized + * arrays in static-lifetime writable memory. */ + char device_desc[100]; char device_name[100]; const GUID *device_guid; DWORD remove_caps; -} device_list7[] = +} device_list[] = { - /* T&L HAL device */ + /* Ramp Emulation (D3D 1&2 only) */ { - "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", - "Wine D3D7 T&L HAL", - &IID_IDirect3DTnLHalDevice, + D3D_VERSION(1)|D3D_VERSION(2), + "WineD3D Ramp Software Emulation", + "Ramp Emulation", + &IID_IDirect3DRampDevice, 0, }, - /* HAL device */ + /* RGB Emulation (D3D 1-7) */ + { + D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7), + "WineD3D RGB Software Emulation", + "RGB Emulation", + &IID_IDirect3DRGBDevice, + D3DDEVCAPS_HWTRANSFORMANDLIGHT, + }, + + /* Direct3D HAL (D3D 1-7) */ { - "WINE Direct3D7 Hardware acceleration using WineD3D", + D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7), + "WineD3D Hardware Acceleration", "Direct3D HAL", &IID_IDirect3DHALDevice, 0, }, - /* RGB device */ + /* MMX Emulation (D3D2 only) */ { - "WINE Direct3D7 RGB Software Emulation using WineD3D", - "Wine D3D7 RGB", - &IID_IDirect3DRGBDevice, - D3DDEVCAPS_HWTRANSFORMANDLIGHT, + D3D_VERSION(2), + "WineD3D MMX Software Emulation", + "MMX Emulation", + &IID_IDirect3DMMXDevice, + 0, }, + + /* Direct3D T&L HAL (D3D7 only) */ + { + D3D_VERSION(7), + "WineD3D Hardware Transform and Lighting Acceleration", + "Direct3D T&L HAL", + &IID_IDirect3DTnLHalDevice, + 0, + }, + + /* In the future, we may wish to add the "Reference Rasterizer" and + * "Null device", which are only available in DX6-8 and must be explicitly + * enabled by the registry values: + * * EnumReference + * * EnumNullDevice, + * which are DWORD values which must be created under + * HKLM\Software\Microsoft\Direct3D\Drivers and set to any nonzero value. + * (Refer to enablerefrast.reg/disablerefrast.reg in the DX6/7 SDKs and + * KB249579 for more information.) + * + * DirectX 9.0 and higher appear to no longer recognize these settings, + * so apparently these devices were removed starting with DX9. + * + * Some games (AvP, Motoracer 2) break if these devices are enumerated. + */ }; static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {} @@ -367,44 +409,32 @@ static ULONG WINAPI d3d1_AddRef(IDirect3D *iface) static void ddraw_destroy_swapchain(struct ddraw *ddraw) { + unsigned int i; + TRACE("Destroying the swapchain.\n"); wined3d_swapchain_decref(ddraw->wined3d_swapchain); - ddraw->wined3d_swapchain = NULL; - if (!(ddraw->flags & DDRAW_NO3D)) + for (i = 0; i < ddraw->numConvertedDecls; ++i) { - UINT i; - - for (i = 0; i < ddraw->numConvertedDecls; ++i) - { - wined3d_vertex_declaration_decref(ddraw->decls[i].decl); - } - heap_free(ddraw->decls); - ddraw->numConvertedDecls = 0; + wined3d_vertex_declaration_decref(ddraw->decls[i].decl); + } + heap_free(ddraw->decls); + ddraw->numConvertedDecls = 0; - if (FAILED(wined3d_device_uninit_3d(ddraw->wined3d_device))) - { - ERR("Failed to uninit 3D.\n"); - } - else - { - /* Free the d3d window if one was created. */ - if (ddraw->d3d_window && ddraw->d3d_window != ddraw->dest_window) - { - TRACE("Destroying the hidden render window %p.\n", ddraw->d3d_window); - DestroyWindow(ddraw->d3d_window); - ddraw->d3d_window = 0; - } - } + wined3d_swapchain_decref(ddraw->wined3d_swapchain); + ddraw->wined3d_swapchain = NULL; - ddraw->flags &= ~DDRAW_D3D_INITIALIZED; - } - else + /* Free the d3d window if one was created. */ + if (ddraw->d3d_window && ddraw->d3d_window != ddraw->dest_window) { - wined3d_device_uninit_gdi(ddraw->wined3d_device); + TRACE("Destroying the hidden render window %p.\n", ddraw->d3d_window); + DestroyWindow(ddraw->d3d_window); + ddraw->d3d_window = 0; } + ddraw->flags &= ~DDRAW_D3D_INITIALIZED; + ddraw_set_swapchain_window(ddraw, NULL); TRACE("Swapchain destroyed.\n"); @@ -563,14 +593,36 @@ static HRESULT ddraw_set_focus_window(struct ddraw *ddraw, HWND window) return DD_OK; } -static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, - struct wined3d_swapchain_desc *swapchain_desc) +static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, HWND window, + BOOL windowed, struct wined3d_swapchain **wined3d_swapchain) { - HWND window = swapchain_desc->device_window; + struct wined3d_swapchain_desc swapchain_desc; + struct wined3d_display_mode mode; HRESULT hr; TRACE("ddraw %p.\n", ddraw); + if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) + { + ERR("Failed to get display mode.\n"); + return hr; + } + + memset(&swapchain_desc, 0, sizeof(swapchain_desc)); + swapchain_desc.backbuffer_width = mode.width; + swapchain_desc.backbuffer_height = mode.height; + swapchain_desc.backbuffer_format = mode.format_id; + swapchain_desc.backbuffer_bind_flags = 0; + swapchain_desc.backbuffer_count = 1; + swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; + swapchain_desc.device_window = window; + swapchain_desc.windowed = windowed; + swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH | WINED3D_SWAPCHAIN_IMPLICIT; + + if (ddraw->flags & DDRAW_NO3D) + return wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc, + NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain); + if (!window || window == GetDesktopWindow()) { window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "Hidden D3D Window", @@ -585,7 +637,7 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, ShowWindow(window, SW_HIDE); /* Just to be sure */ WARN("No window for the Direct3DDevice, created hidden window %p.\n", window); - swapchain_desc->device_window = window; + swapchain_desc.device_window = window; } else { @@ -596,10 +648,12 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, /* Set this NOW, otherwise creating the depth stencil surface will cause a * recursive loop until ram or emulated video memory is full. */ ddraw->flags |= DDRAW_D3D_INITIALIZED; - hr = wined3d_device_init_3d(ddraw->wined3d_device, swapchain_desc); - if (FAILED(hr)) + if (FAILED(hr = wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc, + NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain))) { ddraw->flags &= ~DDRAW_D3D_INITIALIZED; + DestroyWindow(window); + ddraw->d3d_window = NULL; return hr; } @@ -608,7 +662,9 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, { ERR("Error allocating an array for the converted vertex decls.\n"); ddraw->declArraySize = 0; - hr = wined3d_device_uninit_3d(ddraw->wined3d_device); + wined3d_swapchain_decref(*wined3d_swapchain); + DestroyWindow(window); + ddraw->d3d_window = NULL; return E_OUTOFMEMORY; } @@ -619,44 +675,21 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL windowed) { - struct wined3d_swapchain_desc swapchain_desc; - struct wined3d_display_mode mode; - HRESULT hr = WINED3D_OK; + HRESULT hr; - if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) + if (ddraw->wined3d_swapchain) { - ERR("Failed to get display mode.\n"); - return hr; + ERR("Swapchain already created.\n"); + return E_FAIL; } - memset(&swapchain_desc, 0, sizeof(swapchain_desc)); - swapchain_desc.backbuffer_width = mode.width; - swapchain_desc.backbuffer_height = mode.height; - swapchain_desc.backbuffer_format = mode.format_id; - swapchain_desc.backbuffer_usage = WINED3DUSAGE_RENDERTARGET; - swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; - swapchain_desc.device_window = window; - swapchain_desc.windowed = windowed; - swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; - - if (!(ddraw->flags & DDRAW_NO3D)) - hr = ddraw_attach_d3d_device(ddraw, &swapchain_desc); - else - hr = wined3d_device_init_gdi(ddraw->wined3d_device, &swapchain_desc); - - if (FAILED(hr)) + if (FAILED(hr = ddraw_attach_d3d_device(ddraw, window, windowed, &ddraw->wined3d_swapchain))) { ERR("Failed to create swapchain, hr %#x.\n", hr); return hr; } - - if (!(ddraw->wined3d_swapchain = wined3d_device_get_swapchain(ddraw->wined3d_device, 0))) - { - ERR("Failed to get swapchain.\n"); - return DDERR_INVALIDPARAMS; - } - wined3d_swapchain_incref(ddraw->wined3d_swapchain); + ddraw_set_swapchain_window(ddraw, window); if (ddraw->primary && ddraw->primary->palette) @@ -898,21 +931,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ddraw->focuswindow = NULL; } - if ((cooplevel & DDSCL_FULLSCREEN) != (ddraw->cooperative_level & DDSCL_FULLSCREEN) || window != ddraw->dest_window) - { - if (ddraw->cooperative_level & DDSCL_FULLSCREEN) - wined3d_device_restore_fullscreen_window(ddraw->wined3d_device, ddraw->dest_window, NULL); - - if (cooplevel & DDSCL_FULLSCREEN) - { - struct wined3d_display_mode display_mode; - - wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &display_mode, NULL); - wined3d_device_setup_fullscreen_window(ddraw->wined3d_device, window, - display_mode.width, display_mode.height); - } - } - if ((cooplevel & DDSCL_EXCLUSIVE) && exclusive_window != window) { ddraw->device_state = DDRAW_DEVICE_STATE_NOT_RESTORED; @@ -934,7 +952,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, goto done; } - wined3d_stateblock_capture(stateblock); rtv = wined3d_device_get_rendertarget_view(ddraw->wined3d_device, 0); /* Rendering to ddraw->wined3d_frontbuffer. */ if (rtv && !wined3d_rendertarget_view_get_sub_resource_parent(rtv)) @@ -1132,6 +1149,7 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW /* TODO: The possible return values from msdn suggest that the screen mode * can't be changed if a surface is locked or some drawing is in progress. */ + if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode))) { if (ddraw->primary) @@ -1145,6 +1163,10 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW ddrawformat_from_wined3dformat(&ddraw->primary->surface_desc.u4.ddpfPixelFormat, mode.format_id); } ddraw->flags |= DDRAW_RESTORE_MODE; + + if (ddraw->cooperative_level & DDSCL_EXCLUSIVE) + SetWindowPos(ddraw->dest_window, HWND_TOP, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOACTIVATE); + TRACE("DirectDraw window has been resized\n"); } InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_OK); @@ -1247,7 +1269,7 @@ void ddraw_d3dcaps1_from_7(D3DDEVICEDESC *caps1, D3DDEVICEDESC7 *caps7) HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) { - WINED3DCAPS wined3d_caps; + struct wined3d_caps wined3d_caps; HRESULT hr; TRACE("ddraw %p, caps %p.\n", ddraw, caps); @@ -1338,10 +1360,13 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_SUBPIXELX | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT | D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT | - D3DPRASTERCAPS_ANTIALIASEDGES | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | + D3DPRASTERCAPS_ANTIALIASEDGES | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT | D3DPRASTERCAPS_WFOG | - D3DPRASTERCAPS_ZFOG); + D3DPRASTERCAPS_ZFOG | WINED3DPRASTERCAPS_DEPTHBIAS); + if (caps->dpcLineCaps.dwRasterCaps & WINED3DPRASTERCAPS_DEPTHBIAS) + caps->dpcLineCaps.dwRasterCaps = (caps->dpcLineCaps.dwRasterCaps | D3DPRASTERCAPS_ZBIAS) + & ~WINED3DPRASTERCAPS_DEPTHBIAS; caps->dpcLineCaps.dwZCmpCaps &= ( D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | @@ -1394,15 +1419,6 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV); - if (!(caps->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2)) - { - /* DirectX7 always has the np2 flag set, no matter what the card - * supports. Some old games (Rollcage) check the caps incorrectly. - * If wined3d supports nonpow2 textures it also has np2 conditional - * support. */ - caps->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL; - } - /* Fill the missing members, and do some fixup */ caps->dpcLineCaps.dwSize = sizeof(caps->dpcLineCaps); caps->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD @@ -1479,10 +1495,10 @@ HRESULT CALLBACK enum_zbuffer(DDPIXELFORMAT *format, void *ctx) static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DDCAPS *HELCaps) { struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + DDSCAPS2 ddscaps = {0, 0, 0, {0}}; + struct wined3d_caps winecaps; DDCAPS caps; - WINED3DCAPS winecaps; HRESULT hr; - DDSCAPS2 ddscaps = {0, 0, 0, {0}}; TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, DriverCaps, HELCaps); @@ -1675,11 +1691,10 @@ static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2 memset(DDSD, 0, DDSD->dwSize); DDSD->dwSize = sizeof(*DDSD); - DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; + DDSD->dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; DDSD->dwWidth = mode.width; DDSD->dwHeight = mode.height; DDSD->u2.dwRefreshRate = 60; - DDSD->ddsCaps.dwCaps = 0; DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat); ddrawformat_from_wined3dformat(&DDSD->u4.ddpfPixelFormat, mode.format_id); DDSD->u1.lPitch = mode.width * DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount / 8; @@ -1771,7 +1786,7 @@ static HRESULT WINAPI ddraw7_GetFourCCCodes(IDirectDraw7 *iface, DWORD *NumCodes for (i = 0; i < ARRAY_SIZE(formats); ++i) { if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, formats[i]))) + mode.format_id, 0, 0, WINED3D_RTYPE_TEXTURE_2D, formats[i]))) { if (count < outsize) Codes[count] = formats[i]; @@ -2295,21 +2310,24 @@ static HRESULT WINAPI ddraw4_TestCooperativeLevel(IDirectDraw4 *iface) * DDERR_NOTFOUND if the GDI surface wasn't found * *****************************************************************************/ -static HRESULT WINAPI ddraw7_GetGDISurface(IDirectDraw7 *iface, IDirectDrawSurface7 **GDISurface) +static HRESULT WINAPI ddraw7_GetGDISurface(IDirectDraw7 *iface, IDirectDrawSurface7 **surface) { struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + struct ddraw_surface *ddraw_surface; - TRACE("iface %p, surface %p.\n", iface, GDISurface); + TRACE("iface %p, surface %p.\n", iface, surface); wined3d_mutex_lock(); - if (!(*GDISurface = &ddraw->primary->IDirectDrawSurface7_iface)) + if (!ddraw->gdi_surface || !(ddraw_surface = wined3d_texture_get_sub_resource_parent(ddraw->gdi_surface, 0))) { - WARN("Primary not created yet.\n"); + WARN("GDI surface not available.\n"); + *surface = NULL; wined3d_mutex_unlock(); return DDERR_NOTFOUND; } - IDirectDrawSurface7_AddRef(*GDISurface); + *surface = &ddraw_surface->IDirectDrawSurface7_iface; + IDirectDrawSurface7_AddRef(*surface); wined3d_mutex_unlock(); @@ -3716,8 +3734,7 @@ static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface, IDirectDrawSur /***************************************************************************** * IDirect3D7::EnumDevices * - * The EnumDevices method for IDirect3D7. It enumerates all supported - * D3D7 devices. Currently the T&L, HAL and RGB devices are enumerated. + * The EnumDevices method for IDirect3D7. It enumerates all D3D7 devices. * * Params: * callback: Function to call for each enumerated device @@ -3750,14 +3767,17 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA dev_caps = device_desc7.dwDevCaps; - for (i = 0; i < ARRAY_SIZE(device_list7); i++) + for (i = 0; i < ARRAY_SIZE(device_list); i++) { HRESULT ret; - device_desc7.deviceGUID = *device_list7[i].device_guid; - device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; + if (!(device_list[i].version_mask & D3D_VERSION(ddraw->d3dversion))) + continue; + + device_desc7.deviceGUID = *device_list[i].device_guid; + device_desc7.dwDevCaps = dev_caps & ~device_list[i].remove_caps; - ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); + ret = callback(device_list[i].device_name, device_list[i].device_name, &device_desc7, context); if (ret != DDENUMRET_OK) { TRACE("Application cancelled the enumeration.\n"); @@ -3773,11 +3793,21 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA return D3D_OK; } +static void clear_device_desc(D3DDEVICEDESC *device_desc) +{ + memset(device_desc, 0, sizeof(*device_desc)); + device_desc->dwSize = sizeof(*device_desc); + device_desc->dtcTransformCaps.dwSize = sizeof(device_desc->dtcTransformCaps); + device_desc->dlcLightingCaps.dwSize = sizeof(device_desc->dlcLightingCaps); + device_desc->dpcLineCaps.dwSize = sizeof(device_desc->dpcLineCaps); + device_desc->dpcTriCaps.dwSize = sizeof(device_desc->dpcTriCaps); +} + /***************************************************************************** * IDirect3D3::EnumDevices * - * Enumerates all supported Direct3DDevice interfaces. This is the - * implementation for Direct3D 1 to Direc3D 3, Version 7 has its own. + * Enumerates all Direct3DDevice interfaces. This is the implementation for + * Direct3D 1 to Direct3D 3; Version 7 has its own. * * Versions 1, 2 and 3 * @@ -3792,18 +3822,18 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA *****************************************************************************/ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBACK callback, void *context) { - static CHAR wined3d_description[] = "Wine D3DDevice using WineD3D and OpenGL"; - +/* Size of D3DDEVICEDESC in Direct3D 1-3 */ +enum { + D3D1_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth), /* 172 */ + D3D2_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat), /* 204 */ + D3D3_DESC_SIZE = sizeof(D3DDEVICEDESC) /* 252 */ +}; struct ddraw *ddraw = impl_from_IDirect3D3(iface); - D3DDEVICEDESC device_desc1, hal_desc, hel_desc; + DWORD desc_size; + D3DDEVICEDESC device_desc1, empty_desc1, hal_desc, hel_desc; D3DDEVICEDESC7 device_desc7; HRESULT hr; - - /* Some games (Motoracer 2 demo) have the bad idea to modify the device - * name string. Let's put the string in a sufficiently sized array in - * writable memory. */ - char device_name[50]; - strcpy(device_name,"Direct3D HEL"); + size_t i; TRACE("iface %p, callback %p, context %p.\n", iface, callback, context); @@ -3812,52 +3842,58 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA wined3d_mutex_lock(); + switch (ddraw->d3dversion) + { + case 1: desc_size = D3D1_DESC_SIZE; break; + case 2: desc_size = D3D2_DESC_SIZE; break; + default: desc_size = D3D3_DESC_SIZE; break; + } + if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &device_desc7))) { wined3d_mutex_unlock(); return hr; } + ddraw_d3dcaps1_from_7(&device_desc1, &device_desc7); + device_desc1.dwSize = desc_size; - /* Do I have to enumerate the reference id? Note from old d3d7: - * "It seems that enumerating the reference IID on Direct3D 1 games - * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1 - * - * There's a registry key HKLM\Software\Microsoft\Direct3D\Drivers, - * EnumReference which enables / disables enumerating the reference - * rasterizer. It's a DWORD, 0 means disabled, 2 means enabled. The - * enablerefrast.reg and disablerefrast.reg files in the DirectX 7.0 sdk - * demo directory suggest this. - * - * Some games(GTA 2) seem to use the second enumerated device, so I have - * to enumerate at least 2 devices. So enumerate the reference device to - * have 2 devices. - * - * Other games (Rollcage) tell emulation and hal device apart by certain - * flags. Rollcage expects D3DPTEXTURECAPS_POW2 to be set (yeah, it is a - * limitation flag), and it refuses all devices that have the perspective - * flag set. This way it refuses the emulation device, and HAL devices - * never have POW2 unset in d3d7 on windows. */ - if (ddraw->d3dversion != 1) - { - static CHAR reference_description[] = "RGB Direct3D emulation"; - - TRACE("Enumerating WineD3D D3DDevice interface.\n"); - hal_desc = device_desc1; - hel_desc = device_desc1; - /* The rgb device has the pow2 flag set in the hel caps, but not in the hal caps. */ - hal_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 - | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); - hal_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 - | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); - /* RGB, RAMP and MMX devices have a HAL dcmColorModel of 0 */ - hal_desc.dcmColorModel = 0; - /* RGB, RAMP and MMX devices cannot report HAL hardware flags */ - hal_desc.dwFlags = 0; - - hr = callback((GUID *)&IID_IDirect3DRGBDevice, reference_description, - device_name, &hal_desc, &hel_desc, context); - if (hr != D3DENUMRET_OK) + clear_device_desc(&empty_desc1); + empty_desc1.dwSize = desc_size; + + for (i = 0; i < ARRAY_SIZE(device_list); i++) + { + if (!(device_list[i].version_mask & D3D_VERSION(ddraw->d3dversion))) + continue; + + if (IsEqualGUID(&IID_IDirect3DHALDevice, device_list[i].device_guid)) + { + hal_desc = device_desc1; + + /* The HAL device's hel_desc is almost empty -- but not completely */ + hel_desc = empty_desc1; + hel_desc.dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS + | D3DDD_LIGHTINGCAPS | D3DDD_BCLIPPING; + hel_desc.dcmColorModel = 0; + hel_desc.dwDevCaps = D3DDEVCAPS_FLOATTLVERTEX; + hel_desc.dtcTransformCaps.dwCaps = hal_desc.dtcTransformCaps.dwCaps; + hel_desc.dlcLightingCaps = hal_desc.dlcLightingCaps; + hel_desc.bClipping = hal_desc.bClipping; + hel_desc.dwMaxVertexCount = hal_desc.dwMaxVertexCount; + } + else + { + hal_desc = empty_desc1; + + hel_desc = device_desc1; + /* Ramp device supports grayscale only */ + if (IsEqualGUID(&IID_IDirect3DRampDevice, device_list[i].device_guid)) + hel_desc.dcmColorModel = D3DCOLOR_MONO; + } + + hr = callback((GUID *)device_list[i].device_guid, device_list[i].device_desc, + device_list[i].device_name, &hal_desc, &hel_desc, context); + if (hr != DDENUMRET_OK) { TRACE("Application cancelled the enumeration.\n"); wined3d_mutex_unlock(); @@ -3865,29 +3901,6 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA } } - strcpy(device_name,"Direct3D HAL"); - - TRACE("Enumerating HAL Direct3D device.\n"); - hal_desc = device_desc1; - hel_desc = device_desc1; - - /* The hal device does not have the pow2 flag set in hel, but in hal. */ - hel_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 - | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); - hel_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 - | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); - /* HAL devices have a HEL dcmColorModel of 0 */ - hel_desc.dcmColorModel = 0; - - hr = callback((GUID *)&IID_IDirect3DHALDevice, wined3d_description, - device_name, &hal_desc, &hel_desc, context); - if (hr != D3DENUMRET_OK) - { - TRACE("Application cancelled the enumeration.\n"); - wined3d_mutex_unlock(); - return D3D_OK; - } - TRACE("End of enumeration.\n"); wined3d_mutex_unlock(); @@ -4126,52 +4139,73 @@ static HRESULT WINAPI d3d1_CreateViewport(IDirect3D *iface, IDirect3DViewport ** outer_unknown); } -/***************************************************************************** - * IDirect3D3::FindDevice - * - * This method finds a device with the requested properties and returns a - * device description - * - * Versions 1, 2 and 3 - * Params: - * fds: Describes the requested device characteristics - * fdr: Returns the device description - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if no device was found - * - *****************************************************************************/ -static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr) +static HRESULT ddraw_find_device(struct ddraw *ddraw, const D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr, + unsigned int guid_count, const GUID * const *guids, DWORD device_desc_size) { - struct ddraw *ddraw = impl_from_IDirect3D3(iface); + struct ddraw_find_device_result_v1 + { + DWORD size; + GUID guid; + D3DDEVICEDESC_V1 hw_desc; + D3DDEVICEDESC_V1 sw_desc; + } *fdr1; + struct ddraw_find_device_result_v2 + { + DWORD size; + GUID guid; + D3DDEVICEDESC_V2 hw_desc; + D3DDEVICEDESC_V2 sw_desc; + } *fdr2; D3DDEVICEDESC7 desc7; D3DDEVICEDESC desc1; + unsigned int i; HRESULT hr; - TRACE("iface %p, fds %p, fdr %p.\n", iface, fds, fdr); + TRACE("ddraw %p, fds %p, fdr %p, guid_count %u, guids %p, device_desc_size %u.\n", + ddraw, fds, fdr, guid_count, guids, device_desc_size); - if (!fds || !fdr) return DDERR_INVALIDPARAMS; + if (!fds || !fdr) + return DDERR_INVALIDPARAMS; - if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) || (fdr->dwSize != sizeof(D3DFINDDEVICERESULT1) && - fdr->dwSize != sizeof(D3DFINDDEVICERESULT2) && fdr->dwSize != sizeof(D3DFINDDEVICERESULT))) + if (fds->dwSize != sizeof(*fds)) + { + WARN("Got invalid search structure size %u.\n", fds->dwSize); return DDERR_INVALIDPARAMS; + } - if ((fds->dwFlags & D3DFDS_COLORMODEL) - && fds->dcmColorModel != D3DCOLOR_RGB) + if (fdr->dwSize != sizeof(*fdr) && fdr->dwSize != sizeof(*fdr2) && fdr->dwSize != sizeof(*fdr1)) { - WARN("Trying to request a non-RGB D3D color model. Not supported.\n"); - return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */ + WARN("Got invalid result structure size %u.\n", fdr->dwSize); + return DDERR_INVALIDPARAMS; } + if (fds->dwFlags & D3DFDS_COLORMODEL) + WARN("Ignoring colour model %#x.\n", fds->dcmColorModel); + if (fds->dwFlags & D3DFDS_GUID) { - TRACE("Trying to match guid %s.\n", debugstr_guid(&(fds->guid))); - if (!IsEqualGUID(&IID_D3DDEVICE_WineD3D, &fds->guid) - && !IsEqualGUID(&IID_IDirect3DHALDevice, &fds->guid) - && !IsEqualGUID(&IID_IDirect3DRGBDevice, &fds->guid)) + BOOL found = FALSE; + + TRACE("Trying to match GUID %s.\n", debugstr_guid(&fds->guid)); + + if ((ddraw->flags & DDRAW_NO3D) && IsEqualGUID(&fds->guid, &IID_IDirect3DHALDevice)) { - WARN("No match for this GUID.\n"); + WARN("HAL device not available without 3D support.\n"); + return DDERR_NOTFOUND; + } + + for (i = 0; i < guid_count; ++i) + { + if (IsEqualGUID(guids[i], &fds->guid)) + { + found = TRUE; + break; + } + } + + if (!found) + { + WARN("Failed to match GUID %s.\n", debugstr_guid(&fds->guid)); return DDERR_NOTFOUND; } } @@ -4207,22 +4241,52 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd return D3D_OK; } +static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr) +{ + struct ddraw *ddraw = impl_from_IDirect3D3(iface); + static const GUID * const guids[] = + { + &IID_D3DDEVICE_WineD3D, + &IID_IDirect3DHALDevice, + &IID_IDirect3DRGBDevice, + }; + + TRACE("iface %p, fds %p, fdr %p.\n", iface, fds, fdr); + + return ddraw_find_device(ddraw, fds, fdr, ARRAY_SIZE(guids), guids, sizeof(D3DDEVICEDESC_V3)); +} + static HRESULT WINAPI d3d2_FindDevice(IDirect3D2 *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr) { struct ddraw *ddraw = impl_from_IDirect3D2(iface); + static const GUID * const guids[] = + { + &IID_D3DDEVICE_WineD3D, + &IID_IDirect3DHALDevice, + &IID_IDirect3DMMXDevice, + &IID_IDirect3DRGBDevice, + &IID_IDirect3DRampDevice, + }; TRACE("iface %p, fds %p, fdr %p.\n", iface, fds, fdr); - return d3d3_FindDevice(&ddraw->IDirect3D3_iface, fds, fdr); + return ddraw_find_device(ddraw, fds, fdr, ARRAY_SIZE(guids), guids, sizeof(D3DDEVICEDESC_V2)); } static HRESULT WINAPI d3d1_FindDevice(IDirect3D *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr) { struct ddraw *ddraw = impl_from_IDirect3D(iface); + static const GUID * const guids[] = + { + &IID_D3DDEVICE_WineD3D, + &IID_IDirect3DHALDevice, + &IID_IDirect3DRGBDevice, + &IID_IDirect3DRampDevice, + }; TRACE("iface %p, fds %p, fdr %p.\n", iface, fds, fdr); - return d3d3_FindDevice(&ddraw->IDirect3D3_iface, fds, fdr); + return ddraw_find_device(ddraw, fds, fdr, ARRAY_SIZE(guids), guids, sizeof(D3DDEVICEDESC_V1)); } /***************************************************************************** @@ -4484,8 +4548,8 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, mode.format_id, - WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_TEXTURE_2D, formats[i]))) + if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, + mode.format_id, 0, WINED3D_BIND_DEPTH_STENCIL, WINED3D_RTYPE_TEXTURE_2D, formats[i]))) { DDPIXELFORMAT pformat; @@ -4509,7 +4573,7 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device * pixel format, so we use dwZBufferBitDepth=32. Some games expect 24. Windows Vista and * newer enumerate both versions, so we do the same(bug 22434) */ if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, mode.format_id, - WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_TEXTURE_2D, WINED3DFMT_X8D24_UNORM))) + 0, WINED3D_BIND_DEPTH_STENCIL, WINED3D_RTYPE_TEXTURE_2D, WINED3DFMT_X8D24_UNORM))) { DDPIXELFORMAT x8d24 = { @@ -4925,18 +4989,19 @@ void ddraw_update_lost_surfaces(struct ddraw *ddraw) ddraw->device_state = DDRAW_DEVICE_STATE_OK; } -static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, +static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent, + enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); struct ddraw_surface *ddraw_surface; - TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); + TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", + device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops); /* We have a swapchain or wined3d internal texture. */ - if (!wined3d_texture_get_parent(wined3d_texture) || wined3d_texture_get_parent(wined3d_texture) == ddraw) + if (type != WINED3D_RTYPE_TEXTURE_2D || !wined3d_texture_get_parent(wined3d_texture) + || wined3d_texture_get_parent(wined3d_texture) == ddraw) { *parent = NULL; *parent_ops = &ddraw_null_wined3d_parent_ops; @@ -4961,19 +5026,6 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent return DD_OK; } -static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - void **parent, const struct wined3d_parent_ops **parent_ops) -{ - TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", - device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); - - *parent = NULL; - *parent_ops = &ddraw_null_wined3d_parent_ops; - - return DD_OK; -} - static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent) { struct ddraw *ddraw = parent; @@ -4990,46 +5042,26 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic struct wined3d_texture **texture) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); + const struct wined3d_parent_ops *parent_ops; HRESULT hr; TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", device_parent, container_parent, desc, texture_flags, texture); - if (ddraw->wined3d_frontbuffer) - { - ERR("Frontbuffer already created.\n"); - return E_FAIL; - } + if (!ddraw->wined3d_frontbuffer) + parent_ops = &ddraw_frontbuffer_parent_ops; + else + parent_ops = &ddraw_null_wined3d_parent_ops; if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1, - texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture))) + texture_flags, NULL, ddraw, parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; } - ddraw->wined3d_frontbuffer = *texture; - - return hr; -} - -static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) -{ - struct ddraw *ddraw = ddraw_from_device_parent(device_parent); - HRESULT hr; - - TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); - - if (ddraw->wined3d_swapchain) - { - ERR("Swapchain already created.\n"); - return E_FAIL; - } - - if (FAILED(hr = wined3d_swapchain_create(ddraw->wined3d_device, desc, NULL, - &ddraw_null_wined3d_parent_ops, swapchain))) - WARN("Failed to create swapchain, hr %#x.\n", hr); + if (!ddraw->wined3d_frontbuffer) + ddraw->wined3d_frontbuffer = *texture; return hr; } @@ -5039,17 +5071,22 @@ static const struct wined3d_device_parent_ops ddraw_wined3d_device_parent_ops = device_parent_wined3d_device_created, device_parent_mode_changed, device_parent_activate, - device_parent_surface_created, - device_parent_volume_created, + device_parent_texture_sub_resource_created, device_parent_create_swapchain_texture, - device_parent_create_swapchain, }; HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type device_type) { - WINED3DCAPS caps; + struct wined3d_caps caps; HRESULT hr; + static const enum wined3d_feature_level feature_levels[] = + { + WINED3D_FEATURE_LEVEL_7, + WINED3D_FEATURE_LEVEL_6, + WINED3D_FEATURE_LEVEL_5, + }; + ddraw->IDirectDraw7_iface.lpVtbl = &ddraw7_vtbl; ddraw->IDirectDraw_iface.lpVtbl = &ddraw1_vtbl; ddraw->IDirectDraw2_iface.lpVtbl = &ddraw2_vtbl; @@ -5087,7 +5124,8 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de } if (FAILED(hr = wined3d_device_create(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type, - NULL, 0, DDRAW_STRIDE_ALIGNMENT, &ddraw->device_parent, &ddraw->wined3d_device))) + NULL, 0, DDRAW_STRIDE_ALIGNMENT, feature_levels, ARRAY_SIZE(feature_levels), + &ddraw->device_parent, &ddraw->wined3d_device))) { WARN("Failed to create a wined3d device, hr %#x.\n", hr); wined3d_decref(ddraw->wined3d); diff --git a/dll/directx/wine/ddraw/ddraw_private.h b/dll/directx/wine/ddraw/ddraw_private.h index cac38c57e92..7a983767cef 100644 --- a/dll/directx/wine/ddraw/ddraw_private.h +++ b/dll/directx/wine/ddraw/ddraw_private.h @@ -21,6 +21,7 @@ #include #include +#include #define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION @@ -57,6 +58,7 @@ struct FvfToDecl #define DDRAW_NO3D 0x00000008 #define DDRAW_SCL_DDRAW1 0x00000010 #define DDRAW_SCL_RECURSIVE 0x00000020 +#define DDRAW_SWAPPED 0x00000040 #define DDRAW_GDI_FLIP 0x00000040 #define DDRAW_STRIDE_ALIGNMENT 8 @@ -66,6 +68,8 @@ struct FvfToDecl | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT) +#define DDRAW_MAX_ACTIVE_LIGHTS 32 + enum ddraw_device_state { DDRAW_DEVICE_STATE_OK, @@ -97,6 +101,7 @@ struct ddraw struct ddraw_surface *primary; RECT primary_lock; struct wined3d_texture *wined3d_frontbuffer; + struct wined3d_texture *gdi_surface; struct wined3d_swapchain *wined3d_swapchain; HWND swapchain_window; @@ -218,7 +223,7 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, - const RECT *rect, BOOL read) DECLSPEC_HIDDEN; + const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN; static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface) { @@ -325,6 +330,7 @@ struct d3d_device /* Required to keep track which of two available texture blending modes in d3ddevice3 is used */ BOOL legacyTextureBlending; + D3DTEXTUREBLEND texture_map_blend; D3DMATRIX legacy_projection; D3DMATRIX legacy_clipspace; @@ -346,6 +352,8 @@ struct d3d_device D3DMATRIXHANDLE world, proj, view; struct wined3d_vec4 user_clip_planes[D3DMAXUSERCLIPPLANES]; + + struct wined3d_stateblock *recording; }; HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, @@ -391,6 +399,7 @@ struct ddraw_clipper HRESULT ddraw_clipper_init(struct ddraw_clipper *clipper) DECLSPEC_HIDDEN; struct ddraw_clipper *unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface) DECLSPEC_HIDDEN; +BOOL ddraw_clipper_is_valid(const struct ddraw_clipper *clipper) DECLSPEC_HIDDEN; /***************************************************************************** * IDirectDrawPalette implementation structure @@ -442,7 +451,7 @@ struct d3d_light D3DLIGHT2 light; D3DLIGHT7 light7; - DWORD dwLightIndex; + DWORD active_light_index; struct list entry; }; @@ -475,6 +484,13 @@ struct d3d_material void material_activate(struct d3d_material *material) DECLSPEC_HIDDEN; struct d3d_material *d3d_material_create(struct ddraw *ddraw) DECLSPEC_HIDDEN; +enum ddraw_viewport_version +{ + DDRAW_VIEWPORT_VERSION_NONE, + DDRAW_VIEWPORT_VERSION_1, + DDRAW_VIEWPORT_VERSION_2, +}; + /***************************************************************************** * IDirect3DViewport - Wraps to D3D7 *****************************************************************************/ @@ -489,10 +505,10 @@ struct d3d_viewport /* If this viewport is active for one device, put the device here */ struct d3d_device *active_device; - DWORD num_lights; + DWORD active_lights_count; DWORD map_lights; - int use_vp2; + enum ddraw_viewport_version version; union { @@ -511,6 +527,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface /* Helper functions */ void viewport_activate(struct d3d_viewport *viewport, BOOL ignore_lights) DECLSPEC_HIDDEN; +void viewport_deactivate(struct d3d_viewport *viewport) DECLSPEC_HIDDEN; void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) DECLSPEC_HIDDEN; /***************************************************************************** @@ -544,7 +561,7 @@ struct d3d_execute_buffer *unsafe_impl_from_IDirect3DExecuteBuffer(IDirect3DExec /* The execute function */ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *execute_buffer, - struct d3d_device *device, struct d3d_viewport *viewport) DECLSPEC_HIDDEN; + struct d3d_device *device) DECLSPEC_HIDDEN; /***************************************************************************** * IDirect3DVertexBuffer @@ -648,4 +665,7 @@ struct member_info HRESULT hr_ddraw_from_wined3d(HRESULT hr) DECLSPEC_HIDDEN; +void viewport_alloc_active_light_index(struct d3d_light *light) DECLSPEC_HIDDEN; +void viewport_free_active_light_index(struct d3d_light *light) DECLSPEC_HIDDEN; + #endif diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c index 24dbd3be505..3d38ba6248f 100644 --- a/dll/directx/wine/ddraw/device.c +++ b/dll/directx/wine/ddraw/device.c @@ -27,9 +27,6 @@ * */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -248,6 +245,9 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) wined3d_device_set_rendertarget_view(This->wined3d_device, 0, NULL, FALSE); + if (This->recording) + wined3d_stateblock_decref(This->recording); + /* Release the wined3d device. This won't destroy it. */ if (!wined3d_device_decref(This->wined3d_device)) ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device); @@ -712,9 +712,13 @@ static HRESULT WINAPI d3d_device1_Execute(IDirect3DDevice *iface, if(!buffer) return DDERR_INVALIDPARAMS; + if (FAILED(hr = IDirect3DDevice3_SetCurrentViewport + (&device->IDirect3DDevice3_iface, &viewport_impl->IDirect3DViewport3_iface))) + return hr; + /* Execute... */ wined3d_mutex_lock(); - hr = d3d_execute_buffer_execute(buffer, device, viewport_impl); + hr = d3d_execute_buffer_execute(buffer, device); wined3d_mutex_unlock(); return hr; @@ -819,7 +823,9 @@ static HRESULT WINAPI d3d_device3_DeleteViewport(IDirect3DDevice3 *iface, IDirec if (device->current_viewport == vp) { - TRACE("Deleting current viewport, unsetting and releasing\n"); + TRACE("Deleting current viewport, unsetting and releasing.\n"); + + viewport_deactivate(vp); IDirect3DViewport3_Release(viewport); device->current_viewport = NULL; } @@ -1089,7 +1095,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface, for (i = 0; i < ARRAY_SIZE(FormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) + mode.format_id, 0, WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) { DDPIXELFORMAT pformat; @@ -1111,8 +1117,8 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface, for (i = 0; i < ARRAY_SIZE(BumpFormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_LEGACYBUMPMAP, - WINED3D_RTYPE_TEXTURE_2D, BumpFormatList[i]) == D3D_OK) + WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_QUERY_LEGACYBUMPMAP, + WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, BumpFormatList[i]) == D3D_OK) { DDPIXELFORMAT pformat; @@ -1216,8 +1222,8 @@ static HRESULT WINAPI d3d_device2_EnumTextureFormats(IDirect3DDevice2 *iface, for (i = 0; i < ARRAY_SIZE(FormatList); ++i) { - if (wined3d_check_device_format(device->ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) + if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, + mode.format_id, 0, WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) { DDSURFACEDESC sdesc; @@ -1689,48 +1695,42 @@ static HRESULT WINAPI d3d_device1_GetDirect3D(IDirect3DDevice *iface, IDirect3D * (Is a NULL viewport valid?) * *****************************************************************************/ -static HRESULT WINAPI d3d_device3_SetCurrentViewport(IDirect3DDevice3 *iface, IDirect3DViewport3 *Direct3DViewport3) +static HRESULT WINAPI d3d_device3_SetCurrentViewport(IDirect3DDevice3 *iface, IDirect3DViewport3 *viewport) { - struct d3d_device *This = impl_from_IDirect3DDevice3(iface); - struct d3d_viewport *vp = unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3); + struct d3d_viewport *vp = unsafe_impl_from_IDirect3DViewport3(viewport); + struct d3d_device *device = impl_from_IDirect3DDevice3(iface); - TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3); + TRACE("iface %p, viewport %p, current_viewport %p.\n", iface, viewport, device->current_viewport); if (!vp) { - WARN("Direct3DViewport3 is NULL, returning DDERR_INVALIDPARAMS\n"); + WARN("Direct3DViewport3 is NULL.\n"); return DDERR_INVALIDPARAMS; } wined3d_mutex_lock(); /* Do nothing if the specified viewport is the same as the current one */ - if (This->current_viewport == vp) + if (device->current_viewport == vp) { wined3d_mutex_unlock(); return D3D_OK; } - if (vp->active_device != This) + if (vp->active_device != device) { - WARN("Viewport %p active device is %p.\n", vp, vp->active_device); + WARN("Viewport %p, active device %p.\n", vp, vp->active_device); wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } - /* Release previous viewport and AddRef the new one */ - if (This->current_viewport) + IDirect3DViewport3_AddRef(viewport); + if (device->current_viewport) { - TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, - &This->current_viewport->IDirect3DViewport3_iface); - IDirect3DViewport3_Release(&This->current_viewport->IDirect3DViewport3_iface); + viewport_deactivate(device->current_viewport); + IDirect3DViewport3_Release(&device->current_viewport->IDirect3DViewport3_iface); } - IDirect3DViewport3_AddRef(Direct3DViewport3); - - /* Set this viewport as the current viewport */ - This->current_viewport = vp; - - /* Activate this viewport */ - viewport_activate(This->current_viewport, FALSE); + device->current_viewport = vp; + viewport_activate(device->current_viewport, FALSE); wined3d_mutex_unlock(); @@ -2461,62 +2461,7 @@ static HRESULT WINAPI d3d_device3_GetRenderState(IDirect3DDevice3 *iface, case D3DRENDERSTATE_TEXTUREMAPBLEND: { - /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse - the mapping to get the value. */ - DWORD colorop, colorarg1, colorarg2; - DWORD alphaop, alphaarg1, alphaarg2; - - wined3d_mutex_lock(); - - device->legacyTextureBlending = TRUE; - - colorop = wined3d_device_get_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_COLOR_OP); - colorarg1 = wined3d_device_get_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_COLOR_ARG1); - colorarg2 = wined3d_device_get_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_COLOR_ARG2); - alphaop = wined3d_device_get_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_ALPHA_OP); - alphaarg1 = wined3d_device_get_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_ALPHA_ARG1); - alphaarg2 = wined3d_device_get_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_ALPHA_ARG2); - - if (colorop == WINED3D_TOP_SELECT_ARG1 && colorarg1 == WINED3DTA_TEXTURE - && alphaop == WINED3D_TOP_SELECT_ARG1 && alphaarg1 == WINED3DTA_TEXTURE) - *value = D3DTBLEND_DECAL; - else if (colorop == WINED3D_TOP_SELECT_ARG1 && colorarg1 == WINED3DTA_TEXTURE - && alphaop == WINED3D_TOP_MODULATE - && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT) - *value = D3DTBLEND_DECALALPHA; - else if (colorop == WINED3D_TOP_MODULATE - && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT - && alphaop == WINED3D_TOP_MODULATE - && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT) - *value = D3DTBLEND_MODULATEALPHA; - else - { - struct wined3d_texture *tex = NULL; - BOOL tex_alpha = FALSE; - DDPIXELFORMAT ddfmt; - - if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) - { - struct wined3d_resource_desc desc; - - wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); - ddfmt.dwSize = sizeof(ddfmt); - ddrawformat_from_wined3dformat(&ddfmt, desc.format); - if (ddfmt.u5.dwRGBAlphaBitMask) - tex_alpha = TRUE; - } - - if (!(colorop == WINED3D_TOP_MODULATE - && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT - && alphaop == (tex_alpha ? WINED3D_TOP_SELECT_ARG1 : WINED3D_TOP_SELECT_ARG2) - && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)) - ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n"); - - *value = D3DTBLEND_MODULATE; - } - - wined3d_mutex_unlock(); - + *value = device->texture_map_blend; return D3D_OK; } @@ -2717,6 +2662,33 @@ static HRESULT WINAPI d3d_device7_SetRenderState_FPUPreserve(IDirect3DDevice7 *i return hr; } +static void fixup_texture_alpha_op(struct d3d_device *device) +{ + /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states. + See d3d_device3_SetRenderState() for details. */ + struct wined3d_texture *tex; + BOOL tex_alpha = TRUE; + DDPIXELFORMAT ddfmt; + + if (!(device->legacyTextureBlending && device->texture_map_blend == D3DTBLEND_MODULATE)) + return; + + if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) + { + struct wined3d_resource_desc desc; + + wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); + ddfmt.dwSize = sizeof(ddfmt); + ddrawformat_from_wined3dformat(&ddfmt, desc.format); + if (!ddfmt.u5.dwRGBAlphaBitMask) + tex_alpha = FALSE; + } + + /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */ + wined3d_device_set_texture_stage_state(device->wined3d_device, + 0, WINED3D_TSS_ALPHA_OP, tex_alpha ? WINED3D_TOP_SELECT_ARG1 : WINED3D_TOP_SELECT_ARG2); +} + static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, D3DRENDERSTATETYPE state, DWORD value) { @@ -2736,8 +2708,7 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, in device - TRUE if the app is using TEXTUREMAPBLEND. Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by - GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok, - unless some broken game will be found that cares. */ + GetTextureStageState and vice versa. */ struct d3d_device *device = impl_from_IDirect3DDevice3(iface); HRESULT hr; @@ -2760,7 +2731,8 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, if (value == 0) { - hr = wined3d_device_set_texture(device->wined3d_device, 0, NULL); + wined3d_device_set_texture(device->wined3d_device, 0, NULL); + hr = D3D_OK; break; } @@ -2778,33 +2750,23 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, case D3DRENDERSTATE_TEXTUREMAPBLEND: { + if (value == device->texture_map_blend) + { + TRACE("Application is setting the same value over, nothing to do.\n"); + + hr = D3D_OK; + break; + } + device->legacyTextureBlending = TRUE; + device->texture_map_blend = value; switch (value) { case D3DTBLEND_MODULATE: { - struct wined3d_texture *tex = NULL; - BOOL tex_alpha = FALSE; - DDPIXELFORMAT ddfmt; - - if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) - { - struct wined3d_resource_desc desc; + fixup_texture_alpha_op(device); - wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); - ddfmt.dwSize = sizeof(ddfmt); - ddrawformat_from_wined3dformat(&ddfmt, desc.format); - if (ddfmt.u5.dwRGBAlphaBitMask) - tex_alpha = TRUE; - } - - if (tex_alpha) - wined3d_device_set_texture_stage_state(device->wined3d_device, - 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG1); - else - wined3d_device_set_texture_stage_state(device->wined3d_device, - 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG2); wined3d_device_set_texture_stage_state(device->wined3d_device, 0, WINED3D_TSS_ALPHA_ARG1, WINED3DTA_TEXTURE); wined3d_device_set_texture_stage_state(device->wined3d_device, @@ -2874,7 +2836,6 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, default: FIXME("Unhandled texture environment %#x.\n", value); } - hr = D3D_OK; break; } @@ -2949,10 +2910,8 @@ static HRESULT WINAPI d3d_device3_SetLightState(IDirect3DDevice3 *iface, wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } - material_activate(m); } - device->material = value; } else if (state == D3DLIGHTSTATE_COLORMODEL) @@ -3469,9 +3428,9 @@ static HRESULT d3d_device_prepare_vertex_buffer(struct d3d_device *device, UINT TRACE("Growing vertex buffer to %u bytes\n", size); desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY; + desc.usage = WINED3DUSAGE_DYNAMIC; desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -3661,9 +3620,9 @@ static HRESULT d3d_device_prepare_index_buffer(struct d3d_device *device, UINT m TRACE("Growing index buffer to %u bytes\n", size); desc.byte_width = size; - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL; + desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_STATICDECL; desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -3919,7 +3878,20 @@ static HRESULT WINAPI d3d_device2_SetClipStatus(IDirect3DDevice2 *iface, D3DCLIP *****************************************************************************/ static HRESULT WINAPI d3d_device7_GetClipStatus(IDirect3DDevice7 *iface, D3DCLIPSTATUS *clip_status) { - FIXME("iface %p, clip_status %p stub!\n", iface, clip_status); + struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_viewport vp; + + FIXME("iface %p, clip_status %p stub.\n", iface, clip_status); + + wined3d_device_get_viewports(device->wined3d_device, NULL, &vp); + clip_status->minx = vp.x; + clip_status->maxx = vp.x + vp.width; + clip_status->miny = vp.y; + clip_status->maxy = vp.y + vp.height; + clip_status->minz = 0.0f; + clip_status->maxz = 0.0f; + clip_status->dwFlags = D3DCLIPSTATUS_EXTENTS2; + clip_status->dwStatus = 0; return D3D_OK; } @@ -4275,8 +4247,11 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); struct d3d_vertex_buffer *vb_impl = unsafe_impl_from_IDirect3DVertexBuffer7(vb); - HRESULT hr; + struct wined3d_resource *wined3d_resource; + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; DWORD stride; + HRESULT hr; TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n", iface, primitive_type, vb, start_vertex, vertex_count, flags); @@ -4289,6 +4264,26 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE stride = get_flexible_vertex_size(vb_impl->fvf); + if (vb_impl->Caps & D3DVBCAPS_SYSTEMMEMORY) + { + TRACE("Drawing from D3DVBCAPS_SYSTEMMEMORY vertex buffer, forwarding to DrawPrimitive().\n"); + wined3d_mutex_lock(); + wined3d_resource = wined3d_buffer_get_resource(vb_impl->wined3d_buffer); + wined3d_box.left = start_vertex * stride; + wined3d_box.right = wined3d_box.left + vertex_count * stride; + if (FAILED(hr = wined3d_resource_map(wined3d_resource, 0, &wined3d_map_desc, + &wined3d_box, WINED3D_MAP_READ))) + { + wined3d_mutex_unlock(); + return D3DERR_VERTEXBUFFERLOCKED; + } + hr = d3d_device7_DrawPrimitive(iface, primitive_type, vb_impl->fvf, wined3d_map_desc.data, + vertex_count, flags); + wined3d_resource_unmap(wined3d_resource, 0); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_lock(); wined3d_device_set_vertex_declaration(device->wined3d_device, vb_impl->wined3d_declaration); if (FAILED(hr = wined3d_device_set_stream_source(device->wined3d_device, @@ -4366,6 +4361,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, struct d3d_device *device = impl_from_IDirect3DDevice7(iface); struct d3d_vertex_buffer *vb_impl = unsafe_impl_from_IDirect3DVertexBuffer7(vb); DWORD stride = get_flexible_vertex_size(vb_impl->fvf); + struct wined3d_resource *wined3d_resource; struct wined3d_map_desc wined3d_map_desc; struct wined3d_box wined3d_box = {0}; struct wined3d_resource *ib; @@ -4382,6 +4378,26 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, return D3D_OK; } + if (vb_impl->Caps & D3DVBCAPS_SYSTEMMEMORY) + { + TRACE("Drawing from D3DVBCAPS_SYSTEMMEMORY vertex buffer, forwarding to DrawIndexedPrimitive().\n"); + wined3d_mutex_lock(); + wined3d_box.left = start_vertex * stride; + wined3d_box.right = wined3d_box.left + vertex_count * stride; + wined3d_resource = wined3d_buffer_get_resource(vb_impl->wined3d_buffer); + if (FAILED(hr = wined3d_resource_map(wined3d_resource, 0, &wined3d_map_desc, + &wined3d_box, WINED3D_MAP_READ))) + { + wined3d_mutex_unlock(); + return D3DERR_VERTEXBUFFERLOCKED; + } + hr = d3d_device7_DrawIndexedPrimitive(iface, primitive_type, vb_impl->fvf, + wined3d_map_desc.data, vertex_count, indices, index_count, flags); + wined3d_resource_unmap(wined3d_resource, 0); + wined3d_mutex_unlock(); + return hr; + } + /* Steps: * 1) Upload the indices to the index buffer * 2) Set the index source @@ -4464,19 +4480,24 @@ static HRESULT WINAPI d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDe } static HRESULT WINAPI d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface, - D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, WORD *Indices, - DWORD IndexCount, DWORD Flags) + D3DPRIMITIVETYPE primitive_type, IDirect3DVertexBuffer *vertex_buffer, + WORD *indices, DWORD index_count, DWORD flags) { + struct d3d_vertex_buffer *vb = + unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7 *)vertex_buffer); struct d3d_device *device = impl_from_IDirect3DDevice3(iface); - struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7 *)D3DVertexBuf); + DWORD stride; TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n", - iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags); + iface, primitive_type, vertex_buffer, indices, index_count, flags); - setup_lighting(device, vb->fvf, Flags); + setup_lighting(device, vb->fvf, flags); + + if (!(stride = get_flexible_vertex_size(vb->fvf))) + return D3D_OK; - return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device->IDirect3DDevice7_iface, PrimitiveType, - &vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount, Flags); + return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device->IDirect3DDevice7_iface, primitive_type, + &vb->IDirect3DVertexBuffer7_iface, 0, vb->size / stride, indices, index_count, flags); } /***************************************************************************** @@ -4770,18 +4791,18 @@ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface, struct d3d_device *device = impl_from_IDirect3DDevice7(iface); struct ddraw_surface *surf = unsafe_impl_from_IDirectDrawSurface7(texture); struct wined3d_texture *wined3d_texture = NULL; - HRESULT hr; - TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); + TRACE("iface %p, stage %u, texture %p, surf %p, surf->surface_desc.ddsCaps.dwCaps %#x.\n", + iface, stage, texture, surf, surf ? surf->surface_desc.ddsCaps.dwCaps : 0); if (surf && (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) wined3d_texture = surf->wined3d_texture; wined3d_mutex_lock(); - hr = wined3d_device_set_texture(device->wined3d_device, stage, wined3d_texture); + wined3d_device_set_texture(device->wined3d_device, stage, wined3d_texture); wined3d_mutex_unlock(); - return hr; + return D3D_OK; } static HRESULT WINAPI d3d_device7_SetTexture_FPUSetup(IDirect3DDevice7 *iface, @@ -4808,49 +4829,30 @@ static HRESULT WINAPI d3d_device3_SetTexture(IDirect3DDevice3 *iface, { struct d3d_device *device = impl_from_IDirect3DDevice3(iface); struct ddraw_surface *tex = unsafe_impl_from_IDirect3DTexture2(texture); - DWORD texmapblend; - HRESULT hr; + struct wined3d_texture *wined3d_texture; TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); wined3d_mutex_lock(); - if (device->legacyTextureBlending) - IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend); - - hr = IDirect3DDevice7_SetTexture(&device->IDirect3DDevice7_iface, stage, &tex->IDirectDrawSurface7_iface); - - if (device->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE) + if (tex && ((tex->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) || !device->hw)) { - /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states. - See d3d_device3_SetRenderState() for details. */ - struct wined3d_texture *tex = NULL; - BOOL tex_alpha = FALSE; - DDPIXELFORMAT ddfmt; + if (!(tex->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + WARN("Setting texture without DDSCAPS_TEXTURE.\n"); + wined3d_texture = tex->wined3d_texture; + } + else + { + wined3d_texture = NULL; + } - if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) - { - struct wined3d_resource_desc desc; + wined3d_device_set_texture(device->wined3d_device, stage, wined3d_texture); - wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); - ddfmt.dwSize = sizeof(ddfmt); - ddrawformat_from_wined3dformat(&ddfmt, desc.format); - if (ddfmt.u5.dwRGBAlphaBitMask) - tex_alpha = TRUE; - } - - /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */ - if (tex_alpha) - wined3d_device_set_texture_stage_state(device->wined3d_device, - 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG1); - else - wined3d_device_set_texture_stage_state(device->wined3d_device, - 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG2); - } + fixup_texture_alpha_op(device); wined3d_mutex_unlock(); - return hr; + return D3D_OK; } static const struct tss_lookup @@ -5164,10 +5166,26 @@ static HRESULT WINAPI d3d_device3_SetTextureStageState(IDirect3DDevice3 *iface, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value) { struct d3d_device *device = impl_from_IDirect3DDevice3(iface); + DWORD old_value; + HRESULT hr; TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, state, value); + /* Tests show that legacy texture blending is not reset if the texture stage state + * value is unchanged. */ + if (FAILED(hr = IDirect3DDevice7_GetTextureStageState(&device->IDirect3DDevice7_iface, + stage, state, &old_value))) + return hr; + + if (old_value == value) + { + TRACE("Application is setting the same value over, nothing to do.\n"); + return D3D_OK; + } + + device->legacyTextureBlending = FALSE; + return IDirect3DDevice7_SetTextureStageState(&device->IDirect3DDevice7_iface, stage, state, value); } @@ -5296,25 +5314,12 @@ static HRESULT WINAPI d3d_device7_Clear_FPUPreserve(IDirect3DDevice7 *iface, DWO return hr; } -/***************************************************************************** - * IDirect3DDevice7::SetViewport - * - * Sets the current viewport. - * - * Version 7 only, but IDirect3DViewport uses this call for older - * versions - * - * Params: - * Data: The new viewport to set - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; + struct ddraw_surface *surface; struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); @@ -5322,6 +5327,23 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi if (!viewport) return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); + if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + { + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); + + if (viewport->dwX > rt_desc.width || viewport->dwWidth > rt_desc.width - viewport->dwX + || viewport->dwY > rt_desc.height || viewport->dwHeight > rt_desc.height - viewport->dwY) + { + WARN("Invalid viewport, returning E_INVALIDARG.\n"); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + vp.x = viewport->dwX; vp.y = viewport->dwY; vp.width = viewport->dwWidth; @@ -5329,8 +5351,7 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi vp.min_z = viewport->dvMinZ; vp.max_z = viewport->dvMaxZ; - wined3d_mutex_lock(); - wined3d_device_set_viewport(device->wined3d_device, &vp); + wined3d_device_set_viewports(device->wined3d_device, 1, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -5353,21 +5374,6 @@ static HRESULT WINAPI d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7 *ifac return hr; } -/***************************************************************************** - * IDirect3DDevice::GetViewport - * - * Returns the current viewport - * - * Version 7 - * - * Params: - * Data: D3D7Viewport structure to write the viewport information to - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); @@ -5379,7 +5385,7 @@ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); + wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport); wined3d_mutex_unlock(); viewport->dwX = wined3d_viewport.x; @@ -5611,12 +5617,20 @@ static HRESULT WINAPI d3d_device7_GetLight_FPUPreserve(IDirect3DDevice7 *iface, static HRESULT d3d_device7_BeginStateBlock(IDirect3DDevice7 *iface) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_stateblock *stateblock; HRESULT hr; TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_device_begin_stateblock(device->wined3d_device); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to begin a stateblock while recording, returning D3DERR_INBEGINSTATEBLOCK.\n"); + return D3DERR_INBEGINSTATEBLOCK; + } + if (SUCCEEDED(hr = wined3d_device_begin_stateblock(device->wined3d_device, &stateblock))) + device->recording = stateblock; wined3d_mutex_unlock(); return hr_ddraw_from_wined3d(hr); @@ -5668,8 +5682,13 @@ static HRESULT d3d_device7_EndStateBlock(IDirect3DDevice7 *iface, DWORD *statebl return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - - hr = wined3d_device_end_stateblock(device->wined3d_device, &wined3d_sb); + if (!device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to end a stateblock, but no stateblock is being recorded.\n"); + return D3DERR_NOTINBEGINSTATEBLOCK; + } + hr = wined3d_device_end_stateblock(device->wined3d_device); if (FAILED(hr)) { WARN("Failed to end stateblock, hr %#x.\n", hr); @@ -5677,6 +5696,8 @@ static HRESULT d3d_device7_EndStateBlock(IDirect3DDevice7 *iface, DWORD *statebl *stateblock = 0; return hr_ddraw_from_wined3d(hr); } + wined3d_sb = device->recording; + device->recording = NULL; h = ddraw_allocate_handle(&device->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK); if (h == DDRAW_INVALID_HANDLE) @@ -5781,6 +5802,12 @@ static HRESULT d3d_device7_ApplyStateBlock(IDirect3DDevice7 *iface, DWORD stateb TRACE("iface %p, stateblock %#x.\n", iface, stateblock); wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to apply a stateblock while recording, returning D3DERR_INBEGINSTATEBLOCK.\n"); + return D3DERR_INBEGINSTATEBLOCK; + } wined3d_sb = ddraw_get_object(&device->handle_table, stateblock - 1, DDRAW_HANDLE_STATEBLOCK); if (!wined3d_sb) { @@ -5835,6 +5862,12 @@ static HRESULT d3d_device7_CaptureStateBlock(IDirect3DDevice7 *iface, DWORD stat TRACE("iface %p, stateblock %#x.\n", iface, stateblock); wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to capture a stateblock while recording, returning D3DERR_INBEGINSTATEBLOCK.\n"); + return D3DERR_INBEGINSTATEBLOCK; + } wined3d_sb = ddraw_get_object(&device->handle_table, stateblock - 1, DDRAW_HANDLE_STATEBLOCK); if (!wined3d_sb) { @@ -5965,6 +5998,13 @@ static HRESULT d3d_device7_CreateStateBlock(IDirect3DDevice7 *iface, wined3d_mutex_lock(); + if (device->recording) + { + wined3d_mutex_unlock(); + WARN("Trying to apply a stateblock while recording, returning D3DERR_INBEGINSTATEBLOCK.\n"); + return D3DERR_INBEGINSTATEBLOCK; + } + /* The D3DSTATEBLOCKTYPE enum is fine here. */ hr = wined3d_stateblock_create(device->wined3d_device, type, &wined3d_sb); if (FAILED(hr)) @@ -6972,8 +7012,11 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, B else if (version == 2) wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_SPECULARENABLE, TRUE); if (version < 7) + { wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_NORMALIZENORMALS, TRUE); - + IDirect3DDevice3_SetRenderState(&device->IDirect3DDevice3_iface, + D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE); + } return D3D_OK; } @@ -7003,18 +7046,18 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_NOPALETTEATTACHED; } - if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) - { - WARN("Surface %p is not in video memory.\n", target); - return D3DERR_SURFACENOTINVIDMEM; - } - if (ddraw->flags & DDRAW_NO3D) { ERR_(winediag)("The application wants to create a Direct3D device, " "but the current DirectDrawRenderer does not support this.\n"); - return DDERR_NO3D; + return DDERR_OUTOFMEMORY; + } + + if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target); + return D3DERR_SURFACENOTINVIDMEM; } if (ddraw->d3ddevice) diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c index 17bea2764c5..ee803276e65 100644 --- a/dll/directx/wine/ddraw/executebuffer.c +++ b/dll/directx/wine/ddraw/executebuffer.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -48,8 +45,7 @@ static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC *lpDesc) { TRACE("lpData : %p\n", lpDesc->lpData); } -HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, - struct d3d_device *device, struct d3d_viewport *viewport) +HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d_device *device) { DWORD is = buffer->data.dwInstructionOffset; char *instr = (char *)buffer->desc.lpData + is; @@ -58,16 +54,6 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct wined3d_box box = {0}; HRESULT hr; - if (viewport->active_device != device) - { - WARN("Viewport %p active device is %p.\n", - viewport, viewport->active_device); - return DDERR_INVALIDPARAMS; - } - - /* Activate the viewport */ - viewport_activate(viewport, FALSE); - TRACE("ExecuteData :\n"); if (TRACE_ON(ddraw)) _dump_executedata(&(buffer->data)); @@ -129,10 +115,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct wined3d_buffer_desc desc; desc.byte_width = new_size * sizeof(*indices); - desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_STATICDECL; + desc.usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_STATICDECL; desc.bind_flags = WINED3D_BIND_INDEX_BUFFER; - desc.access = WINED3D_RESOURCE_ACCESS_GPU - | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; desc.misc_flags = 0; desc.structure_byte_stride = 0; @@ -321,21 +306,11 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, case D3DPROCESSVERTICES_TRANSFORM: wined3d_device_set_stream_source(device->wined3d_device, 0, buffer->src_vertex_buffer, buffer->src_vertex_pos, sizeof(D3DVERTEX)); - if (op == D3DPROCESSVERTICES_TRANSFORMLIGHT) - { - wined3d_device_set_vertex_declaration(device->wined3d_device, - ddraw_find_decl(device->ddraw, D3DFVF_VERTEX)); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_LIGHTING, TRUE); - } - else - { - wined3d_device_set_vertex_declaration(device->wined3d_device, - ddraw_find_decl(device->ddraw, D3DFVF_LVERTEX)); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_LIGHTING, FALSE); - } - + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_LIGHTING, + op == D3DPROCESSVERTICES_TRANSFORMLIGHT && !!device->material); + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, op == D3DPROCESSVERTICES_TRANSFORMLIGHT + ? D3DFVF_VERTEX : D3DFVF_LVERTEX)); wined3d_device_process_vertices(device->wined3d_device, ci->wStart, ci->wDest, ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); break; @@ -348,7 +323,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, ci->wDest * sizeof(D3DTLVERTEX), 0, 0, - wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box); + wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box, 0); break; default: @@ -610,9 +585,16 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; HRESULT hr; + DWORD buf_size = buffer->desc.dwBufferSize, copy_size; TRACE("iface %p, data %p.\n", iface, data); + if (data->dwSize != sizeof(*data)) + { + WARN("data->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", data->dwSize); + return DDERR_INVALIDPARAMS; + } + /* Skip past previous vertex data. */ buffer->src_vertex_pos += buffer->data.dwVertexCount; @@ -635,7 +617,7 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * desc.byte_width = new_size * sizeof(D3DTLVERTEX); desc.usage = WINED3DUSAGE_STATICDECL; - desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_W; if (FAILED(hr = wined3d_buffer_create(buffer->d3ddev->wined3d_device, &desc, NULL, NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer))) @@ -659,7 +641,7 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * buffer->src_vertex_pos = 0; } - if (data->dwVertexCount) + if (data->dwVertexCount && (!buf_size || data->dwVertexOffset < buf_size)) { box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX); box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX); @@ -667,8 +649,11 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * 0, &map_desc, &box, WINED3D_MAP_WRITE))) return hr; - memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, - data->dwVertexCount * sizeof(D3DVERTEX)); + copy_size = data->dwVertexCount * sizeof(D3DVERTEX); + if (buf_size) + copy_size = min(copy_size, buf_size - data->dwVertexOffset); + + memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, copy_size); wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0); } @@ -696,12 +681,11 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * static HRESULT WINAPI d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data) { struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface); - DWORD dwSize; TRACE("iface %p, data %p.\n", iface, data); - dwSize = data->dwSize; - memcpy(data, &buffer->data, dwSize); + /* Tests show that dwSize is ignored. */ + memcpy(data, &buffer->data, sizeof(*data)); if (TRACE_ON(ddraw)) { diff --git a/dll/directx/wine/ddraw/light.c b/dll/directx/wine/ddraw/light.c index 9d0bb6028f3..a8c3a93f738 100644 --- a/dll/directx/wine/ddraw/light.c +++ b/dll/directx/wine/ddraw/light.c @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -39,7 +36,7 @@ static void light_update(struct d3d_light *light) if (!light->active_viewport || !light->active_viewport->active_device) return; device = light->active_viewport->active_device; - IDirect3DDevice7_SetLight(&device->IDirect3DDevice7_iface, light->dwLightIndex, &light->light7); + IDirect3DDevice7_SetLight(&device->IDirect3DDevice7_iface, light->active_light_index, &light->light7); } /***************************************************************************** @@ -54,14 +51,16 @@ void light_activate(struct d3d_light *light) TRACE("light %p.\n", light); - if (!light->active_viewport || !light->active_viewport->active_device) return; + if (!light->active_viewport || !light->active_viewport->active_device + || light->active_viewport->active_device->current_viewport != light->active_viewport) + return; device = light->active_viewport->active_device; - light_update(light); - if (!(light->light.dwFlags & D3DLIGHT_ACTIVE)) + if (light->light.dwFlags & D3DLIGHT_ACTIVE) { - IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, TRUE); - light->light.dwFlags |= D3DLIGHT_ACTIVE; + viewport_alloc_active_light_index(light); + light_update(light); + IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->active_light_index, TRUE); } } @@ -78,13 +77,18 @@ void light_deactivate(struct d3d_light *light) TRACE("light %p.\n", light); - if (!light->active_viewport || !light->active_viewport->active_device) return; - device = light->active_viewport->active_device; + if (!light->active_viewport || !light->active_viewport->active_device + || light->active_viewport->active_device->current_viewport != light->active_viewport) + { + assert(!light->active_light_index); + return; + } - if (light->light.dwFlags & D3DLIGHT_ACTIVE) + device = light->active_viewport->active_device; + if (light->active_light_index) { - IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, FALSE); - light->light.dwFlags &= ~D3DLIGHT_ACTIVE; + IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->active_light_index, FALSE); + viewport_free_active_light_index(light); } } @@ -182,7 +186,7 @@ static HRESULT WINAPI d3d_light_SetLight(IDirect3DLight *iface, D3DLIGHT *data) light7->dcvSpecular = zero_value; else light7->dcvSpecular = data->dcvColor; - light7->dcvAmbient = data->dcvColor; + light7->dcvAmbient = zero_value; light7->dvPosition = data->dvPosition; light7->dvDirection = data->dvDirection; light7->dvRange = data->dvRange; @@ -195,13 +199,12 @@ static HRESULT WINAPI d3d_light_SetLight(IDirect3DLight *iface, D3DLIGHT *data) wined3d_mutex_lock(); memcpy(&light->light, data, sizeof(*data)); - if (!(light->light.dwFlags & D3DLIGHT_ACTIVE) && flags & D3DLIGHT_ACTIVE) - light_activate(light); - else if (light->light.dwFlags & D3DLIGHT_ACTIVE && !(flags & D3DLIGHT_ACTIVE)) + + if (!(flags & D3DLIGHT_ACTIVE)) light_deactivate(light); - else if (flags & D3DLIGHT_ACTIVE) - light_update(light); + light->light.dwFlags = flags; + light_activate(light); wined3d_mutex_unlock(); return D3D_OK; diff --git a/dll/directx/wine/ddraw/main.c b/dll/directx/wine/ddraw/main.c index 9c0a81ca18e..3b3fa12d605 100644 --- a/dll/directx/wine/ddraw/main.c +++ b/dll/directx/wine/ddraw/main.c @@ -21,9 +21,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #define DDRAW_INIT_GUID #include "ddraw_private.h" #include "rpcproxy.h" @@ -256,62 +253,52 @@ HRESULT WINAPI GetSurfaceFromDC(HDC dc, IDirectDrawSurface4 **surface, HDC *devi * E_OUTOFMEMORY if some allocation failed * ***********************************************************************/ -static HRESULT -DDRAW_Create(const GUID *guid, - void **DD, - IUnknown *UnkOuter, - REFIID iid) +static HRESULT DDRAW_Create(const GUID *guid, void **out, IUnknown *outer_unknown, REFIID iid) { enum wined3d_device_type device_type; struct ddraw *ddraw; - HRESULT hr; DWORD flags = 0; + HRESULT hr; TRACE("driver_guid %s, ddraw %p, outer_unknown %p, interface_iid %s.\n", - debugstr_guid(guid), DD, UnkOuter, debugstr_guid(iid)); + debugstr_guid(guid), out, outer_unknown, debugstr_guid(iid)); - *DD = NULL; + *out = NULL; if (guid == (GUID *) DDCREATE_EMULATIONONLY) { - /* Use the reference device id. This doesn't actually change anything, - * WineD3D always uses OpenGL for D3D rendering. One could make it request - * indirect rendering - */ device_type = WINED3D_DEVICE_TYPE_REF; } - else if(guid == (GUID *) DDCREATE_HARDWAREONLY) + else if (guid == (GUID *) DDCREATE_HARDWAREONLY) { device_type = WINED3D_DEVICE_TYPE_HAL; } else { - device_type = 0; + device_type = WINED3D_DEVICE_TYPE_HAL; } /* DDraw doesn't support aggregation, according to msdn */ - if (UnkOuter != NULL) + if (outer_unknown != NULL) return CLASS_E_NOAGGREGATION; if (!IsEqualGUID(iid, &IID_IDirectDraw7)) flags = WINED3D_LEGACY_FFP_LIGHTING; - /* DirectDraw creation comes here */ if (!(ddraw = heap_alloc_zero(sizeof(*ddraw)))) { - ERR("Out of memory when creating DirectDraw\n"); + ERR("Out of memory when creating DirectDraw.\n"); return E_OUTOFMEMORY; } - hr = ddraw_init(ddraw, flags, device_type); - if (FAILED(hr)) + if (FAILED(hr = ddraw_init(ddraw, flags, device_type))) { WARN("Failed to initialize ddraw object, hr %#x.\n", hr); heap_free(ddraw); return hr; } - hr = IDirectDraw7_QueryInterface(&ddraw->IDirectDraw7_iface, iid, DD); + hr = IDirectDraw7_QueryInterface(&ddraw->IDirectDraw7_iface, iid, out); IDirectDraw7_Release(&ddraw->IDirectDraw7_iface); if (SUCCEEDED(hr)) list_add_head(&global_ddraw_list, &ddraw->ddraw_list_entry); diff --git a/dll/directx/wine/ddraw/material.c b/dll/directx/wine/ddraw/material.c index 1fbf093e455..01c93e8bbc7 100644 --- a/dll/directx/wine/ddraw/material.c +++ b/dll/directx/wine/ddraw/material.c @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); diff --git a/dll/directx/wine/ddraw/palette.c b/dll/directx/wine/ddraw/palette.c index 5148832cab6..89e4fa69e33 100644 --- a/dll/directx/wine/ddraw/palette.c +++ b/dll/directx/wine/ddraw/palette.c @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -176,7 +173,7 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface, hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count, entries); if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE) - ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE); + ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE, 0); wined3d_mutex_unlock(); @@ -218,7 +215,7 @@ static HRESULT WINAPI ddraw_palette_GetEntries(IDirectDrawPalette *iface, return hr; } -static const struct IDirectDrawPaletteVtbl ddraw_palette_vtbl = +static struct IDirectDrawPaletteVtbl ddraw_palette_vtbl = { /*** IUnknown ***/ ddraw_palette_QueryInterface, diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c index 11a0e6ba8db..9ed442e8d65 100644 --- a/dll/directx/wine/ddraw/surface.c +++ b/dll/directx/wine/ddraw/surface.c @@ -21,9 +21,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -40,8 +37,10 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra * applications from drawing to the screen while we've locked the frontbuffer. * We'd like to do this in wined3d instead, but for that to work wined3d needs * to support windowless rendering first. */ -HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) +HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, + const RECT *rect, BOOL read, unsigned int swap_interval) { + struct wined3d_texture *dst_texture; struct ddraw *ddraw = surface->ddraw; HDC surface_dc, screen_dc; int x, y, w, h; @@ -49,6 +48,12 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE BOOL ret; RECT r; + if (surface->ddraw->flags & DDRAW_SWAPPED && !read) + { + surface->ddraw->flags &= ~DDRAW_SWAPPED; + rect = NULL; + } + if (!rect) { SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight); @@ -69,9 +74,18 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE * care about. */ if (read) return DD_OK; + if (swap_interval) + dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0); + else + dst_texture = surface->ddraw->wined3d_frontbuffer; - return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect, - surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT); + if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture, + surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval) + { + hr = wined3d_swapchain_present(surface->ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0); + surface->ddraw->flags |= DDRAW_SWAPPED; + } + return hr; } if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc))) @@ -474,7 +488,7 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD palette_impl->flags |= DDPCAPS_PRIMARYSURFACE; wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain, palette_impl ? palette_impl->wined3d_palette : NULL); - ddraw_surface_update_frontbuffer(surface, NULL, FALSE); + ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0); } if (palette_impl) IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface); @@ -510,7 +524,16 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface) surf = surface->complex_array[i]; surface->complex_array[i] = NULL; if (!surf->is_complex_root) + { + struct ddraw_texture *texture = wined3d_texture_get_parent(surf->wined3d_texture); + struct wined3d_device *wined3d_device = texture->wined3d_device; + struct ddraw_surface *root = texture->root; + ddraw_surface_cleanup(surf); + + if (surf == root) + wined3d_device_decref(wined3d_device); + } } if (surface->device1) @@ -734,38 +757,47 @@ static ULONG WINAPI d3d_texture1_Release(IDirect3DTexture *iface) * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7 *iface, - DDSCAPS2 *Caps, IDirectDrawSurface7 **Surface) + DDSCAPS2 *caps, IDirectDrawSurface7 **surface) { - struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface); + struct ddraw_surface *head_surface = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *surf; DDSCAPS2 our_caps; int i; - TRACE("iface %p, caps %p, attachment %p.\n", iface, Caps, Surface); + TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, surface); + + if (IDirectDrawSurface7_IsLost(&head_surface->IDirectDrawSurface7_iface) != DD_OK) + { + WARN("Surface %p is lost.\n", head_surface); + + *surface = NULL; + return DDERR_SURFACELOST; + } wined3d_mutex_lock(); - if(This->version < 7) + if(head_surface->version < 7) { /* Earlier dx apps put garbage into these members, clear them */ - our_caps.dwCaps = Caps->dwCaps; + our_caps.dwCaps = caps->dwCaps; our_caps.dwCaps2 = 0; our_caps.dwCaps3 = 0; our_caps.u1.dwCaps4 = 0; } else { - our_caps = *Caps; + our_caps = *caps; } - TRACE("(%p): Looking for caps: %x,%x,%x,%x\n", This, our_caps.dwCaps, our_caps.dwCaps2, our_caps.dwCaps3, our_caps.u1.dwCaps4); /* FIXME: Better debugging */ + TRACE("head_surface %p, looking for caps %#x, %#x, %#x, %#x.\n", head_surface, our_caps.dwCaps, + our_caps.dwCaps2, our_caps.dwCaps3, our_caps.u1.dwCaps4); /* FIXME: Better debugging */ for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) { - surf = This->complex_array[i]; + surf = head_surface->complex_array[i]; if(!surf) break; - TRACE("Surface: (%p) caps: %#x, %#x, %#x, %#x.\n", surf, + TRACE("Surface %p, caps %#x, %#x, %#x, %#x.\n", surf, surf->surface_desc.ddsCaps.dwCaps, surf->surface_desc.ddsCaps.dwCaps2, surf->surface_desc.ddsCaps.dwCaps3, @@ -780,9 +812,9 @@ static HRESULT WINAPI ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7 *ifa * Not sure how to test this. */ - TRACE("(%p): Returning surface %p\n", This, surf); - *Surface = &surf->IDirectDrawSurface7_iface; - ddraw_surface7_AddRef(*Surface); + TRACE("head_surface %p, returning surface %p.\n", head_surface, surf); + *surface = &surf->IDirectDrawSurface7_iface; + ddraw_surface7_AddRef(*surface); wined3d_mutex_unlock(); return DD_OK; @@ -790,11 +822,11 @@ static HRESULT WINAPI ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7 *ifa } /* Next, look at the attachment chain */ - surf = This; + surf = head_surface; while( (surf = surf->next_attached) ) { - TRACE("Surface: (%p) caps: %#x, %#x, %#x, %#x.\n", surf, + TRACE("Surface %p, caps %#x, %#x, %#x, %#x.\n", surf, surf->surface_desc.ddsCaps.dwCaps, surf->surface_desc.ddsCaps.dwCaps2, surf->surface_desc.ddsCaps.dwCaps3, @@ -803,19 +835,19 @@ static HRESULT WINAPI ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7 *ifa if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) { - TRACE("(%p): Returning surface %p\n", This, surf); - *Surface = &surf->IDirectDrawSurface7_iface; - ddraw_surface7_AddRef(*Surface); + TRACE("head_surface %p, returning surface %p.\n", head_surface, surf); + *surface = &surf->IDirectDrawSurface7_iface; + ddraw_surface7_AddRef(*surface); wined3d_mutex_unlock(); return DD_OK; } } - TRACE("(%p) Didn't find a valid surface\n", This); + TRACE("head_surface %p, didn't find a valid surface.\n", head_surface); wined3d_mutex_unlock(); - *Surface = NULL; + *surface = NULL; return DDERR_NOTFOUND; } @@ -990,7 +1022,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface, } if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE); + hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0); if (SUCCEEDED(hr)) hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, &map_desc, rect ? &box : NULL, @@ -1179,7 +1211,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface wined3d_mutex_lock(); hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE); + hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0); wined3d_mutex_unlock(); return hr; @@ -1224,6 +1256,24 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Unlock(IDirectDrawSurface return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL); } +static unsigned int ddraw_swap_interval_from_flags(DWORD flags) +{ + if (flags & DDFLIP_NOVSYNC) + return 0; + + switch (flags & (DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4)) + { + case DDFLIP_INTERVAL2: + return 2; + case DDFLIP_INTERVAL3: + return 3; + case DDFLIP_INTERVAL4: + return 4; + default: + return 1; + } +} + static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *src, DWORD flags) { @@ -1337,7 +1387,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture); src_impl->wined3d_texture = texture; - if (flags) + if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4)) { static UINT once; if (!once++) @@ -1347,7 +1397,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 } if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE); + hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE, ddraw_swap_interval_from_flags(flags)); else hr = DD_OK; @@ -1414,24 +1464,32 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * if (flags & DDBLT_COLORFILL) { + wined3d_flags = WINED3DCLEAR_TARGET; + if (!(flags & DDBLT_ASYNC)) + wined3d_flags |= WINED3DCLEAR_SYNCHRONOUS; + if (!wined3d_colour_from_ddraw_colour(&dst_surface->surface_desc.u4.ddpfPixelFormat, dst_surface->palette, fill_colour, &colour)) return DDERR_INVALIDPARAMS; return wined3d_device_clear_rendertarget_view(wined3d_device, ddraw_surface_get_rendertarget_view(dst_surface), - dst_rect, WINED3DCLEAR_TARGET, &colour, 0.0f, 0); + dst_rect, wined3d_flags, &colour, 0.0f, 0); } if (flags & DDBLT_DEPTHFILL) { + wined3d_flags = WINED3DCLEAR_ZBUFFER; + if (!(flags & DDBLT_ASYNC)) + wined3d_flags |= WINED3DCLEAR_SYNCHRONOUS; + if (!wined3d_colour_from_ddraw_colour(&dst_surface->surface_desc.u4.ddpfPixelFormat, dst_surface->palette, fill_colour, &colour)) return DDERR_INVALIDPARAMS; return wined3d_device_clear_rendertarget_view(wined3d_device, ddraw_surface_get_rendertarget_view(dst_surface), - dst_rect, WINED3DCLEAR_ZBUFFER, NULL, colour.r, 0); + dst_rect, wined3d_flags, NULL, colour.r, 0); } wined3d_flags = flags & ~DDBLT_ASYNC; @@ -1488,15 +1546,21 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (!dst_surface->clipper) { if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE); + hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0); if (SUCCEEDED(hr)) hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter); if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE); + hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0); return hr; } + if (!ddraw_clipper_is_valid(dst_surface->clipper)) + { + FIXME("Attempting to blit with an invalid clipper.\n"); + return DDERR_INVALIDPARAMS; + } + scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left); scale_y = (float)(src_rect.bottom - src_rect.top) / (float)(dst_rect.bottom - dst_rect.top); @@ -1535,7 +1599,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE))) + if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0))) break; } } @@ -1546,7 +1610,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE))) + if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0))) break; } } @@ -1678,6 +1742,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 * && ((ULONG)src_rect->left >= src_rect->right || src_rect->right > src_impl->surface_desc.dwWidth || (ULONG)src_rect->top >= src_rect->bottom || src_rect->bottom > src_impl->surface_desc.dwHeight)) { + wined3d_mutex_unlock(); WARN("Invalid source rectangle.\n"); return DDERR_INVALIDRECT; } @@ -1715,6 +1780,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 * if (!(flags & (DDBLT_COLORFILL | DDBLT_DEPTHFILL)) && !src_impl) { WARN("No source surface.\n"); + wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } @@ -2219,7 +2285,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) if (surface->dc) hr = DDERR_DCALREADYCREATED; else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE); + hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0); if (SUCCEEDED(hr)) hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); @@ -2323,7 +2389,7 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h { surface->dc = NULL; if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE); + hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0); } wined3d_mutex_unlock(); @@ -3670,6 +3736,7 @@ static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface) static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); + unsigned int i; TRACE("iface %p.\n", iface); @@ -3710,6 +3777,12 @@ static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface) ddraw_update_lost_surfaces(surface->ddraw); surface->is_lost = FALSE; + for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) + { + if (surface->complex_array[i]) + surface->complex_array[i]->is_lost = FALSE; + } + return DD_OK; } @@ -4291,12 +4364,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac } if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE); + hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0); if (SUCCEEDED(hr)) hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT); if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE); + hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0); wined3d_mutex_unlock(); switch(hr) @@ -4358,39 +4431,26 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_BltFast(IDirectDrawSurfac src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags); } -/***************************************************************************** - * IDirectDrawSurface7::GetClipper - * - * Returns the IDirectDrawClipper interface of the clipper assigned to this - * surface - * - * Params: - * Clipper: Address to store the interface pointer at - * - * Returns: - * DD_OK on success - * DDERR_INVALIDPARAMS if Clipper is NULL - * DDERR_NOCLIPPERATTACHED if there's no clipper attached - * - *****************************************************************************/ -static HRESULT WINAPI ddraw_surface7_GetClipper(IDirectDrawSurface7 *iface, IDirectDrawClipper **Clipper) +static HRESULT WINAPI ddraw_surface7_GetClipper(IDirectDrawSurface7 *iface, IDirectDrawClipper **clipper) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); - TRACE("iface %p, clipper %p.\n", iface, Clipper); + TRACE("iface %p, clipper %p.\n", iface, clipper); - if (!Clipper) + if (!clipper) return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); if (!surface->clipper) { wined3d_mutex_unlock(); + *clipper = NULL; return DDERR_NOCLIPPERATTACHED; } - *Clipper = &surface->clipper->IDirectDrawClipper_iface; - IDirectDrawClipper_AddRef(*Clipper); + *clipper = &surface->clipper->IDirectDrawClipper_iface; + if (ddraw_clipper_is_valid(surface->clipper)) + IDirectDrawClipper_AddRef(*clipper); wined3d_mutex_unlock(); return DD_OK; @@ -4465,7 +4525,7 @@ static HRESULT WINAPI ddraw_surface7_SetClipper(IDirectDrawSurface7 *iface, if (clipper != NULL) IDirectDrawClipper_AddRef(iclipper); - if (old_clipper) + if (old_clipper && ddraw_clipper_is_valid(old_clipper)) IDirectDrawClipper_Release(&old_clipper->IDirectDrawClipper_iface); if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && This->ddraw->wined3d_swapchain) @@ -5356,7 +5416,7 @@ static HRESULT WINAPI d3d_texture1_Load(IDirect3DTexture *iface, IDirect3DTextur * The VTable *****************************************************************************/ -static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = +static struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = { /* IUnknown */ ddraw_surface7_QueryInterface, @@ -5415,7 +5475,7 @@ static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = ddraw_surface7_GetLOD, }; -static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = +static struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = { /* IUnknown */ ddraw_surface4_QueryInterface, @@ -5469,7 +5529,7 @@ static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = ddraw_surface4_ChangeUniquenessValue, }; -static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = +static struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = { /* IUnknown */ ddraw_surface3_QueryInterface, @@ -5517,7 +5577,7 @@ static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = ddraw_surface3_SetSurfaceDesc, }; -static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = +static struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = { /* IUnknown */ ddraw_surface2_QueryInterface, @@ -5755,11 +5815,14 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren /* Reduce the ddraw surface count. */ list_remove(&surface->surface_list_entry); - if (surface->clipper) + if (surface->clipper && ddraw_clipper_is_valid(surface->clipper)) IDirectDrawClipper_Release(&surface->clipper->IDirectDrawClipper_iface); if (surface == surface->ddraw->primary) + { surface->ddraw->primary = NULL; + surface->ddraw->gdi_surface = NULL; + } wined3d_private_store_cleanup(&surface->private_store); @@ -5939,13 +6002,21 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ } if (desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) { - WARN("DDSCAPS2_TEXTUREMANAGE used width DDSCAPS_VIDEOMEMORY " + WARN("DDSCAPS2_TEXTUREMANAGE used with DDSCAPS_VIDEOMEMORY " "or DDSCAPS_SYSTEMMEMORY, returning DDERR_INVALIDCAPS.\n"); heap_free(texture); return DDERR_INVALIDCAPS; } } + if (desc->ddsCaps.dwCaps & DDSCAPS_WRITEONLY + && !(desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE))) + { + WARN("DDSCAPS_WRITEONLY used without DDSCAPS2_TEXTUREMANAGE, returning DDERR_INVALIDCAPS.\n"); + heap_free(texture); + return DDERR_INVALIDCAPS; + } + if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) { ERR("Failed to get display mode, hr %#x.\n", hr); @@ -6016,6 +6087,13 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ return hr_ddraw_from_wined3d(hr); } + if (ddraw->d3ddevice) + { + if (ddraw->d3ddevice->recording) + wined3d_stateblock_decref(ddraw->d3ddevice->recording); + ddraw->d3ddevice->recording = NULL; + } + wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); } @@ -6024,6 +6102,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; wined3d_desc.usage = 0; + wined3d_desc.bind_flags = 0; wined3d_desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; wined3d_desc.width = desc->dwWidth; wined3d_desc.height = desc->dwHeight; @@ -6077,20 +6156,27 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ { if (!(desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE))) { + unsigned int bind_flags = 0; DWORD usage = 0; if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) - usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; + { + usage |= WINED3DUSAGE_LEGACY_CUBEMAP; + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; + } else if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - usage |= WINED3DUSAGE_TEXTURE; + { + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; + } if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) - usage = WINED3DUSAGE_DEPTHSTENCIL; + bind_flags |= WINED3D_BIND_DEPTH_STENCIL; else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) - usage = WINED3DUSAGE_RENDERTARGET; + bind_flags |= WINED3D_BIND_RENDER_TARGET; - if (SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, usage, WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) + if (!(ddraw->flags & DDRAW_NO3D) && SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, + WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, mode.format_id, + usage, bind_flags, WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; else desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; @@ -6113,34 +6199,20 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) { - /* - * The ddraw RGB device allows to use system memory surfaces as rendering target. - * This does not cause problems because the RGB device does software rasterization - * though it will fail with hardware accelerated ddraw. In order to be partially - * compatible with games requesting explicitly the RGB device, we ignore the - * specified location and try to create rendering targets in video memory if - * possible. - */ - if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && - SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_RENDERTARGET, - WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) - { - FIXME("Application wants to create rendering target in system memory, using video memory instead\n"); - wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET; - } - else - wined3d_desc.access = WINED3D_RESOURCE_ACCESS_CPU + wined3d_desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; } else { - if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - wined3d_desc.usage |= WINED3DUSAGE_TEXTURE; - if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) - wined3d_desc.usage |= WINED3DUSAGE_DEPTHSTENCIL; - else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) - wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET; + if (!(ddraw->flags & DDRAW_NO3D)) + { + if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + wined3d_desc.bind_flags |= WINED3D_BIND_SHADER_RESOURCE; + if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + wined3d_desc.bind_flags |= WINED3D_BIND_DEPTH_STENCIL; + else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + wined3d_desc.bind_flags |= WINED3D_BIND_RENDER_TARGET; + } if (desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)) { @@ -6154,7 +6226,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ /* Videomemory adds localvidmem. This is mutually exclusive with * systemmemory and texturemanage. */ desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; - wined3d_desc.usage |= WINED3DUSAGE_DYNAMIC; + /* Dynamic resources can't be written by the GPU. */ + if (!(wined3d_desc.bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL))) + wined3d_desc.usage |= WINED3DUSAGE_DYNAMIC; } } @@ -6241,6 +6315,13 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ return DDERR_NOCOLORKEYHW; } + if ((ddraw->flags & DDRAW_NO3D) && (desc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Video memory surfaces not supported without 3D support.\n"); + heap_free(texture); + return DDERR_NODIRECTDRAWHW; + } + if (desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY)) wined3d_desc.usage |= WINED3DUSAGE_OVERLAY; @@ -6295,6 +6376,8 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ { mip = wined3d_texture_get_sub_resource_parent(wined3d_texture, i * levels + j); mip_desc = &mip->surface_desc; + if (desc->ddsCaps.dwCaps & DDSCAPS_MIPMAP) + mip_desc->u2.dwMipMapCount = levels - j; if (j) { @@ -6413,7 +6496,10 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ } if (surface_desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { ddraw->primary = root; + ddraw->gdi_surface = root->wined3d_texture; + } *surface = root; return DD_OK; diff --git a/dll/directx/wine/ddraw/utils.c b/dll/directx/wine/ddraw/utils.c index b0a028d4a57..2aa4cc2e88e 100644 --- a/dll/directx/wine/ddraw/utils.c +++ b/dll/directx/wine/ddraw/utils.c @@ -21,9 +21,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); diff --git a/dll/directx/wine/ddraw/vertexbuffer.c b/dll/directx/wine/ddraw/vertexbuffer.c index 3ad8f7e1bdd..9df386d1a07 100644 --- a/dll/directx/wine/ddraw/vertexbuffer.c +++ b/dll/directx/wine/ddraw/vertexbuffer.c @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -119,8 +116,6 @@ static HRESULT d3d_vertex_buffer_create_wined3d_buffer(struct d3d_vertex_buffer desc.byte_width = buffer->size; desc.usage = WINED3DUSAGE_STATICDECL; - if (buffer->Caps & D3DVBCAPS_WRITEONLY) - desc.usage |= WINED3DUSAGE_WRITEONLY; if (dynamic) desc.usage |= WINED3DUSAGE_DYNAMIC; desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; @@ -262,7 +257,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 struct d3d_device *device_impl = dst_buffer_impl->version == 7 ? unsafe_impl_from_IDirect3DDevice7(device) : unsafe_impl_from_IDirect3DDevice3((IDirect3DDevice3 *)device); - BOOL oldClip, doClip; + BOOL old_clip, do_clip, old_lighting, do_lighting; HRESULT hr; TRACE("iface %p, vertex_op %#x, dst_idx %u, count %u, src_buffer %p, src_idx %u, device %p, flags %#x.\n", @@ -287,10 +282,20 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 * render states instead. Set the render states according to * the vertex ops */ - doClip = !!(vertex_op & D3DVOP_CLIP); - oldClip = wined3d_device_get_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING); - if (doClip != oldClip) - wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, doClip); + do_clip = !!(vertex_op & D3DVOP_CLIP); + old_clip = !!wined3d_device_get_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING); + if (do_clip != old_clip) + wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, do_clip); + + old_lighting = !!wined3d_device_get_render_state(device_impl->wined3d_device, WINED3D_RS_LIGHTING); + if (dst_buffer_impl->version == 3) + do_lighting = device_impl->material && (src_buffer_impl->fvf & D3DFVF_NORMAL) + && (vertex_op & D3DVOP_LIGHT); + else + do_lighting = old_lighting && (vertex_op & D3DVOP_LIGHT); + + if (do_lighting != old_lighting) + wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_LIGHTING, do_lighting); wined3d_device_set_stream_source(device_impl->wined3d_device, 0, src_buffer_impl->wined3d_buffer, 0, get_flexible_vertex_size(src_buffer_impl->fvf)); @@ -299,8 +304,10 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 count, dst_buffer_impl->wined3d_buffer, NULL, flags, dst_buffer_impl->fvf); /* Restore the states if needed */ - if (doClip != oldClip) - wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, oldClip); + if (do_clip != old_clip) + wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, old_clip); + if (do_lighting != old_lighting) + wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_LIGHTING, old_lighting); wined3d_mutex_unlock(); diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c index 6ef3226c4d1..ab6bada2da6 100644 --- a/dll/directx/wine/ddraw/viewport.c +++ b/dll/directx/wine/ddraw/viewport.c @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "ddraw_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -68,8 +65,14 @@ void viewport_activate(struct d3d_viewport *This, BOOL ignore_lights) } } + if (This->version == DDRAW_VIEWPORT_VERSION_NONE) + { + TRACE("Viewport data was not set.\n"); + return; + } + /* And copy the values in the structure used by the device */ - if (This->use_vp2) + if (This->version == DDRAW_VIEWPORT_VERSION_2) { vp.dwX = This->viewports.vp2.dwX; vp.dwY = This->viewports.vp2.dwY; @@ -106,6 +109,72 @@ void viewport_activate(struct d3d_viewport *This, BOOL ignore_lights) IDirect3DDevice7_SetViewport(&This->active_device->IDirect3DDevice7_iface, &vp); } +void viewport_deactivate(struct d3d_viewport *viewport) +{ + struct d3d_light *light; + + LIST_FOR_EACH_ENTRY(light, &viewport->light_list, struct d3d_light, entry) + { + light_deactivate(light); + } +} + +void viewport_alloc_active_light_index(struct d3d_light *light) +{ + struct d3d_viewport *vp = light->active_viewport; + unsigned int i; + DWORD map; + + TRACE("vp %p, light %p, index %u, active_lights_count %u.\n", + vp, light, light->active_light_index, vp->active_lights_count); + + if (light->active_light_index) + return; + + if (vp->active_lights_count >= DDRAW_MAX_ACTIVE_LIGHTS) + { + struct d3d_light *l; + + LIST_FOR_EACH_ENTRY(l, &vp->light_list, struct d3d_light, entry) + { + if (l->active_light_index) + { + WARN("Too many active lights, viewport %p, light %p, deactivating %p.\n", vp, light, l); + light_deactivate(l); + + /* Recycle active lights in a FIFO way. */ + list_remove(&light->entry); + list_add_tail(&vp->light_list, &light->entry); + break; + } + } + } + + map = ~vp->map_lights; + assert(vp->active_lights_count < DDRAW_MAX_ACTIVE_LIGHTS && map); + i = wined3d_bit_scan(&map); + light->active_light_index = i + 1; + ++vp->active_lights_count; + vp->map_lights |= 1u << i; +} + +void viewport_free_active_light_index(struct d3d_light *light) +{ + struct d3d_viewport *vp = light->active_viewport; + + TRACE("vp %p, light %p, index %u, active_lights_count %u, map_lights %#x.\n", + vp, light, light->active_light_index, vp->active_lights_count, vp->map_lights); + + if (!light->active_light_index) + return; + + assert(vp->map_lights & (1u << (light->active_light_index - 1))); + + --vp->active_lights_count; + vp->map_lights &= ~(1u << (light->active_light_index - 1)); + light->active_light_index = 0; +} + /***************************************************************************** * _dump_D3DVIEWPORT, _dump_D3DVIEWPORT2 * @@ -249,109 +318,129 @@ static HRESULT WINAPI d3d_viewport_Initialize(IDirect3DViewport3 *iface, IDirect return DDERR_ALREADYINITIALIZED; } -/***************************************************************************** - * IDirect3DViewport3::GetViewport - * - * Returns the viewport data assigned to this viewport interface - * - * Params: - * Data: Address to store the data - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData) +static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp) { - struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); - DWORD dwSize; + struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); + DWORD size; - TRACE("iface %p, data %p.\n", iface, lpData); + TRACE("iface %p, vp %p.\n", iface, vp); + + if (!vp) + return DDERR_INVALIDPARAMS; + + if (viewport->version == DDRAW_VIEWPORT_VERSION_NONE) + { + WARN("Viewport data was not set.\n"); + return D3DERR_VIEWPORTDATANOTSET; + } wined3d_mutex_lock(); - dwSize = lpData->dwSize; - if (!This->use_vp2) - memcpy(lpData, &(This->viewports.vp1), dwSize); - else { + size = vp->dwSize; + if (viewport->version == DDRAW_VIEWPORT_VERSION_1) + { + memcpy(vp, &viewport->viewports.vp1, size); + } + else + { D3DVIEWPORT vp1; + vp1.dwSize = sizeof(vp1); - vp1.dwX = This->viewports.vp2.dwX; - vp1.dwY = This->viewports.vp2.dwY; - vp1.dwWidth = This->viewports.vp2.dwWidth; - vp1.dwHeight = This->viewports.vp2.dwHeight; - vp1.dvMaxX = 0.0; - vp1.dvMaxY = 0.0; - vp1.dvScaleX = 0.0; - vp1.dvScaleY = 0.0; - vp1.dvMinZ = This->viewports.vp2.dvMinZ; - vp1.dvMaxZ = This->viewports.vp2.dvMaxZ; - memcpy(lpData, &vp1, dwSize); + vp1.dwX = viewport->viewports.vp2.dwX; + vp1.dwY = viewport->viewports.vp2.dwY; + vp1.dwWidth = viewport->viewports.vp2.dwWidth; + vp1.dwHeight = viewport->viewports.vp2.dwHeight; + vp1.dvMaxX = 0.0f; + vp1.dvMaxY = 0.0f; + vp1.dvScaleX = 0.0f; + vp1.dvScaleY = 0.0f; + vp1.dvMinZ = viewport->viewports.vp2.dvMinZ; + vp1.dvMaxZ = viewport->viewports.vp2.dvMaxZ; + memcpy(vp, &vp1, size); } if (TRACE_ON(ddraw)) { TRACE(" returning D3DVIEWPORT :\n"); - _dump_D3DVIEWPORT(lpData); + _dump_D3DVIEWPORT(vp); } wined3d_mutex_unlock(); - return DD_OK; + return D3D_OK; } -/***************************************************************************** - * IDirect3DViewport3::SetViewport - * - * Sets the viewport information for this interface - * - * Params: - * lpData: Viewport to set - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData) +static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp) { - struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); + struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); + struct d3d_device *device = viewport->active_device; + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; IDirect3DViewport3 *current_viewport; + struct ddraw_surface *surface; - TRACE("iface %p, data %p.\n", iface, lpData); + TRACE("iface %p, vp %p.\n", iface, vp); + + if (!vp) + return DDERR_INVALIDPARAMS; + + if (vp->dwSize != sizeof(*vp)) + { + WARN("Invalid D3DVIEWPORT size %u.\n", vp->dwSize); + return DDERR_INVALIDPARAMS; + } if (TRACE_ON(ddraw)) { TRACE(" getting D3DVIEWPORT :\n"); - _dump_D3DVIEWPORT(lpData); + _dump_D3DVIEWPORT(vp); } - wined3d_mutex_lock(); - - This->use_vp2 = 0; - memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1)); - memcpy(&(This->viewports.vp1), lpData, lpData->dwSize); + if (!device) + { + WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n"); + return D3DERR_VIEWPORTHASNODEVICE; + } - /* Tests on two games show that these values are never used properly so override - them with proper ones :-) - */ - This->viewports.vp1.dvMinZ = 0.0; - This->viewports.vp1.dvMaxZ = 1.0; + wined3d_mutex_lock(); - if (This->active_device) + if (device->version > 1) { - IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface; - if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, ¤t_viewport))) + if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + { + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); + + if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX + || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY) { - if (current_viewport == iface) viewport_activate(This, FALSE); - IDirect3DViewport3_Release(current_viewport); + WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n"); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; } } + viewport->version = DDRAW_VIEWPORT_VERSION_1; + viewport->viewports.vp1 = *vp; + + /* Empirical testing on a couple of d3d1 games showed that these values + * should be ignored. */ + viewport->viewports.vp1.dvMinZ = 0.0f; + viewport->viewports.vp1.dvMaxZ = 1.0f; + + if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) + { + if (current_viewport == iface) + viewport_activate(viewport, FALSE); + IDirect3DViewport3_Release(current_viewport); + } + wined3d_mutex_unlock(); - return DD_OK; + return D3D_OK; } /***************************************************************************** @@ -717,47 +806,29 @@ static HRESULT WINAPI d3d_viewport_Clear(IDirect3DViewport3 *iface, * DDERR_INVALIDPARAMS if there are 8 lights or more * *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_AddLight(IDirect3DViewport3 *iface, IDirect3DLight *lpDirect3DLight) +static HRESULT WINAPI d3d_viewport_AddLight(IDirect3DViewport3 *viewport, IDirect3DLight *light) { - struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); - struct d3d_light *light_impl = unsafe_impl_from_IDirect3DLight(lpDirect3DLight); - DWORD i = 0; - DWORD map = This->map_lights; + struct d3d_light *light_impl = unsafe_impl_from_IDirect3DLight(light); + struct d3d_viewport *vp = impl_from_IDirect3DViewport3(viewport); - TRACE("iface %p, light %p.\n", iface, lpDirect3DLight); + TRACE("viewport %p, light %p.\n", viewport, light); wined3d_mutex_lock(); - if (This->num_lights >= 8) + if (light_impl->active_viewport) { wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + WARN("Light %p is active in viewport %p.\n", light_impl, light_impl->active_viewport); + return D3DERR_LIGHTHASVIEWPORT; } - /* Find a light number and update both light and viewports objects accordingly */ - while (map & 1) - { - map >>= 1; - ++i; - } - light_impl->dwLightIndex = i; - This->num_lights++; - This->map_lights |= 1<active_viewport = vp; /* Add the light in the 'linked' chain */ - list_add_head(&This->light_list, &light_impl->entry); - IDirect3DLight_AddRef(lpDirect3DLight); + list_add_tail(&vp->light_list, &light_impl->entry); + IDirect3DLight_AddRef(light); - /* Attach the light to the viewport */ - light_impl->active_viewport = This; - - /* If active, activate the light */ - if (This->active_device && light_impl->light.dwFlags & D3DLIGHT_ACTIVE) - { - /* Disable the flag so that light_activate actually does its job. */ - light_impl->light.dwFlags &= ~D3DLIGHT_ACTIVE; - light_activate(light_impl); - } + light_activate(light_impl); wined3d_mutex_unlock(); @@ -797,8 +868,6 @@ static HRESULT WINAPI d3d_viewport_DeleteLight(IDirect3DViewport3 *iface, IDirec list_remove(&l->entry); l->active_viewport = NULL; IDirect3DLight_Release(lpDirect3DLight); - --viewport->num_lights; - viewport->map_lights &= ~(1 << l->dwLightIndex); wined3d_mutex_unlock(); @@ -882,53 +951,50 @@ static HRESULT WINAPI d3d_viewport_NextLight(IDirect3DViewport3 *iface, * IDirect3DViewport2 Methods. *****************************************************************************/ -/***************************************************************************** - * IDirect3DViewport3::GetViewport2 - * - * Returns the currently set viewport in a D3DVIEWPORT2 structure. - * Similar to IDirect3DViewport3::GetViewport - * - * Params: - * lpData: Pointer to the structure to fill - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if the viewport was set with - * IDirect3DViewport3::SetViewport - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData) +static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp) { - struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); - DWORD dwSize; + struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); + DWORD size; - TRACE("iface %p, data %p.\n", iface, lpData); + TRACE("iface %p, vp %p.\n", iface, vp); + + if (!vp) + return DDERR_INVALIDPARAMS; + + if (viewport->version == DDRAW_VIEWPORT_VERSION_NONE) + { + WARN("Viewport data was not set.\n"); + return D3DERR_VIEWPORTDATANOTSET; + } wined3d_mutex_lock(); - dwSize = lpData->dwSize; - if (This->use_vp2) - memcpy(lpData, &(This->viewports.vp2), dwSize); - else { + size = vp->dwSize; + if (viewport->version == DDRAW_VIEWPORT_VERSION_2) + { + memcpy(vp, &viewport->viewports.vp2, size); + } + else + { D3DVIEWPORT2 vp2; + vp2.dwSize = sizeof(vp2); - vp2.dwX = This->viewports.vp1.dwX; - vp2.dwY = This->viewports.vp1.dwY; - vp2.dwWidth = This->viewports.vp1.dwWidth; - vp2.dwHeight = This->viewports.vp1.dwHeight; - vp2.dvClipX = 0.0; - vp2.dvClipY = 0.0; - vp2.dvClipWidth = 0.0; - vp2.dvClipHeight = 0.0; - vp2.dvMinZ = This->viewports.vp1.dvMinZ; - vp2.dvMaxZ = This->viewports.vp1.dvMaxZ; - memcpy(lpData, &vp2, dwSize); + vp2.dwX = viewport->viewports.vp1.dwX; + vp2.dwY = viewport->viewports.vp1.dwY; + vp2.dwWidth = viewport->viewports.vp1.dwWidth; + vp2.dwHeight = viewport->viewports.vp1.dwHeight; + vp2.dvClipX = 0.0f; + vp2.dvClipY = 0.0f; + vp2.dvClipWidth = 0.0f; + vp2.dvClipHeight = 0.0f; + vp2.dvMinZ = viewport->viewports.vp1.dvMinZ; + vp2.dvMaxZ = viewport->viewports.vp1.dvMaxZ; + memcpy(vp, &vp2, size); } if (TRACE_ON(ddraw)) { TRACE(" returning D3DVIEWPORT2 :\n"); - _dump_D3DVIEWPORT2(lpData); + _dump_D3DVIEWPORT2(vp); } wined3d_mutex_unlock(); @@ -936,45 +1002,67 @@ static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVI return D3D_OK; } -/***************************************************************************** - * IDirect3DViewport3::SetViewport2 - * - * Sets the viewport from a D3DVIEWPORT2 structure - * - * Params: - * lpData: Viewport to set - * - * Returns: - * D3D_OK on success - * - *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData) +static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp) { - struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); + struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); + struct d3d_device *device = viewport->active_device; + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; IDirect3DViewport3 *current_viewport; + struct ddraw_surface *surface; + + TRACE("iface %p, vp %p.\n", iface, vp); - TRACE("iface %p, data %p.\n", iface, lpData); + if (!vp) + return DDERR_INVALIDPARAMS; + + if (vp->dwSize != sizeof(*vp)) + { + WARN("Invalid D3DVIEWPORT2 size %u.\n", vp->dwSize); + return DDERR_INVALIDPARAMS; + } if (TRACE_ON(ddraw)) { TRACE(" getting D3DVIEWPORT2 :\n"); - _dump_D3DVIEWPORT2(lpData); + _dump_D3DVIEWPORT2(vp); } - wined3d_mutex_lock(); + if (!device) + { + WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n"); + return D3DERR_VIEWPORTHASNODEVICE; + } - This->use_vp2 = 1; - memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2)); - memcpy(&(This->viewports.vp2), lpData, lpData->dwSize); + wined3d_mutex_lock(); - if (This->active_device) + if (device->version > 1) { - IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface; - if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, ¤t_viewport))) + if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) { - if (current_viewport == iface) viewport_activate(This, FALSE); - IDirect3DViewport3_Release(current_viewport); + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; } + surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); + + if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX + || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY) + { + WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n"); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + } + + viewport->version = DDRAW_VIEWPORT_VERSION_2; + viewport->viewports.vp2 = *vp; + + if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) + { + if (current_viewport == iface) + viewport_activate(viewport, FALSE); + IDirect3DViewport3_Release(current_viewport); } wined3d_mutex_unlock(); @@ -1148,6 +1236,6 @@ void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) viewport->IDirect3DViewport3_iface.lpVtbl = &d3d_viewport_vtbl; viewport->ref = 1; viewport->ddraw = ddraw; - viewport->use_vp2 = 0xff; + viewport->version = DDRAW_VIEWPORT_VERSION_NONE; list_init(&viewport->light_list); } diff --git a/dll/directx/wine/dxgi/CMakeLists.txt b/dll/directx/wine/dxgi/CMakeLists.txt new file mode 100644 index 00000000000..343364d123e --- /dev/null +++ b/dll/directx/wine/dxgi/CMakeLists.txt @@ -0,0 +1,32 @@ + + +add_definitions( + -D__WINESRC__) + +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/psdk) + +spec2def(dxgi.dll dxgi.spec ADD_IMPORTLIB) + +add_library(dxgi MODULE + version.rc + adapter.c + dxgi_main.c + factory.c + output.c + surface.c + swapchain.c + device.c + utils.c + ${CMAKE_CURRENT_BINARY_DIR}/dxgi_stubs.c + ${CMAKE_CURRENT_BINARY_DIR}/dxgi.def) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(dxgi PRIVATE -Wno-sequence-point -Wno-unused-function -Wno-unused-but-set-variable -Wno-error) # Our favourite compiler :) +endif() + +set_module_type(dxgi win32dll) +target_link_libraries(dxgi dxguid uuid wine) +add_importlibs(dxgi advapi32 gdi32 user32 d3dwine msvcrt kernel32 ntdll) +add_dependencies(dxgi wineheaders d3d_idl_headers) +add_cd_file(TARGET dxgi DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/dxgi/adapter.c b/dll/directx/wine/dxgi/adapter.c new file mode 100644 index 00000000000..d2fc629c843 --- /dev/null +++ b/dll/directx/wine/dxgi/adapter.c @@ -0,0 +1,463 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_adapter *impl_from_IWineDXGIAdapter(IWineDXGIAdapter *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_adapter, IWineDXGIAdapter_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryInterface(IWineDXGIAdapter *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IWineDXGIAdapter) + || IsEqualGUID(iid, &IID_IDXGIAdapter4) + || IsEqualGUID(iid, &IID_IDXGIAdapter3) + || IsEqualGUID(iid, &IID_IDXGIAdapter2) + || IsEqualGUID(iid, &IID_IDXGIAdapter1) + || IsEqualGUID(iid, &IID_IDXGIAdapter) + || IsEqualGUID(iid, &IID_IDXGIObject) + || IsEqualGUID(iid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_adapter_AddRef(IWineDXGIAdapter *iface) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + ULONG refcount = InterlockedIncrement(&adapter->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IWineDXGIAdapter *iface) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + ULONG refcount = InterlockedDecrement(&adapter->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&adapter->private_store); + IWineDXGIFactory_Release(&adapter->factory->IWineDXGIFactory_iface); + heap_free(adapter); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetPrivateData(IWineDXGIAdapter *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&adapter->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetPrivateDataInterface(IWineDXGIAdapter *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&adapter->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetPrivateData(IWineDXGIAdapter *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&adapter->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetParent(IWineDXGIAdapter *iface, REFIID iid, void **parent) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, iid %s, parent %p.\n", iface, debugstr_guid(iid), parent); + + return IWineDXGIFactory_QueryInterface(&adapter->factory->IWineDXGIFactory_iface, iid, parent); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IWineDXGIAdapter *iface, + UINT output_idx, IDXGIOutput **output) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + struct dxgi_output *output_object; + HRESULT hr; + + TRACE("iface %p, output_idx %u, output %p.\n", iface, output_idx, output); + + if (output_idx > 0) + { + *output = NULL; + return DXGI_ERROR_NOT_FOUND; + } + + if (FAILED(hr = dxgi_output_create(adapter, &output_object))) + { + *output = NULL; + return hr; + } + + *output = (IDXGIOutput *)&output_object->IDXGIOutput4_iface; + + TRACE("Returning output %p.\n", *output); + + return S_OK; +} + +static HRESULT dxgi_adapter_get_desc(struct dxgi_adapter *adapter, DXGI_ADAPTER_DESC3 *desc) +{ + char description[ARRAY_SIZE(desc->Description)]; + struct wined3d_adapter_identifier adapter_id; + HRESULT hr; + + adapter_id.driver_size = 0; + adapter_id.description = description; + adapter_id.description_size = sizeof(description); + adapter_id.device_name_size = 0; + + if (FAILED(hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id))) + return hr; + + if (!MultiByteToWideChar(CP_ACP, 0, description, -1, desc->Description, ARRAY_SIZE(description))) + { + DWORD err = GetLastError(); + ERR("Failed to translate description %s (%#x).\n", debugstr_a(description), err); + hr = E_FAIL; + } + + desc->VendorId = adapter_id.vendor_id; + desc->DeviceId = adapter_id.device_id; + desc->SubSysId = adapter_id.subsystem_id; + desc->Revision = adapter_id.revision; + desc->DedicatedVideoMemory = adapter_id.video_memory; + desc->DedicatedSystemMemory = 0; /* FIXME */ + desc->SharedSystemMemory = adapter_id.shared_system_memory; + desc->AdapterLuid = adapter_id.adapter_luid; + desc->Flags = 0; + desc->GraphicsPreemptionGranularity = 0; /* FIXME */ + desc->ComputePreemptionGranularity = 0; /* FIXME */ + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC *desc) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + DXGI_ADAPTER_DESC3 desc3; + HRESULT hr; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + return E_INVALIDARG; + + if (SUCCEEDED(hr = dxgi_adapter_get_desc(adapter, &desc3))) + memcpy(desc, &desc3, sizeof(*desc)); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IWineDXGIAdapter *iface, + REFGUID guid, LARGE_INTEGER *umd_version) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + struct wined3d_adapter_identifier adapter_id; + struct wined3d_caps caps; + struct wined3d *wined3d; + HRESULT hr; + + TRACE("iface %p, guid %s, umd_version %p.\n", iface, debugstr_guid(guid), umd_version); + + /* This method works only for D3D10 interfaces. */ + if (!(IsEqualGUID(guid, &IID_IDXGIDevice) + || IsEqualGUID(guid, &IID_ID3D10Device) + || IsEqualGUID(guid, &IID_ID3D10Device1))) + { + WARN("Returning DXGI_ERROR_UNSUPPORTED for %s.\n", debugstr_guid(guid)); + return DXGI_ERROR_UNSUPPORTED; + } + + adapter_id.driver_size = 0; + adapter_id.description_size = 0; + adapter_id.device_name_size = 0; + + wined3d_mutex_lock(); + wined3d = adapter->factory->wined3d; + hr = wined3d_get_device_caps(wined3d, adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, &caps); + if (SUCCEEDED(hr)) + hr = wined3d_get_adapter_identifier(wined3d, adapter->ordinal, 0, &adapter_id); + wined3d_mutex_unlock(); + + if (FAILED(hr)) + return hr; + if (caps.max_feature_level < WINED3D_FEATURE_LEVEL_10) + return DXGI_ERROR_UNSUPPORTED; + + if (umd_version) + *umd_version = adapter_id.driver_version; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc1(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC1 *desc) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + DXGI_ADAPTER_DESC3 desc3; + HRESULT hr; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + return E_INVALIDARG; + + if (SUCCEEDED(hr = dxgi_adapter_get_desc(adapter, &desc3))) + memcpy(desc, &desc3, sizeof(*desc)); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc2(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC2 *desc) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + DXGI_ADAPTER_DESC3 desc3; + HRESULT hr; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + return E_INVALIDARG; + + if (SUCCEEDED(hr = dxgi_adapter_get_desc(adapter, &desc3))) + memcpy(desc, &desc3, sizeof(*desc)); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_RegisterHardwareContentProtectionTeardownStatusEvent( + IWineDXGIAdapter *iface, HANDLE event, DWORD *cookie) +{ + FIXME("iface %p, event %p, cookie %p stub!\n", iface, event, cookie); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_adapter_UnregisterHardwareContentProtectionTeardownStatus( + IWineDXGIAdapter *iface, DWORD cookie) +{ + FIXME("iface %p, cookie %#x stub!\n", iface, cookie); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryVideoMemoryInfo(IWineDXGIAdapter *iface, + UINT node_index, DXGI_MEMORY_SEGMENT_GROUP segment_group, DXGI_QUERY_VIDEO_MEMORY_INFO *info) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + struct wined3d_adapter_identifier adapter_id; + static unsigned int once; + HRESULT hr; + + TRACE("iface %p, node_index %u, segment_group %#x, info %p.\n", + iface, node_index, segment_group, info); + + if (!once++) + FIXME("Returning fake video memory info.\n"); + + if (node_index) + FIXME("Ignoring node index %u.\n", node_index); + + adapter_id.driver_size = 0; + adapter_id.description_size = 0; + adapter_id.device_name_size = 0; + + if (FAILED(hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id))) + return hr; + + switch (segment_group) + { + case DXGI_MEMORY_SEGMENT_GROUP_LOCAL: + info->Budget = adapter_id.video_memory; + info->CurrentUsage = 0; + info->AvailableForReservation = adapter_id.video_memory / 2; + info->CurrentReservation = 0; + break; + case DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL: + memset(info, 0, sizeof(*info)); + break; + default: + WARN("Invalid memory segment group %#x.\n", segment_group); + return E_INVALIDARG; + } + + TRACE("Budget 0x%s, usage 0x%s, available for reservation 0x%s, reservation 0x%s.\n", + wine_dbgstr_longlong(info->Budget), wine_dbgstr_longlong(info->CurrentUsage), + wine_dbgstr_longlong(info->AvailableForReservation), wine_dbgstr_longlong(info->CurrentReservation)); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetVideoMemoryReservation(IWineDXGIAdapter *iface, + UINT node_index, DXGI_MEMORY_SEGMENT_GROUP segment_group, UINT64 reservation) +{ + FIXME("iface %p, node_index %u, segment_group %#x, reservation 0x%s stub!\n", + iface, node_index, segment_group, wine_dbgstr_longlong(reservation)); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_RegisterVideoMemoryBudgetChangeNotificationEvent( + IWineDXGIAdapter *iface, HANDLE event, DWORD *cookie) +{ + FIXME("iface %p, event %p, cookie %p stub!\n", iface, event, cookie); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_adapter_UnregisterVideoMemoryBudgetChangeNotification( + IWineDXGIAdapter *iface, DWORD cookie) +{ + FIXME("iface %p, cookie %#x stub!\n", iface, cookie); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc3(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC3 *desc) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + return E_INVALIDARG; + + return dxgi_adapter_get_desc(adapter, desc); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_get_adapter_info(IWineDXGIAdapter *iface, + struct wine_dxgi_adapter_info *info) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + struct wined3d_adapter_identifier adapter_id; + HRESULT hr; + + TRACE("iface %p, info %p.\n", iface, info); + + memset(&adapter_id, 0, sizeof(adapter_id)); + if (SUCCEEDED(hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id))) + { + info->driver_uuid = adapter_id.driver_uuid; + info->device_uuid = adapter_id.device_uuid; + info->vendor_id = adapter_id.vendor_id; + info->device_id = adapter_id.device_id; + info->luid = adapter_id.adapter_luid; + } + + return hr; +} + +static const struct IWineDXGIAdapterVtbl dxgi_adapter_vtbl = +{ + dxgi_adapter_QueryInterface, + dxgi_adapter_AddRef, + dxgi_adapter_Release, + dxgi_adapter_SetPrivateData, + dxgi_adapter_SetPrivateDataInterface, + dxgi_adapter_GetPrivateData, + dxgi_adapter_GetParent, + /* IDXGIAdapter methods */ + dxgi_adapter_EnumOutputs, + dxgi_adapter_GetDesc, + dxgi_adapter_CheckInterfaceSupport, + /* IDXGIAdapter1 methods */ + dxgi_adapter_GetDesc1, + /* IDXGIAdapter2 methods */ + dxgi_adapter_GetDesc2, + /* IDXGIAdapter3 methods */ + dxgi_adapter_RegisterHardwareContentProtectionTeardownStatusEvent, + dxgi_adapter_UnregisterHardwareContentProtectionTeardownStatus, + dxgi_adapter_QueryVideoMemoryInfo, + dxgi_adapter_SetVideoMemoryReservation, + dxgi_adapter_RegisterVideoMemoryBudgetChangeNotificationEvent, + dxgi_adapter_UnregisterVideoMemoryBudgetChangeNotification, + /* IDXGIAdapter4 methods */ + dxgi_adapter_GetDesc3, + /* IWineDXGIAdapter methods */ + dxgi_adapter_get_adapter_info, +}; + +struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) +{ + IWineDXGIAdapter *wine_adapter; + struct dxgi_adapter *adapter; + HRESULT hr; + + if (!iface) + return NULL; + if (FAILED(hr = IDXGIAdapter_QueryInterface(iface, &IID_IWineDXGIAdapter, (void **)&wine_adapter))) + { + ERR("Failed to get IWineDXGIAdapter interface, hr %#x.\n", hr); + return NULL; + } + assert(wine_adapter->lpVtbl == &dxgi_adapter_vtbl); + adapter = CONTAINING_RECORD(wine_adapter, struct dxgi_adapter, IWineDXGIAdapter_iface); + IWineDXGIAdapter_Release(wine_adapter); + return adapter; +} + +static void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *factory, UINT ordinal) +{ + adapter->IWineDXGIAdapter_iface.lpVtbl = &dxgi_adapter_vtbl; + adapter->refcount = 1; + wined3d_private_store_init(&adapter->private_store); + adapter->ordinal = ordinal; + adapter->factory = factory; + IWineDXGIFactory_AddRef(&adapter->factory->IWineDXGIFactory_iface); +} + +HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal, struct dxgi_adapter **adapter) +{ + if (!(*adapter = heap_alloc(sizeof(**adapter)))) + return E_OUTOFMEMORY; + + dxgi_adapter_init(*adapter, factory, ordinal); + return S_OK; +} diff --git a/dll/directx/wine/dxgi/device.c b/dll/directx/wine/dxgi/device.c new file mode 100644 index 00000000000..4b23155754d --- /dev/null +++ b/dll/directx/wine/dxgi/device.c @@ -0,0 +1,569 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_device *impl_from_IWineDXGIDevice(IWineDXGIDevice *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_device, IWineDXGIDevice_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IWineDXGIDevice *iface, REFIID riid, void **object) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IDXGIDevice) + || IsEqualGUID(riid, &IID_IDXGIDevice1) + || IsEqualGUID(riid, &IID_IDXGIDevice2) + || IsEqualGUID(riid, &IID_IDXGIDevice3) + || IsEqualGUID(riid, &IID_IWineDXGIDevice)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + if (IsEqualGUID(riid, &IID_IWineDXGISwapChainFactory)) + { + IUnknown_AddRef(iface); + *object = &device->IWineDXGISwapChainFactory_iface; + return S_OK; + } + + if (device->child_layer) + { + TRACE("Forwarding to child layer %p.\n", device->child_layer); + return IUnknown_QueryInterface(device->child_layer, riid, object); + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IWineDXGIDevice *iface) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + ULONG refcount = InterlockedIncrement(&device->refcount); + + TRACE("%p increasing refcount to %u\n", device, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_device_Release(IWineDXGIDevice *iface) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + ULONG refcount = InterlockedDecrement(&device->refcount); + + TRACE("%p decreasing refcount to %u.\n", device, refcount); + + if (!refcount) + { + if (device->child_layer) + IUnknown_Release(device->child_layer); + wined3d_mutex_lock(); + wined3d_swapchain_decref(device->implicit_swapchain); + wined3d_device_decref(device->wined3d_device); + wined3d_mutex_unlock(); + IWineDXGIAdapter_Release(device->adapter); + wined3d_private_store_cleanup(&device->private_store); + heap_free(device); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateData(IWineDXGIDevice *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&device->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateDataInterface(IWineDXGIDevice *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&device->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetPrivateData(IWineDXGIDevice *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&device->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetParent(IWineDXGIDevice *iface, REFIID riid, void **parent) +{ + IDXGIAdapter *adapter; + HRESULT hr; + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + hr = IWineDXGIDevice_GetAdapter(iface, &adapter); + if (FAILED(hr)) + { + ERR("Failed to get adapter, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIAdapter_QueryInterface(adapter, riid, parent); + IDXGIAdapter_Release(adapter); + + return hr; +} + +/* IDXGIDevice methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetAdapter(IWineDXGIDevice *iface, IDXGIAdapter **adapter) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, adapter %p.\n", iface, adapter); + + *adapter = (IDXGIAdapter *)device->adapter; + IDXGIAdapter_AddRef(*adapter); + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *iface, + const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage, + const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface) +{ + struct wined3d_device_parent *device_parent; + struct wined3d_resource_desc surface_desc; + IWineDXGIDeviceParent *dxgi_device_parent; + HRESULT hr; + UINT i; + UINT j; + + TRACE("iface %p, desc %p, surface_count %u, usage %#x, shared_resource %p, surface %p.\n", + iface, desc, surface_count, usage, shared_resource, surface); + + hr = IWineDXGIDevice_QueryInterface(iface, &IID_IWineDXGIDeviceParent, (void **)&dxgi_device_parent); + if (FAILED(hr)) + { + ERR("Device should implement IWineDXGIDeviceParent.\n"); + return E_FAIL; + } + + device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); + + surface_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + surface_desc.format = wined3dformat_from_dxgi_format(desc->Format); + wined3d_sample_desc_from_dxgi(&surface_desc.multisample_type, + &surface_desc.multisample_quality, &desc->SampleDesc); + surface_desc.bind_flags = wined3d_bind_flags_from_dxgi_usage(usage); + surface_desc.usage = 0; + surface_desc.access = WINED3D_RESOURCE_ACCESS_GPU; + surface_desc.width = desc->Width; + surface_desc.height = desc->Height; + surface_desc.depth = 1; + surface_desc.size = 0; + + wined3d_mutex_lock(); + memset(surface, 0, surface_count * sizeof(*surface)); + for (i = 0; i < surface_count; ++i) + { + struct wined3d_texture *wined3d_texture; + IUnknown *parent; + + if (FAILED(hr = device_parent->ops->create_swapchain_texture(device_parent, + NULL, &surface_desc, 0, &wined3d_texture))) + { + ERR("Failed to create surface, hr %#x.\n", hr); + goto fail; + } + + parent = wined3d_texture_get_parent(wined3d_texture); + hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]); + wined3d_texture_decref(wined3d_texture); + if (FAILED(hr)) + { + ERR("Surface should implement IDXGISurface.\n"); + goto fail; + } + + TRACE("Created IDXGISurface %p (%u/%u).\n", surface[i], i + 1, surface_count); + } + wined3d_mutex_unlock(); + IWineDXGIDeviceParent_Release(dxgi_device_parent); + + return S_OK; + +fail: + wined3d_mutex_unlock(); + for (j = 0; j < i; ++j) + { + IDXGISurface_Release(surface[i]); + } + IWineDXGIDeviceParent_Release(dxgi_device_parent); + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_QueryResourceResidency(IWineDXGIDevice *iface, + IUnknown *const *resources, DXGI_RESIDENCY *residency, UINT resource_count) +{ + FIXME("iface %p, resources %p, residency %p, resource_count %u stub!\n", + iface, resources, residency, resource_count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetGPUThreadPriority(IWineDXGIDevice *iface, INT priority) +{ + FIXME("iface %p, priority %d stub!\n", iface, priority); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetGPUThreadPriority(IWineDXGIDevice *iface, INT *priority) +{ + FIXME("iface %p, priority %p stub!\n", iface, priority); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetMaximumFrameLatency(IWineDXGIDevice *iface, UINT max_latency) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, max_latency %u.\n", iface, max_latency); + + if (max_latency > DXGI_FRAME_LATENCY_MAX) + return DXGI_ERROR_INVALID_CALL; + + wined3d_mutex_lock(); + wined3d_device_set_max_frame_latency(device->wined3d_device, max_latency); + wined3d_mutex_unlock(); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetMaximumFrameLatency(IWineDXGIDevice *iface, UINT *max_latency) +{ + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, max_latency %p.\n", iface, max_latency); + + if (!max_latency) + return DXGI_ERROR_INVALID_CALL; + + wined3d_mutex_lock(); + *max_latency = wined3d_device_get_max_frame_latency(device->wined3d_device); + wined3d_mutex_unlock(); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_OfferResources(IWineDXGIDevice *iface, UINT resource_count, + IDXGIResource * const *resources, DXGI_OFFER_RESOURCE_PRIORITY priority) +{ + FIXME("iface %p, resource_count %u, resources %p, priority %u stub!\n", iface, resource_count, + resources, priority); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_ReclaimResources(IWineDXGIDevice *iface, UINT resource_count, + IDXGIResource * const *resources, BOOL *discarded) +{ + FIXME("iface %p, resource_count %u, resources %p, discarded %p stub!\n", iface, resource_count, + resources, discarded); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_EnqueueSetEvent(IWineDXGIDevice *iface, HANDLE event) +{ + FIXME("iface %p, event %p stub!\n", iface, event); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_device_Trim(IWineDXGIDevice *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +/* IWineDXGIDevice methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *iface, + struct wined3d_texture *wined3d_texture, DXGI_USAGE usage, + const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, void **surface) +{ + struct dxgi_surface *object; + HRESULT hr; + + TRACE("iface %p, wined3d_texture %p, usage %#x, shared_resource %p, outer %p, surface %p.\n", + iface, wined3d_texture, usage, shared_resource, outer, surface); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate DXGI surface object memory.\n"); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = dxgi_surface_init(object, (IDXGIDevice *)iface, outer, wined3d_texture))) + { + WARN("Failed to initialize surface, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created IDXGISurface %p.\n", object); + *surface = outer ? &object->IUnknown_iface : (IUnknown *)&object->IDXGISurface1_iface; + + return S_OK; +} + +static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl = +{ + /* IUnknown methods */ + dxgi_device_QueryInterface, + dxgi_device_AddRef, + dxgi_device_Release, + /* IDXGIObject methods */ + dxgi_device_SetPrivateData, + dxgi_device_SetPrivateDataInterface, + dxgi_device_GetPrivateData, + dxgi_device_GetParent, + /* IDXGIDevice methods */ + dxgi_device_GetAdapter, + dxgi_device_CreateSurface, + dxgi_device_QueryResourceResidency, + dxgi_device_SetGPUThreadPriority, + dxgi_device_GetGPUThreadPriority, + /* IDXGIDevice1 methods */ + dxgi_device_SetMaximumFrameLatency, + dxgi_device_GetMaximumFrameLatency, + /* IDXGIDevice2 methods */ + dxgi_device_OfferResources, + dxgi_device_ReclaimResources, + dxgi_device_EnqueueSetEvent, + /* IDXGIDevice3 methods */ + dxgi_device_Trim, + /* IWineDXGIDevice methods */ + dxgi_device_create_surface, +}; + +static inline struct dxgi_device *impl_from_IWineDXGISwapChainFactory(IWineDXGISwapChainFactory *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_device, IWineDXGISwapChainFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_QueryInterface(IWineDXGISwapChainFactory *iface, + REFIID iid, void **out) +{ + struct dxgi_device *device = impl_from_IWineDXGISwapChainFactory(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return dxgi_device_QueryInterface(&device->IWineDXGIDevice_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE dxgi_swapchain_factory_AddRef(IWineDXGISwapChainFactory *iface) +{ + struct dxgi_device *device = impl_from_IWineDXGISwapChainFactory(iface); + + TRACE("iface %p.\n", iface); + + return dxgi_device_AddRef(&device->IWineDXGIDevice_iface); +} + +static ULONG STDMETHODCALLTYPE dxgi_swapchain_factory_Release(IWineDXGISwapChainFactory *iface) +{ + struct dxgi_device *device = impl_from_IWineDXGISwapChainFactory(iface); + + TRACE("iface %p.\n", iface); + + return dxgi_device_Release(&device->IWineDXGIDevice_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDXGISwapChainFactory *iface, + IDXGIFactory *factory, HWND window, const DXGI_SWAP_CHAIN_DESC1 *desc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, IDXGIOutput *output, IDXGISwapChain1 **swapchain) +{ + struct dxgi_device *device = impl_from_IWineDXGISwapChainFactory(iface); + struct wined3d_swapchain_desc wined3d_desc; + struct d3d11_swapchain *object; + HRESULT hr; + + TRACE("iface %p, factory %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n", + iface, factory, window, desc, fullscreen_desc, output, swapchain); + + if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, desc, fullscreen_desc))) + return hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate swapchain memory.\n"); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = d3d11_swapchain_init(object, device, &wined3d_desc))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created swapchain %p.\n", object); + + *swapchain = &object->IDXGISwapChain1_iface; + + return S_OK; +} + +static const struct IWineDXGISwapChainFactoryVtbl dxgi_swapchain_factory_vtbl = +{ + dxgi_swapchain_factory_QueryInterface, + dxgi_swapchain_factory_AddRef, + dxgi_swapchain_factory_Release, + dxgi_swapchain_factory_create_swapchain, +}; + +HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer, + IDXGIFactory *factory, IDXGIAdapter *adapter, + const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) +{ + struct wined3d_device_parent *wined3d_device_parent; + struct wined3d_swapchain_desc swapchain_desc; + IWineDXGIDeviceParent *dxgi_device_parent; + struct d3d11_swapchain *swapchain; + struct dxgi_adapter *dxgi_adapter; + struct dxgi_factory *dxgi_factory; + void *layer_base; + HRESULT hr; + + if (!(dxgi_factory = unsafe_impl_from_IDXGIFactory(factory))) + { + WARN("This is not the factory we're looking for.\n"); + return E_FAIL; + } + + if (!(dxgi_adapter = unsafe_impl_from_IDXGIAdapter(adapter))) + { + WARN("This is not the adapter we're looking for.\n"); + return E_FAIL; + } + + device->IWineDXGIDevice_iface.lpVtbl = &dxgi_device_vtbl; + device->IWineDXGISwapChainFactory_iface.lpVtbl = &dxgi_swapchain_factory_vtbl; + device->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&device->private_store); + + layer_base = device + 1; + + if (FAILED(hr = layer->create(layer->id, &layer_base, 0, + device, &IID_IUnknown, (void **)&device->child_layer))) + { + WARN("Failed to create device, returning %#x.\n", hr); + wined3d_private_store_cleanup(&device->private_store); + wined3d_mutex_unlock(); + return hr; + } + + if (FAILED(hr = IWineDXGIDevice_QueryInterface(&device->IWineDXGIDevice_iface, + &IID_IWineDXGIDeviceParent, (void **)&dxgi_device_parent))) + { + ERR("DXGI device should implement IWineDXGIDeviceParent.\n"); + IUnknown_Release(device->child_layer); + wined3d_private_store_cleanup(&device->private_store); + wined3d_mutex_unlock(); + return hr; + } + wined3d_device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); + IWineDXGIDeviceParent_Release(dxgi_device_parent); + + if (FAILED(hr = wined3d_device_create(dxgi_factory->wined3d, + dxgi_adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4, + (const enum wined3d_feature_level *)feature_levels, level_count, + wined3d_device_parent, &device->wined3d_device))) + { + WARN("Failed to create a wined3d device, returning %#x.\n", hr); + IUnknown_Release(device->child_layer); + wined3d_private_store_cleanup(&device->private_store); + wined3d_mutex_unlock(); + return hr; + } + + memset(&swapchain_desc, 0, sizeof(swapchain_desc)); + swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; + swapchain_desc.device_window = dxgi_factory_get_device_window(dxgi_factory); + swapchain_desc.windowed = TRUE; + swapchain_desc.flags = WINED3D_SWAPCHAIN_IMPLICIT; + + if (!(swapchain = heap_alloc_zero(sizeof(*swapchain)))) + { + ERR("Failed to allocate swapchain memory.\n"); + wined3d_device_decref(device->wined3d_device); + IUnknown_Release(device->child_layer); + wined3d_private_store_cleanup(&device->private_store); + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = d3d11_swapchain_init(swapchain, device, &swapchain_desc))) + { + WARN("Failed to initialize swapchain, hr %#x.\n", hr); + heap_free(swapchain); + wined3d_device_decref(device->wined3d_device); + IUnknown_Release(device->child_layer); + wined3d_private_store_cleanup(&device->private_store); + wined3d_mutex_unlock(); + return hr; + } + device->implicit_swapchain = swapchain->wined3d_swapchain; + + TRACE("Created swapchain %p.\n", swapchain); + + wined3d_mutex_unlock(); + + device->adapter = &dxgi_adapter->IWineDXGIAdapter_iface; + IWineDXGIAdapter_AddRef(device->adapter); + + return S_OK; +} diff --git a/dll/directx/wine/dxgi/dxgi.spec b/dll/directx/wine/dxgi/dxgi.spec new file mode 100644 index 00000000000..67a345dc376 --- /dev/null +++ b/dll/directx/wine/dxgi/dxgi.spec @@ -0,0 +1,6 @@ +@ stdcall CreateDXGIFactory(ptr ptr) +@ stdcall CreateDXGIFactory1(ptr ptr) +@ stdcall CreateDXGIFactory2(long ptr ptr) +@ stdcall DXGID3D10CreateDevice(ptr ptr ptr long ptr long ptr) +@ stdcall DXGID3D10RegisterLayers(ptr long) +@ stdcall DXGIGetDebugInterface1(long ptr ptr) diff --git a/dll/directx/wine/dxgi/dxgi_main.c b/dll/directx/wine/dxgi/dxgi_main.c new file mode 100644 index 00000000000..83c3f3734a7 --- /dev/null +++ b/dll/directx/wine/dxgi/dxgi_main.c @@ -0,0 +1,258 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#define DXGI_INIT_GUID +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +struct dxgi_main +{ + HMODULE d3d10core; + struct dxgi_device_layer *device_layers; + UINT layer_count; +}; +static struct dxgi_main dxgi_main; + +static void dxgi_main_cleanup(void) +{ + heap_free(dxgi_main.device_layers); + FreeLibrary(dxgi_main.d3d10core); +} + +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(inst); + break; + + case DLL_PROCESS_DETACH: + if (!reserved) + dxgi_main_cleanup(); + break; + } + + return TRUE; +} + +HRESULT WINAPI CreateDXGIFactory2(UINT flags, REFIID iid, void **factory) +{ + TRACE("flags %#x, iid %s, factory %p.\n", flags, debugstr_guid(iid), factory); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + return dxgi_factory_create(iid, factory, TRUE); +} + +HRESULT WINAPI CreateDXGIFactory1(REFIID iid, void **factory) +{ + TRACE("iid %s, factory %p.\n", debugstr_guid(iid), factory); + + return dxgi_factory_create(iid, factory, TRUE); +} + +HRESULT WINAPI CreateDXGIFactory(REFIID iid, void **factory) +{ + TRACE("iid %s, factory %p.\n", debugstr_guid(iid), factory); + + return dxgi_factory_create(iid, factory, FALSE); +} + +static BOOL get_layer(enum dxgi_device_layer_id id, struct dxgi_device_layer *layer) +{ + UINT i; + + wined3d_mutex_lock(); + + for (i = 0; i < dxgi_main.layer_count; ++i) + { + if (dxgi_main.device_layers[i].id == id) + { + *layer = dxgi_main.device_layers[i]; + wined3d_mutex_unlock(); + return TRUE; + } + } + + wined3d_mutex_unlock(); + return FALSE; +} + +static HRESULT register_d3d10core_layers(HMODULE d3d10core) +{ + wined3d_mutex_lock(); + + if (!dxgi_main.d3d10core) + { + HRESULT hr; + HRESULT (WINAPI *d3d11core_register_layers)(void); + HMODULE mod; + BOOL ret; + + if (!(ret = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char *)d3d10core, &mod))) + { + wined3d_mutex_unlock(); + return E_FAIL; + } + + d3d11core_register_layers = (void *)GetProcAddress(mod, "D3D11CoreRegisterLayers"); + hr = d3d11core_register_layers(); + if (FAILED(hr)) + { + ERR("Failed to register d3d11 layers, returning %#x.\n", hr); + FreeLibrary(mod); + wined3d_mutex_unlock(); + return hr; + } + + dxgi_main.d3d10core = mod; + } + + wined3d_mutex_unlock(); + + return S_OK; +} + +HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter, + unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count, void **device) +{ + struct layer_get_size_args get_size_args; + struct dxgi_device_layer d3d10_layer; + struct dxgi_device *dxgi_device; + UINT device_size; + DWORD count; + HRESULT hr; + + TRACE("d3d10core %p, factory %p, adapter %p, flags %#x, feature_levels %p, level_count %u, device %p.\n", + d3d10core, factory, adapter, flags, feature_levels, level_count, device); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + if (TRACE_ON(dxgi)) + dump_feature_levels(feature_levels, level_count); + + hr = register_d3d10core_layers(d3d10core); + if (FAILED(hr)) + { + ERR("Failed to register d3d10core layers, returning %#x.\n", hr); + return hr; + } + + if (!get_layer(DXGI_DEVICE_LAYER_D3D10_DEVICE, &d3d10_layer)) + { + ERR("Failed to get D3D10 device layer.\n"); + return E_FAIL; + } + + count = 0; + hr = d3d10_layer.init(d3d10_layer.id, &count, NULL); + if (FAILED(hr)) + { + WARN("Failed to initialize D3D10 device layer.\n"); + return E_FAIL; + } + + get_size_args.unknown0 = 0; + get_size_args.unknown1 = 0; + get_size_args.unknown2 = NULL; + get_size_args.unknown3 = NULL; + get_size_args.adapter = adapter; + get_size_args.interface_major = 10; + get_size_args.interface_minor = 1; + get_size_args.version_build = 4; + get_size_args.version_revision = 6000; + + device_size = d3d10_layer.get_size(d3d10_layer.id, &get_size_args, 0); + device_size += sizeof(*dxgi_device); + + if (!(dxgi_device = heap_alloc_zero(device_size))) + { + ERR("Failed to allocate device memory.\n"); + return E_OUTOFMEMORY; + } + + hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter, feature_levels, level_count); + if (FAILED(hr)) + { + WARN("Failed to initialize device, hr %#x.\n", hr); + heap_free(dxgi_device); + *device = NULL; + return hr; + } + + TRACE("Created device %p.\n", dxgi_device); + *device = &dxgi_device->IWineDXGIDevice_iface; + + return S_OK; +} + +HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count) +{ + UINT i; + struct dxgi_device_layer *new_layers; + + TRACE("layers %p, layer_count %u\n", layers, layer_count); + + wined3d_mutex_lock(); + + if (!dxgi_main.layer_count) + new_layers = heap_alloc(layer_count * sizeof(*new_layers)); + else + new_layers = heap_realloc(dxgi_main.device_layers, + (dxgi_main.layer_count + layer_count) * sizeof(*new_layers)); + + if (!new_layers) + { + wined3d_mutex_unlock(); + ERR("Failed to allocate layer memory\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < layer_count; ++i) + { + const struct dxgi_device_layer *layer = &layers[i]; + + TRACE("layer %d: id %#x, init %p, get_size %p, create %p\n", + i, layer->id, layer->init, layer->get_size, layer->create); + + new_layers[dxgi_main.layer_count + i] = *layer; + } + + dxgi_main.device_layers = new_layers; + dxgi_main.layer_count += layer_count; + + wined3d_mutex_unlock(); + + return S_OK; +} + +HRESULT WINAPI DXGIGetDebugInterface1(UINT flags, REFIID iid, void **debug) +{ + TRACE("flags %#x, iid %s, debug %p.\n", flags, debugstr_guid(iid), debug); + + WARN("Returning DXGI_ERROR_SDK_COMPONENT_MISSING.\n"); + return DXGI_ERROR_SDK_COMPONENT_MISSING; +} diff --git a/dll/directx/wine/dxgi/dxgi_private.h b/dll/directx/wine/dxgi/dxgi_private.h new file mode 100644 index 00000000000..7fe62f0f946 --- /dev/null +++ b/dll/directx/wine/dxgi/dxgi_private.h @@ -0,0 +1,255 @@ +#ifndef __WINE_DXGI_PRIVATE_H +#define __WINE_DXGI_PRIVATE_H + +#include "wine/debug.h" +#include "wine/heap.h" + +#include + +#define COBJMACROS +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "objbase.h" +#include "winnls.h" + +#include "dxgi1_6.h" +#include "d3d10_1.h" +#include "d3d12.h" +#ifdef DXGI_INIT_GUID +#include "initguid.h" +#endif +#include "wine/wined3d.h" +#include "wine/winedxgi.h" + +#ifdef __REACTOS__ +#define USE_WIN32_VULKAN 1 +#endif + +DEFINE_GUID(IID_IDXGIDevice3,0x6007896c,0x3244,0x4afd,0xbf,0x18,0xa6,0xd3,0xbe,0xda,0x50,0x23); +DEFINE_GUID(IID_IDXGIOutput3,0x8a6bb301,0x7e7e,0x41F4,0xa8,0xe0,0x5b,0x32,0xf7,0xf9,0x9b,0x18); +DEFINE_GUID(IID_IDXGIOutput2,0x595e39d1,0x2724,0x4663,0x99,0xb1,0xda,0x96,0x9d,0xe2,0x83,0x64); +DEFINE_GUID(IID_IDXGIAdapter4,0x3c8d99d1,0x4fbf,0x4181,0xa8,0x2c,0xaf,0x66,0xbf,0x7b,0xd2,0x4e); +DEFINE_GUID(IID_ID3D12CommandQueue,0x0ec870a6,0x5d7e,0x4c22,0x8c,0xfc,0x5b,0xaa,0xe0,0x76,0x16,0xed); +DEFINE_GUID(IID_ID3D10BlendState1,0xEDAD8D99,0x8A35,0x4d6d,0x85,0x66,0x2E,0xA2,0x76,0xCD,0xE1,0x61); +DEFINE_GUID(IID_ID3D10ShaderResourceView1,0x9B7E4C87,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Device1,0x9B7E4C8F,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DeviceChild,0x9B7E4C00,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DepthStencilState,0x2B4B1CC8,0xA4AD,0x41f8,0x83,0x22,0xCA,0x86,0xFC,0x3E,0xC6,0x75); +DEFINE_GUID(IID_ID3D10BlendState,0xEDAD8D19,0x8A35,0x4d6d,0x85,0x66,0x2E,0xA2,0x76,0xCD,0xE1,0x61); +DEFINE_GUID(IID_ID3D10RasterizerState,0xA2A07292,0x89AF,0x4345,0xBE,0x2E,0xC5,0x3D,0x9F,0xBB,0x6E,0x9F); +DEFINE_GUID(IID_ID3D10Resource,0x9B7E4C01,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Buffer,0x9B7E4C02,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture1D,0x9B7E4C03,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture2D,0x9B7E4C04,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture3D,0x9B7E4C05,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10View,0xC902B03F,0x60A7,0x49BA,0x99,0x36,0x2A,0x3A,0xB3,0x7A,0x7E,0x33); +DEFINE_GUID(IID_ID3D10ShaderResourceView,0x9B7E4C07,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10RenderTargetView,0x9B7E4C08,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DepthStencilView,0x9B7E4C09,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10VertexShader,0x9B7E4C0A,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10GeometryShader,0x6316BE88,0x54CD,0x4040,0xAB,0x44,0x20,0x46,0x1B,0xC8,0x1F,0x68); +DEFINE_GUID(IID_ID3D10PixelShader,0x4968B601,0x9D00,0x4cde,0x83,0x46,0x8E,0x7F,0x67,0x58,0x19,0xB6); +DEFINE_GUID(IID_ID3D10InputLayout,0x9B7E4C0B,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10SamplerState,0x9B7E4C0C,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Asynchronous,0x9B7E4C0D,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Query,0x9B7E4C0E,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Predicate,0x9B7E4C10,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Counter,0x9B7E4C11,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Device,0x9B7E4C0F,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Multithread,0x9B7E4E00,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_IDXGIObject,0xaec22fb8,0x76f3,0x4639,0x9b,0xe0,0x28,0xeb,0x43,0xa6,0x7a,0x2e); +DEFINE_GUID(IID_IDXGIDeviceSubObject,0x3d3e0379,0xf9de,0x4d58,0xbb,0x6c,0x18,0xd6,0x29,0x92,0xf1,0xa6); +DEFINE_GUID(IID_IDXGIResource,0x035f3ab4,0x482e,0x4e50,0xb4,0x1f,0x8a,0x7f,0x8b,0xd8,0x96,0x0b); +DEFINE_GUID(IID_IDXGIKeyedMutex,0x9d8e1289,0xd7b3,0x465f,0x81,0x26,0x25,0x0e,0x34,0x9a,0xf8,0x5d); +DEFINE_GUID(IID_IDXGISurface,0xcafcb56c,0x6ac3,0x4889,0xbf,0x47,0x9e,0x23,0xbb,0xd2,0x60,0xec); +DEFINE_GUID(IID_IDXGISurface1,0x4AE63092,0x6327,0x4c1b,0x80,0xAE,0xBF,0xE1,0x2E,0xA3,0x2B,0x86); +DEFINE_GUID(IID_IDXGIAdapter,0x2411e7e1,0x12ac,0x4ccf,0xbd,0x14,0x97,0x98,0xe8,0x53,0x4d,0xc0); +DEFINE_GUID(IID_IDXGIOutput,0xae02eedb,0xc735,0x4690,0x8d,0x52,0x5a,0x8d,0xc2,0x02,0x13,0xaa); +DEFINE_GUID(IID_IDXGISwapChain,0x310d36a0,0xd2e7,0x4c0a,0xaa,0x04,0x6a,0x9d,0x23,0xb8,0x88,0x6a); +DEFINE_GUID(IID_IDXGIFactory,0x7b7166ec,0x21c7,0x44ae,0xb2,0x1a,0xc9,0xae,0x32,0x1a,0xe3,0x69); +DEFINE_GUID(IID_IDXGIDevice,0x54ec77fa,0x1377,0x44e6,0x8c,0x32,0x88,0xfd,0x5f,0x44,0xc8,0x4c); +DEFINE_GUID(IID_IDXGIFactory1,0x770aae78,0xf26f,0x4dba,0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87); +DEFINE_GUID(IID_IDXGIAdapter1,0x29038f61,0x3839,0x4626,0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05); +DEFINE_GUID(IID_IDXGIDevice1,0x77db970f,0x6276,0x48ba,0xba,0x28,0x07,0x01,0x43,0xb4,0x39,0x2c); +DEFINE_GUID(IID_IDXGIDisplayControl,0xea9dbf1a,0xc88e,0x4486,0x85,0x4a,0x98,0xaa,0x01,0x38,0xf3,0x0c); +DEFINE_GUID(IID_IDXGIOutputDuplication,0x191cfac3,0xa341,0x470d,0xb2,0x6e,0xa8,0x64,0xf4,0x28,0x31,0x9c); +DEFINE_GUID(IID_IDXGISurface2,0xaba496dd,0xb617,0x4cb8,0xa8,0x66,0xbc,0x44,0xd7,0xeb,0x1f,0xa2); +DEFINE_GUID(IID_IDXGIResource1,0x30961379,0x4609,0x4a41,0x99,0x8e,0x54,0xfe,0x56,0x7e,0xe0,0xc1); +DEFINE_GUID(IID_IDXGIDevice2,0x05008617,0xfbfd,0x4051,0xa7,0x90,0x14,0x48,0x84,0xb4,0xf6,0xa9); +DEFINE_GUID(IID_IDXGISwapChain1,0x790a45f7,0x0d42,0x4876,0x98,0x3a,0x0a,0x55,0xcf,0xe6,0xf4,0xaa); +DEFINE_GUID(IID_IDXGIFactory2,0x50c83a1c,0xe072,0x4c48,0x87,0xb0,0x36,0x30,0xfa,0x36,0xa6,0xd0); +DEFINE_GUID(IID_IDXGIAdapter2,0x0AA1AE0A,0xFA0E,0x4B84,0x86,0x44,0xE0,0x5F,0xF8,0xE5,0xAC,0xB5); +DEFINE_GUID(IID_IDXGIOutput1,0x00cddea8,0x939b,0x4b83,0xa3,0x40,0xa6,0x85,0x22,0x66,0x66,0xcc); +DEFINE_GUID(IID_IDXGISwapChain3,0x94d99bdb,0xf1f8,0x4ab0,0xb2,0x36,0x7d,0xa0,0x17,0x0e,0xda,0xb1); +DEFINE_GUID(IID_IDXGIOutput4,0xdc7dca35,0x2196,0x414d,0x9F,0x53,0x61,0x78,0x84,0x03,0x2a,0x60); +DEFINE_GUID(IID_IDXGIFactory4,0x1bc6ea02,0xef36,0x464f,0xbf,0x0c,0x21,0xca,0x39,0xe5,0x16,0x8a); +DEFINE_GUID(IID_IDXGIAdapter3,0x645967A4,0x1392,0x4310,0xA7,0x98,0x80,0x53,0xCE,0x3E,0x93,0xFD); +DEFINE_GUID(IID_IDXGIFactory3,0x25483823,0xcd46,0x4c7d,0x86,0xca,0x47,0xaa,0x95,0xb8,0x37,0xbd); +DEFINE_GUID(IID_IDXGIFactory5,0x7632e1f5,0xee65,0x4dca,0x87,0xfd,0x84,0xcd,0x75,0xf8,0x83,0x8d); + + +enum dxgi_frame_latency +{ + DXGI_FRAME_LATENCY_MAX = 16, +}; + +/* Layered device */ +enum dxgi_device_layer_id +{ + DXGI_DEVICE_LAYER_DEBUG1 = 0x8, + DXGI_DEVICE_LAYER_THREAD_SAFE = 0x10, + DXGI_DEVICE_LAYER_DEBUG2 = 0x20, + DXGI_DEVICE_LAYER_SWITCH_TO_REF = 0x30, + DXGI_DEVICE_LAYER_D3D10_DEVICE = 0xffffffff, +}; + +struct layer_get_size_args +{ + DWORD unknown0; + DWORD unknown1; + DWORD *unknown2; + DWORD *unknown3; + IDXGIAdapter *adapter; + WORD interface_major; + WORD interface_minor; + WORD version_build; + WORD version_revision; +}; + +struct dxgi_device_layer +{ + enum dxgi_device_layer_id id; + HRESULT (WINAPI *init)(enum dxgi_device_layer_id id, DWORD *count, DWORD *values); + UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0); + HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0, + void *device_object, REFIID riid, void **device_layer); +}; + +/* TRACE helper functions */ +const char *debug_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; +const char *debug_dxgi_mode(const DXGI_MODE_DESC *desc) DECLSPEC_HIDDEN; +const char *debug_dxgi_mode1(const DXGI_MODE_DESC1 *desc) DECLSPEC_HIDDEN; +void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) DECLSPEC_HIDDEN; + +DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; +enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; +void dxgi_sample_desc_from_wined3d(DXGI_SAMPLE_DESC *desc, + enum wined3d_multisample_type wined3d_type, unsigned int wined3d_quality) DECLSPEC_HIDDEN; +void wined3d_sample_desc_from_dxgi(enum wined3d_multisample_type *wined3d_type, + unsigned int *wined3d_quality, const DXGI_SAMPLE_DESC *dxgi_desc) DECLSPEC_HIDDEN; +void wined3d_display_mode_from_dxgi(struct wined3d_display_mode *wined3d_mode, + const DXGI_MODE_DESC *mode) DECLSPEC_HIDDEN; +void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode, + const DXGI_MODE_DESC1 *mode) DECLSPEC_HIDDEN; +DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) DECLSPEC_HIDDEN; +unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN; +unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN; +HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc, + HWND window, const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *dxgi_fullscreen_desc) DECLSPEC_HIDDEN; + +HRESULT dxgi_get_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN; +HRESULT dxgi_set_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT data_size, const void *data) DECLSPEC_HIDDEN; +HRESULT dxgi_set_private_data_interface(struct wined3d_private_store *store, + REFGUID guid, const IUnknown *object) DECLSPEC_HIDDEN; + +/* IDXGIFactory */ +struct dxgi_factory +{ + IWineDXGIFactory IWineDXGIFactory_iface; + LONG refcount; + struct wined3d_private_store private_store; + struct wined3d *wined3d; + BOOL extended; + HWND device_window; +}; + +HRESULT dxgi_factory_create(REFIID riid, void **factory, BOOL extended) DECLSPEC_HIDDEN; +HWND dxgi_factory_get_device_window(struct dxgi_factory *factory) DECLSPEC_HIDDEN; +struct dxgi_factory *unsafe_impl_from_IDXGIFactory(IDXGIFactory *iface) DECLSPEC_HIDDEN; + +/* IDXGIDevice */ +struct dxgi_device +{ + IWineDXGIDevice IWineDXGIDevice_iface; + IWineDXGISwapChainFactory IWineDXGISwapChainFactory_iface; + IUnknown *child_layer; + LONG refcount; + struct wined3d_private_store private_store; + struct wined3d_device *wined3d_device; + struct wined3d_swapchain *implicit_swapchain; + IWineDXGIAdapter *adapter; +}; + +HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer, + IDXGIFactory *factory, IDXGIAdapter *adapter, + const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) DECLSPEC_HIDDEN; + +/* IDXGIOutput */ +struct dxgi_output +{ + IDXGIOutput4 IDXGIOutput4_iface; + LONG refcount; + struct wined3d_private_store private_store; + struct dxgi_adapter *adapter; +}; + +HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) DECLSPEC_HIDDEN; +struct dxgi_output *unsafe_impl_from_IDXGIOutput(IDXGIOutput *iface) DECLSPEC_HIDDEN; + +/* IDXGIAdapter */ +struct dxgi_adapter +{ + IWineDXGIAdapter IWineDXGIAdapter_iface; + LONG refcount; + struct wined3d_private_store private_store; + UINT ordinal; + struct dxgi_factory *factory; +}; + +HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal, + struct dxgi_adapter **adapter) DECLSPEC_HIDDEN; +struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) DECLSPEC_HIDDEN; + +/* IDXGISwapChain */ +struct d3d11_swapchain +{ + IDXGISwapChain1 IDXGISwapChain1_iface; + LONG refcount; + struct wined3d_private_store private_store; + struct wined3d_swapchain *wined3d_swapchain; + IWineDXGIDevice *device; + IDXGIFactory *factory; + + IDXGIOutput *target; +}; + +HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device, + struct wined3d_swapchain_desc *desc) DECLSPEC_HIDDEN; + +HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window, + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, + IDXGISwapChain1 **swapchain) DECLSPEC_HIDDEN; + +BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc) DECLSPEC_HIDDEN; + +/* IDXGISurface */ +struct dxgi_surface +{ + IDXGISurface1 IDXGISurface1_iface; + IUnknown IUnknown_iface; + IUnknown *outer_unknown; + LONG refcount; + struct wined3d_private_store private_store; + IDXGIDevice *device; + struct wined3d_texture *wined3d_texture; + HDC dc; +}; + +HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, + IUnknown *outer, struct wined3d_texture *wined3d_texture) DECLSPEC_HIDDEN; + +#endif /* __WINE_DXGI_PRIVATE_H */ diff --git a/dll/directx/wine/dxgi/factory.c b/dll/directx/wine/dxgi/factory.c new file mode 100644 index 00000000000..a0038b4fe77 --- /dev/null +++ b/dll/directx/wine/dxgi/factory.c @@ -0,0 +1,569 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_factory *impl_from_IWineDXGIFactory(IWineDXGIFactory *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_factory, IWineDXGIFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_QueryInterface(IWineDXGIFactory *iface, REFIID iid, void **out) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IWineDXGIFactory) + || IsEqualGUID(iid, &IID_IDXGIFactory5) + || IsEqualGUID(iid, &IID_IDXGIFactory4) + || IsEqualGUID(iid, &IID_IDXGIFactory3) + || IsEqualGUID(iid, &IID_IDXGIFactory2) + || (factory->extended && IsEqualGUID(iid, &IID_IDXGIFactory1)) + || IsEqualGUID(iid, &IID_IDXGIFactory) + || IsEqualGUID(iid, &IID_IDXGIObject) + || IsEqualGUID(iid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_factory_AddRef(IWineDXGIFactory *iface) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_factory_Release(IWineDXGIFactory *iface) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + ULONG refcount = InterlockedDecrement(&factory->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + if (factory->device_window) + DestroyWindow(factory->device_window); + + wined3d_mutex_lock(); + wined3d_decref(factory->wined3d); + wined3d_mutex_unlock(); + wined3d_private_store_cleanup(&factory->private_store); + heap_free(factory); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_SetPrivateData(IWineDXGIFactory *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&factory->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_SetPrivateDataInterface(IWineDXGIFactory *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&factory->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetPrivateData(IWineDXGIFactory *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&factory->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetParent(IWineDXGIFactory *iface, REFIID iid, void **parent) +{ + WARN("iface %p, iid %s, parent %p.\n", iface, debugstr_guid(iid), parent); + + *parent = NULL; + + return E_NOINTERFACE; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters1(IWineDXGIFactory *iface, + UINT adapter_idx, IDXGIAdapter1 **adapter) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + struct dxgi_adapter *adapter_object; + UINT adapter_count; + HRESULT hr; + + TRACE("iface %p, adapter_idx %u, adapter %p.\n", iface, adapter_idx, adapter); + + if (!adapter) + return DXGI_ERROR_INVALID_CALL; + + wined3d_mutex_lock(); + adapter_count = wined3d_get_adapter_count(factory->wined3d); + wined3d_mutex_unlock(); + + if (adapter_idx >= adapter_count) + { + *adapter = NULL; + return DXGI_ERROR_NOT_FOUND; + } + + if (FAILED(hr = dxgi_adapter_create(factory, adapter_idx, &adapter_object))) + { + *adapter = NULL; + return hr; + } + + *adapter = (IDXGIAdapter1 *)&adapter_object->IWineDXGIAdapter_iface; + + TRACE("Returning adapter %p.\n", *adapter); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters(IWineDXGIFactory *iface, + UINT adapter_idx, IDXGIAdapter **adapter) +{ + TRACE("iface %p, adapter_idx %u, adapter %p.\n", iface, adapter_idx, adapter); + + return dxgi_factory_EnumAdapters1(iface, adapter_idx, (IDXGIAdapter1 **)adapter); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_MakeWindowAssociation(IWineDXGIFactory *iface, + HWND window, UINT flags) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags); + + if (flags > DXGI_MWA_VALID) + return DXGI_ERROR_INVALID_CALL; + + if (!window) + { + wined3d_unregister_windows(factory->wined3d); + return S_OK; + } + + if (!wined3d_register_window(factory->wined3d, window, NULL, flags)) + return E_FAIL; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetWindowAssociation(IWineDXGIFactory *iface, HWND *window) +{ + TRACE("iface %p, window %p.\n", iface, window); + + if (!window) + return DXGI_ERROR_INVALID_CALL; + + /* The tests show that this always returns NULL for some unknown reason. */ + *window = NULL; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IWineDXGIFactory *iface, + IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) +{ + struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface); + DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; + DXGI_SWAP_CHAIN_DESC1 swapchain_desc; + + TRACE("iface %p, device %p, desc %p, swapchain %p.\n", iface, device, desc, swapchain); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + swapchain_desc.Width = desc->BufferDesc.Width; + swapchain_desc.Height = desc->BufferDesc.Height; + swapchain_desc.Format = desc->BufferDesc.Format; + swapchain_desc.Stereo = FALSE; + swapchain_desc.SampleDesc = desc->SampleDesc; + swapchain_desc.BufferUsage = desc->BufferUsage; + swapchain_desc.BufferCount = desc->BufferCount; + swapchain_desc.Scaling = DXGI_SCALING_STRETCH; + swapchain_desc.SwapEffect = desc->SwapEffect; + swapchain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + swapchain_desc.Flags = desc->Flags; + + fullscreen_desc.RefreshRate = desc->BufferDesc.RefreshRate; + fullscreen_desc.ScanlineOrdering = desc->BufferDesc.ScanlineOrdering; + fullscreen_desc.Scaling = desc->BufferDesc.Scaling; + fullscreen_desc.Windowed = desc->Windowed; + + return IWineDXGIFactory_CreateSwapChainForHwnd(&factory->IWineDXGIFactory_iface, + device, desc->OutputWindow, &swapchain_desc, &fullscreen_desc, NULL, + (IDXGISwapChain1 **)swapchain); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSoftwareAdapter(IWineDXGIFactory *iface, + HMODULE swrast, IDXGIAdapter **adapter) +{ + FIXME("iface %p, swrast %p, adapter %p stub!\n", iface, swrast, adapter); + + return E_NOTIMPL; +} + +static BOOL STDMETHODCALLTYPE dxgi_factory_IsCurrent(IWineDXGIFactory *iface) +{ + FIXME("iface %p stub!\n", iface); + + return TRUE; +} + +static BOOL STDMETHODCALLTYPE dxgi_factory_IsWindowedStereoEnabled(IWineDXGIFactory *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChainForHwnd(IWineDXGIFactory *iface, + IUnknown *device, HWND window, const DXGI_SWAP_CHAIN_DESC1 *desc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, + IDXGIOutput *output, IDXGISwapChain1 **swapchain) +{ + IWineDXGISwapChainFactory *swapchain_factory; + ID3D12CommandQueue *command_queue; + HRESULT hr; + + TRACE("iface %p, device %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n", + iface, device, window, desc, fullscreen_desc, output, swapchain); + + if (!device || !window || !desc || !swapchain) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (desc->Stereo) + { + FIXME("Stereo swapchains are not supported.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + + if (!dxgi_validate_swapchain_desc(desc)) + return DXGI_ERROR_INVALID_CALL; + + if (output) + FIXME("Ignoring output %p.\n", output); + + if (SUCCEEDED(IUnknown_QueryInterface(device, &IID_IWineDXGISwapChainFactory, (void **)&swapchain_factory))) + { + hr = IWineDXGISwapChainFactory_create_swapchain(swapchain_factory, + (IDXGIFactory *)iface, window, desc, fullscreen_desc, output, swapchain); + IWineDXGISwapChainFactory_Release(swapchain_factory); + return hr; + } + + if (SUCCEEDED(IUnknown_QueryInterface(device, &IID_ID3D12CommandQueue, (void **)&command_queue))) + { + hr = d3d12_swapchain_create(iface, command_queue, window, desc, fullscreen_desc, swapchain); + ID3D12CommandQueue_Release(command_queue); + return hr; + } + + ERR("This is not the device we're looking for.\n"); + return DXGI_ERROR_UNSUPPORTED; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChainForCoreWindow(IWineDXGIFactory *iface, + IUnknown *device, IUnknown *window, const DXGI_SWAP_CHAIN_DESC1 *desc, + IDXGIOutput *output, IDXGISwapChain1 **swapchain) +{ + FIXME("iface %p, device %p, window %p, desc %p, output %p, swapchain %p stub!\n", + iface, device, window, desc, output, swapchain); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetSharedResourceAdapterLuid(IWineDXGIFactory *iface, + HANDLE resource, LUID *luid) +{ + FIXME("iface %p, resource %p, luid %p stub!\n", iface, resource, luid); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_RegisterOcclusionStatusWindow(IWineDXGIFactory *iface, + HWND window, UINT message, DWORD *cookie) +{ + FIXME("iface %p, window %p, message %#x, cookie %p stub!\n", + iface, window, message, cookie); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_RegisterStereoStatusEvent(IWineDXGIFactory *iface, + HANDLE event, DWORD *cookie) +{ + FIXME("iface %p, event %p, cookie %p stub!\n", iface, event, cookie); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_factory_UnregisterStereoStatus(IWineDXGIFactory *iface, DWORD cookie) +{ + FIXME("iface %p, cookie %#x stub!\n", iface, cookie); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_RegisterStereoStatusWindow(IWineDXGIFactory *iface, + HWND window, UINT message, DWORD *cookie) +{ + FIXME("iface %p, window %p, message %#x, cookie %p stub!\n", + iface, window, message, cookie); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_RegisterOcclusionStatusEvent(IWineDXGIFactory *iface, + HANDLE event, DWORD *cookie) +{ + FIXME("iface %p, event %p, cookie %p stub!\n", iface, event, cookie); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_factory_UnregisterOcclusionStatus(IWineDXGIFactory *iface, DWORD cookie) +{ + FIXME("iface %p, cookie %#x stub!\n", iface, cookie); +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChainForComposition(IWineDXGIFactory *iface, + IUnknown *device, const DXGI_SWAP_CHAIN_DESC1 *desc, IDXGIOutput *output, IDXGISwapChain1 **swapchain) +{ + FIXME("iface %p, device %p, desc %p, output %p, swapchain %p stub!\n", + iface, device, desc, output, swapchain); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE dxgi_factory_GetCreationFlags(IWineDXGIFactory *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapterByLuid(IWineDXGIFactory *iface, + LUID luid, REFIID iid, void **adapter) +{ + unsigned int adapter_index; + DXGI_ADAPTER_DESC1 desc; + IDXGIAdapter1 *adapter1; + HRESULT hr; + + TRACE("iface %p, luid %08x:%08x, iid %s, adapter %p.\n", + iface, luid.HighPart, luid.LowPart, debugstr_guid(iid), adapter); + + adapter_index = 0; + while ((hr = dxgi_factory_EnumAdapters1(iface, adapter_index, &adapter1)) == S_OK) + { + if (FAILED(hr = IDXGIAdapter1_GetDesc1(adapter1, &desc))) + { + WARN("Failed to get adapter %u desc, hr %#x.\n", adapter_index, hr); + ++adapter_index; + continue; + } + + if (desc.AdapterLuid.LowPart == luid.LowPart + && desc.AdapterLuid.HighPart == luid.HighPart) + { + hr = IDXGIAdapter1_QueryInterface(adapter1, iid, adapter); + IDXGIAdapter1_Release(adapter1); + return hr; + } + + IDXGIAdapter1_Release(adapter1); + ++adapter_index; + } + if (hr != DXGI_ERROR_NOT_FOUND) + WARN("Failed to enumerate adapters, hr %#x.\n", hr); + + WARN("Adapter could not be found.\n"); + return DXGI_ERROR_NOT_FOUND; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumWarpAdapter(IWineDXGIFactory *iface, + REFIID iid, void **adapter) +{ + FIXME("iface %p, iid %s, adapter %p stub!\n", iface, debugstr_guid(iid), adapter); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CheckFeatureSupport(IWineDXGIFactory *iface, + DXGI_FEATURE feature, void *feature_data, UINT data_size) +{ + FIXME("iface %p, feature %#x, feature_data %p, data_size %u stub!\n", + iface, feature, feature_data, data_size); + + return E_NOTIMPL; +} + +static const struct IWineDXGIFactoryVtbl dxgi_factory_vtbl = +{ + dxgi_factory_QueryInterface, + dxgi_factory_AddRef, + dxgi_factory_Release, + dxgi_factory_SetPrivateData, + dxgi_factory_SetPrivateDataInterface, + dxgi_factory_GetPrivateData, + dxgi_factory_GetParent, + dxgi_factory_EnumAdapters, + dxgi_factory_MakeWindowAssociation, + dxgi_factory_GetWindowAssociation, + dxgi_factory_CreateSwapChain, + dxgi_factory_CreateSoftwareAdapter, + /* IDXGIFactory1 methods */ + dxgi_factory_EnumAdapters1, + dxgi_factory_IsCurrent, + /* IDXGIFactory2 methods */ + dxgi_factory_IsWindowedStereoEnabled, + dxgi_factory_CreateSwapChainForHwnd, + dxgi_factory_CreateSwapChainForCoreWindow, + dxgi_factory_GetSharedResourceAdapterLuid, + dxgi_factory_RegisterOcclusionStatusWindow, + dxgi_factory_RegisterStereoStatusEvent, + dxgi_factory_UnregisterStereoStatus, + dxgi_factory_RegisterStereoStatusWindow, + dxgi_factory_RegisterOcclusionStatusEvent, + dxgi_factory_UnregisterOcclusionStatus, + dxgi_factory_CreateSwapChainForComposition, + /* IDXGIFactory3 methods */ + dxgi_factory_GetCreationFlags, + /* IDXGIFactory4 methods */ + dxgi_factory_EnumAdapterByLuid, + dxgi_factory_EnumWarpAdapter, + /* IDXIGFactory5 methods */ + dxgi_factory_CheckFeatureSupport, +}; + +struct dxgi_factory *unsafe_impl_from_IDXGIFactory(IDXGIFactory *iface) +{ + IWineDXGIFactory *wine_factory; + struct dxgi_factory *factory; + HRESULT hr; + + if (!iface) + return NULL; + if (FAILED(hr = IDXGIFactory_QueryInterface(iface, &IID_IWineDXGIFactory, (void **)&wine_factory))) + { + ERR("Failed to get IWineDXGIFactory interface, hr %#x.\n", hr); + return NULL; + } + assert(wine_factory->lpVtbl == &dxgi_factory_vtbl); + factory = CONTAINING_RECORD(wine_factory, struct dxgi_factory, IWineDXGIFactory_iface); + IWineDXGIFactory_Release(wine_factory); + return factory; +} + +static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended) +{ + factory->IWineDXGIFactory_iface.lpVtbl = &dxgi_factory_vtbl; + factory->refcount = 1; + wined3d_private_store_init(&factory->private_store); + + wined3d_mutex_lock(); + factory->wined3d = wined3d_create(0); + wined3d_mutex_unlock(); + if (!factory->wined3d) + { + wined3d_private_store_cleanup(&factory->private_store); + return DXGI_ERROR_UNSUPPORTED; + } + + factory->extended = extended; + + return S_OK; +} + +HRESULT dxgi_factory_create(REFIID riid, void **factory, BOOL extended) +{ + struct dxgi_factory *object; + HRESULT hr; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = dxgi_factory_init(object, extended))) + { + WARN("Failed to initialize factory, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created factory %p.\n", object); + + hr = IWineDXGIFactory_QueryInterface(&object->IWineDXGIFactory_iface, riid, factory); + IWineDXGIFactory_Release(&object->IWineDXGIFactory_iface); + return hr; +} + +HWND dxgi_factory_get_device_window(struct dxgi_factory *factory) +{ + wined3d_mutex_lock(); + + if (!factory->device_window) + { + if (!(factory->device_window = CreateWindowA("static", "DXGI device window", + WS_DISABLED, 0, 0, 0, 0, NULL, NULL, NULL, NULL))) + { + wined3d_mutex_unlock(); + ERR("Failed to create a window.\n"); + return NULL; + } + TRACE("Created device window %p for factory %p.\n", factory->device_window, factory); + } + + wined3d_mutex_unlock(); + + return factory->device_window; +} diff --git a/dll/directx/wine/dxgi/output.c b/dll/directx/wine/dxgi/output.c new file mode 100644 index 00000000000..abe1aef950c --- /dev/null +++ b/dll/directx/wine/dxgi/output.c @@ -0,0 +1,549 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static void dxgi_mode_from_wined3d(DXGI_MODE_DESC *mode, const struct wined3d_display_mode *wined3d_mode) +{ + mode->Width = wined3d_mode->width; + mode->Height = wined3d_mode->height; + mode->RefreshRate.Numerator = wined3d_mode->refresh_rate; + mode->RefreshRate.Denominator = 1; + mode->Format = dxgi_format_from_wined3dformat(wined3d_mode->format_id); + mode->ScanlineOrdering = wined3d_mode->scanline_ordering; + mode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ +} + +static void dxgi_mode1_from_wined3d(DXGI_MODE_DESC1 *mode, const struct wined3d_display_mode *wined3d_mode) +{ + mode->Width = wined3d_mode->width; + mode->Height = wined3d_mode->height; + mode->RefreshRate.Numerator = wined3d_mode->refresh_rate; + mode->RefreshRate.Denominator = 1; + mode->Format = dxgi_format_from_wined3dformat(wined3d_mode->format_id); + mode->ScanlineOrdering = wined3d_mode->scanline_ordering; + mode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ + mode->Stereo = FALSE; /* FIXME */ +} + +static HRESULT dxgi_output_find_closest_matching_mode(struct dxgi_output *output, + struct wined3d_display_mode *mode, IUnknown *device) +{ + struct dxgi_adapter *adapter; + struct wined3d *wined3d; + HRESULT hr; + + if (!mode->width != !mode->height) + return DXGI_ERROR_INVALID_CALL; + + if (mode->format_id == WINED3DFMT_UNKNOWN && !device) + return DXGI_ERROR_INVALID_CALL; + + if (mode->format_id == WINED3DFMT_UNKNOWN) + { + FIXME("Matching formats to device not implemented.\n"); + return E_NOTIMPL; + } + + wined3d_mutex_lock(); + adapter = output->adapter; + wined3d = adapter->factory->wined3d; + + hr = wined3d_find_closest_matching_adapter_mode(wined3d, adapter->ordinal, mode); + wined3d_mutex_unlock(); + + return hr; +} + +enum dxgi_mode_struct_version +{ + DXGI_MODE_STRUCT_VERSION_0, + DXGI_MODE_STRUCT_VERSION_1, +}; + +static HRESULT dxgi_output_get_display_mode_list(struct dxgi_output *output, + DXGI_FORMAT format, unsigned int *mode_count, void *modes, + enum dxgi_mode_struct_version struct_version) +{ + enum wined3d_format_id wined3d_format; + struct wined3d_display_mode mode; + unsigned int i, max_count; + struct wined3d *wined3d; + HRESULT hr; + + if (!mode_count) + return DXGI_ERROR_INVALID_CALL; + + if (format == DXGI_FORMAT_UNKNOWN) + { + *mode_count = 0; + return S_OK; + } + + wined3d_format = wined3dformat_from_dxgi_format(format); + + wined3d_mutex_lock(); + wined3d = output->adapter->factory->wined3d; + max_count = wined3d_get_adapter_mode_count(wined3d, output->adapter->ordinal, + wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN); + + if (!modes) + { + wined3d_mutex_unlock(); + *mode_count = max_count; + return S_OK; + } + + if (max_count > *mode_count) + { + wined3d_mutex_unlock(); + return DXGI_ERROR_MORE_DATA; + } + + *mode_count = max_count; + + for (i = 0; i < *mode_count; ++i) + { + if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, output->adapter->ordinal, + wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode))) + { + WARN("Failed to enum adapter mode %u, hr %#x.\n", i, hr); + wined3d_mutex_unlock(); + return hr; + } + + switch (struct_version) + { + case DXGI_MODE_STRUCT_VERSION_0: + { + DXGI_MODE_DESC *desc = modes; + dxgi_mode_from_wined3d(&desc[i], &mode); + break; + } + + case DXGI_MODE_STRUCT_VERSION_1: + { + DXGI_MODE_DESC1 *desc = modes; + dxgi_mode1_from_wined3d(&desc[i], &mode); + break; + } + } + } + wined3d_mutex_unlock(); + + return S_OK; +} + +static inline struct dxgi_output *impl_from_IDXGIOutput4(IDXGIOutput4 *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_QueryInterface(IDXGIOutput4 *iface, REFIID iid, void **object) +{ + TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + + if (IsEqualGUID(iid, &IID_IDXGIOutput4) + || IsEqualGUID(iid, &IID_IDXGIOutput3) + || IsEqualGUID(iid, &IID_IDXGIOutput2) + || IsEqualGUID(iid, &IID_IDXGIOutput1) + || IsEqualGUID(iid, &IID_IDXGIOutput) + || IsEqualGUID(iid, &IID_IDXGIObject) + || IsEqualGUID(iid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_output_AddRef(IDXGIOutput4 *iface) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + ULONG refcount = InterlockedIncrement(&output->refcount); + + TRACE("%p increasing refcount to %u.\n", output, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_output_Release(IDXGIOutput4 *iface) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + ULONG refcount = InterlockedDecrement(&output->refcount); + + TRACE("%p decreasing refcount to %u.\n", output, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&output->private_store); + IWineDXGIAdapter_Release(&output->adapter->IWineDXGIAdapter_iface); + heap_free(output); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetPrivateData(IDXGIOutput4 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&output->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetPrivateDataInterface(IDXGIOutput4 *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&output->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetPrivateData(IDXGIOutput4 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&output->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetParent(IDXGIOutput4 *iface, + REFIID riid, void **parent) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + return IWineDXGIAdapter_QueryInterface(&output->adapter->IWineDXGIAdapter_iface, riid, parent); +} + +/* IDXGIOutput methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput4 *iface, DXGI_OUTPUT_DESC *desc) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + struct wined3d_output_desc wined3d_desc; + HRESULT hr; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + return E_INVALIDARG; + + wined3d_mutex_lock(); + hr = wined3d_get_output_desc(output->adapter->factory->wined3d, + output->adapter->ordinal, &wined3d_desc); + wined3d_mutex_unlock(); + + if (FAILED(hr)) + { + WARN("Failed to get output desc, hr %#x.\n", hr); + return hr; + } + + memcpy(desc->DeviceName, wined3d_desc.device_name, sizeof(desc->DeviceName)); + desc->DesktopCoordinates = wined3d_desc.desktop_rect; + desc->AttachedToDesktop = wined3d_desc.attached_to_desktop; + desc->Rotation = wined3d_desc.rotation; + desc->Monitor = wined3d_desc.monitor; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput4 *iface, + DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *modes) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + + FIXME("iface %p, format %s, flags %#x, mode_count %p, modes %p partial stub!\n", + iface, debug_dxgi_format(format), flags, mode_count, modes); + + return dxgi_output_get_display_mode_list(output, + format, mode_count, modes, DXGI_MODE_STRUCT_VERSION_0); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput4 *iface, + const DXGI_MODE_DESC *mode, DXGI_MODE_DESC *closest_match, IUnknown *device) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + struct wined3d_display_mode wined3d_mode; + HRESULT hr; + + TRACE("iface %p, mode %p, closest_match %p, device %p.\n", + iface, mode, closest_match, device); + + TRACE("Mode: %s.\n", debug_dxgi_mode(mode)); + + wined3d_display_mode_from_dxgi(&wined3d_mode, mode); + hr = dxgi_output_find_closest_matching_mode(output, &wined3d_mode, device); + if (SUCCEEDED(hr)) + { + dxgi_mode_from_wined3d(closest_match, &wined3d_mode); + TRACE("Returning %s.\n", debug_dxgi_mode(closest_match)); + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_WaitForVBlank(IDXGIOutput4 *iface) +{ + static BOOL once = FALSE; + + if (!once++) + FIXME("iface %p stub!\n", iface); + else + TRACE("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput4 *iface, IUnknown *device, BOOL exclusive) +{ + FIXME("iface %p, device %p, exclusive %d stub!\n", iface, device, exclusive); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput4 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput4 *iface, + DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps) +{ + unsigned int i; + + TRACE("iface %p, gamma_caps %p.\n", iface, gamma_caps); + + if (!gamma_caps) + return E_INVALIDARG; + + gamma_caps->ScaleAndOffsetSupported = FALSE; + gamma_caps->MaxConvertedValue = 1.0f; + gamma_caps->MinConvertedValue = 0.0f; + gamma_caps->NumGammaControlPoints = 256; + + for (i = 0; i < gamma_caps->NumGammaControlPoints; ++i) + gamma_caps->ControlPointPositions[i] = i / 255.0f; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetGammaControl(IDXGIOutput4 *iface, + const DXGI_GAMMA_CONTROL *gamma_control) +{ + FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControl(IDXGIOutput4 *iface, + DXGI_GAMMA_CONTROL *gamma_control) +{ + FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetDisplaySurface(IDXGIOutput4 *iface, IDXGISurface *surface) +{ + FIXME("iface %p, surface %p stub!\n", iface, surface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplaySurfaceData(IDXGIOutput4 *iface, IDXGISurface *surface) +{ + FIXME("iface %p, surface %p stub!\n", iface, surface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetFrameStatistics(IDXGIOutput4 *iface, DXGI_FRAME_STATISTICS *stats) +{ + FIXME("iface %p, stats %p stub!\n", iface, stats); + + return E_NOTIMPL; +} + +/* IDXGIOutput1 methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList1(IDXGIOutput4 *iface, + DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC1 *modes) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + + FIXME("iface %p, format %s, flags %#x, mode_count %p, modes %p partial stub!\n", + iface, debug_dxgi_format(format), flags, mode_count, modes); + + return dxgi_output_get_display_mode_list(output, + format, mode_count, modes, DXGI_MODE_STRUCT_VERSION_1); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode1(IDXGIOutput4 *iface, + const DXGI_MODE_DESC1 *mode, DXGI_MODE_DESC1 *closest_match, IUnknown *device) +{ + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + struct wined3d_display_mode wined3d_mode; + HRESULT hr; + + TRACE("iface %p, mode %p, closest_match %p, device %p.\n", + iface, mode, closest_match, device); + + TRACE("Mode: %s.\n", debug_dxgi_mode1(mode)); + + wined3d_display_mode_from_dxgi1(&wined3d_mode, mode); + hr = dxgi_output_find_closest_matching_mode(output, &wined3d_mode, device); + if (SUCCEEDED(hr)) + { + dxgi_mode1_from_wined3d(closest_match, &wined3d_mode); + TRACE("Returning %s.\n", debug_dxgi_mode1(closest_match)); + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplaySurfaceData1(IDXGIOutput4 *iface, + IDXGIResource *resource) +{ + FIXME("iface %p, resource %p stub!\n", iface, resource); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_DuplicateOutput(IDXGIOutput4 *iface, + IUnknown *device, IDXGIOutputDuplication **output_duplication) +{ + FIXME("iface %p, device %p, output_duplication %p stub!\n", iface, device, output_duplication); + + return E_NOTIMPL; +} + +/* IDXGIOutput2 methods */ + +static BOOL STDMETHODCALLTYPE dxgi_output_SupportsOverlays(IDXGIOutput4 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +/* IDXGIOutput3 methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_CheckOverlaySupport(IDXGIOutput4 *iface, + DXGI_FORMAT format, IUnknown *device, UINT *flags) +{ + FIXME("iface %p, format %#x, device %p, flags %p stub!\n", iface, format, device, flags); + + return E_NOTIMPL; +} + +/* IDXGIOutput4 methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_CheckOverlayColorSpaceSupport(IDXGIOutput4 *iface, + DXGI_FORMAT format, DXGI_COLOR_SPACE_TYPE color_space, IUnknown *device, UINT *flags) +{ + FIXME("iface %p, format %#x, color_space %#x, device %p, flags %p stub!\n", + iface, format, color_space, device, flags); + + return E_NOTIMPL; +} + +static const struct IDXGIOutput4Vtbl dxgi_output_vtbl = +{ + dxgi_output_QueryInterface, + dxgi_output_AddRef, + dxgi_output_Release, + /* IDXGIObject methods */ + dxgi_output_SetPrivateData, + dxgi_output_SetPrivateDataInterface, + dxgi_output_GetPrivateData, + dxgi_output_GetParent, + /* IDXGIOutput methods */ + dxgi_output_GetDesc, + dxgi_output_GetDisplayModeList, + dxgi_output_FindClosestMatchingMode, + dxgi_output_WaitForVBlank, + dxgi_output_TakeOwnership, + dxgi_output_ReleaseOwnership, + dxgi_output_GetGammaControlCapabilities, + dxgi_output_SetGammaControl, + dxgi_output_GetGammaControl, + dxgi_output_SetDisplaySurface, + dxgi_output_GetDisplaySurfaceData, + dxgi_output_GetFrameStatistics, + /* IDXGIOutput1 methods */ + dxgi_output_GetDisplayModeList1, + dxgi_output_FindClosestMatchingMode1, + dxgi_output_GetDisplaySurfaceData1, + dxgi_output_DuplicateOutput, + /* IDXGIOutput2 methods */ + dxgi_output_SupportsOverlays, + /* IDXGIOutput3 methods */ + dxgi_output_CheckOverlaySupport, + /* IDXGIOutput4 methods */ + dxgi_output_CheckOverlayColorSpaceSupport, +}; + +struct dxgi_output *unsafe_impl_from_IDXGIOutput(IDXGIOutput *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == (IDXGIOutputVtbl *)&dxgi_output_vtbl); + return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface); +} + +static void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter) +{ + output->IDXGIOutput4_iface.lpVtbl = &dxgi_output_vtbl; + output->refcount = 1; + wined3d_private_store_init(&output->private_store); + output->adapter = adapter; + IWineDXGIAdapter_AddRef(&output->adapter->IWineDXGIAdapter_iface); +} + +HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) +{ + if (!(*output = heap_alloc_zero(sizeof(**output)))) + return E_OUTOFMEMORY; + + dxgi_output_init(*output, adapter); + return S_OK; +} diff --git a/dll/directx/wine/dxgi/surface.c b/dll/directx/wine/dxgi/surface.c new file mode 100644 index 00000000000..4b1b83b84a9 --- /dev/null +++ b/dll/directx/wine/dxgi/surface.c @@ -0,0 +1,305 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +/* Inner IUnknown methods */ + +static inline struct dxgi_surface *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_surface, IUnknown_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out) +{ + struct dxgi_surface *surface = impl_from_IUnknown(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IDXGISurface1) + || IsEqualGUID(riid, &IID_IDXGISurface) + || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IDXGISurface1_AddRef(&surface->IDXGISurface1_iface); + *out = &surface->IDXGISurface1_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_inner_AddRef(IUnknown *iface) +{ + struct dxgi_surface *surface = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&surface->refcount); + + TRACE("%p increasing refcount to %u.\n", surface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_inner_Release(IUnknown *iface) +{ + struct dxgi_surface *surface = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&surface->refcount); + + TRACE("%p decreasing refcount to %u.\n", surface, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&surface->private_store); + heap_free(surface); + } + + return refcount; +} + +static inline struct dxgi_surface *impl_from_IDXGISurface1(IDXGISurface1 *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_surface, IDXGISurface1_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface1 *iface, REFIID riid, + void **object) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_QueryInterface(surface->outer_unknown, riid, object); +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface1 *iface) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_AddRef(surface->outer_unknown); +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface1 *iface) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_Release(surface->outer_unknown); +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface1 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&surface->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateDataInterface(IDXGISurface1 *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&surface->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface1 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&surface->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface1 *iface, REFIID riid, void **parent) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + return IDXGIDevice_QueryInterface(surface->device, riid, parent); +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface1 *iface, REFIID riid, void **device) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + + TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device); + + return IDXGIDevice_QueryInterface(surface->device, riid, device); +} + +/* IDXGISurface methods */ +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDesc(IDXGISurface1 *iface, DXGI_SURFACE_DESC *desc) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + struct wined3d_resource_desc wined3d_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + wined3d_mutex_lock(); + wined3d_resource_get_desc(wined3d_texture_get_resource(surface->wined3d_texture), &wined3d_desc); + wined3d_mutex_unlock(); + desc->Width = wined3d_desc.width; + desc->Height = wined3d_desc.height; + desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format); + dxgi_sample_desc_from_wined3d(&desc->SampleDesc, wined3d_desc.multisample_type, wined3d_desc.multisample_quality); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_Map(IDXGISurface1 *iface, DXGI_MAPPED_RECT *mapped_rect, UINT flags) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + struct wined3d_map_desc wined3d_map_desc; + DWORD wined3d_map_flags = 0; + HRESULT hr; + + TRACE("iface %p, mapped_rect %p, flags %#x.\n", iface, mapped_rect, flags); + + if (flags & DXGI_MAP_READ) + wined3d_map_flags |= WINED3D_MAP_READ; + if (flags & DXGI_MAP_WRITE) + wined3d_map_flags |= WINED3D_MAP_WRITE; + if (flags & DXGI_MAP_DISCARD) + wined3d_map_flags |= WINED3D_MAP_DISCARD; + + wined3d_mutex_lock(); + if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), 0, + &wined3d_map_desc, NULL, wined3d_map_flags))) + { + mapped_rect->Pitch = wined3d_map_desc.row_pitch; + mapped_rect->pBits = wined3d_map_desc.data; + } + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface1 *iface) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), 0); + wined3d_mutex_unlock(); + + return S_OK; +} + +/* IDXGISurface1 methods */ +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDC(IDXGISurface1 *iface, BOOL discard, HDC *hdc) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + HRESULT hr; + + FIXME("iface %p, discard %d, hdc %p semi-stub!\n", iface, discard, hdc); + + if (!hdc) + return E_INVALIDARG; + + wined3d_mutex_lock(); + hr = wined3d_texture_get_dc(surface->wined3d_texture, 0, hdc); + wined3d_mutex_unlock(); + + if (SUCCEEDED(hr)) + surface->dc = *hdc; + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_ReleaseDC(IDXGISurface1 *iface, RECT *dirty_rect) +{ + struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); + HRESULT hr; + + TRACE("iface %p, rect %s\n", iface, wine_dbgstr_rect(dirty_rect)); + + if (!IsRectEmpty(dirty_rect)) + FIXME("dirty rectangle is ignored.\n"); + + wined3d_mutex_lock(); + hr = wined3d_texture_release_dc(surface->wined3d_texture, 0, surface->dc); + wined3d_mutex_unlock(); + + return hr; +} + +static const struct IDXGISurface1Vtbl dxgi_surface_vtbl = +{ + /* IUnknown methods */ + dxgi_surface_QueryInterface, + dxgi_surface_AddRef, + dxgi_surface_Release, + /* IDXGIObject methods */ + dxgi_surface_SetPrivateData, + dxgi_surface_SetPrivateDataInterface, + dxgi_surface_GetPrivateData, + dxgi_surface_GetParent, + /* IDXGIDeviceSubObject methods */ + dxgi_surface_GetDevice, + /* IDXGISurface methods */ + dxgi_surface_GetDesc, + dxgi_surface_Map, + dxgi_surface_Unmap, + /* IDXGISurface1 methods */ + dxgi_surface_GetDC, + dxgi_surface_ReleaseDC, +}; + +static const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl = +{ + /* IUnknown methods */ + dxgi_surface_inner_QueryInterface, + dxgi_surface_inner_AddRef, + dxgi_surface_inner_Release, +}; + +HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, + IUnknown *outer, struct wined3d_texture *wined3d_texture) +{ + surface->IDXGISurface1_iface.lpVtbl = &dxgi_surface_vtbl; + surface->IUnknown_iface.lpVtbl = &dxgi_surface_inner_unknown_vtbl; + surface->refcount = 1; + wined3d_private_store_init(&surface->private_store); + surface->outer_unknown = outer ? outer : &surface->IUnknown_iface; + surface->device = device; + surface->wined3d_texture = wined3d_texture; + surface->dc = NULL; + + return S_OK; +} diff --git a/dll/directx/wine/dxgi/swapchain.c b/dll/directx/wine/dxgi/swapchain.c new file mode 100644 index 00000000000..c76ad1d1359 --- /dev/null +++ b/dll/directx/wine/dxgi/swapchain.c @@ -0,0 +1,3015 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +#ifdef SONAME_LIBVKD3D +#define VK_NO_PROTOTYPES +#define VKD3D_NO_PROTOTYPES +#define VKD3D_NO_VULKAN_H +#define VKD3D_NO_WIN32_TYPES +#ifndef USE_WIN32_VULKAN +#define WINE_VK_HOST +#endif +#include "wine/library.h" +#include "wine/vulkan.h" +#include "wine/vulkan_driver.h" +#include +#endif + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); +WINE_DECLARE_DEBUG_CHANNEL(winediag); + +static DXGI_SWAP_EFFECT dxgi_swap_effect_from_wined3d(enum wined3d_swap_effect swap_effect) +{ + switch (swap_effect) + { + case WINED3D_SWAP_EFFECT_DISCARD: + return DXGI_SWAP_EFFECT_DISCARD; + case WINED3D_SWAP_EFFECT_SEQUENTIAL: + return DXGI_SWAP_EFFECT_SEQUENTIAL; + case WINED3D_SWAP_EFFECT_FLIP_DISCARD: + return DXGI_SWAP_EFFECT_FLIP_DISCARD; + case WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL: + return DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + default: + FIXME("Invalid swap effect %#x.\n", swap_effect); + return DXGI_SWAP_EFFECT_DISCARD; + } +} + +static BOOL dxgi_validate_flip_swap_effect_format(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + return TRUE; + default: + WARN("Invalid swapchain format %#x for flip presentation model.\n", format); + return FALSE; + } +} + +BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc) +{ + unsigned int min_buffer_count; + + switch (desc->SwapEffect) + { + case DXGI_SWAP_EFFECT_DISCARD: + case DXGI_SWAP_EFFECT_SEQUENTIAL: + min_buffer_count = 1; + break; + + case DXGI_SWAP_EFFECT_FLIP_DISCARD: + case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: + min_buffer_count = 2; + + if (desc->Format && !dxgi_validate_flip_swap_effect_format(desc->Format)) + return FALSE; + + if (desc->SampleDesc.Count != 1 || desc->SampleDesc.Quality) + { + WARN("Invalid sample desc %u, %u for swap effect %#x.\n", + desc->SampleDesc.Count, desc->SampleDesc.Quality, desc->SwapEffect); + return FALSE; + } + break; + + default: + WARN("Invalid swap effect %u used.\n", desc->SwapEffect); + return FALSE; + } + + if (desc->BufferCount < min_buffer_count || desc->BufferCount > DXGI_MAX_SWAP_CHAIN_BUFFERS) + { + WARN("BufferCount is %u.\n", desc->BufferCount); + return FALSE; + } + + return TRUE; +} + +static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, IDXGIOutput **dxgi_output) +{ + DXGI_OUTPUT_DESC desc; + IDXGIOutput *output; + unsigned int index; + HMONITOR monitor; + HRESULT hr; + + if (!(monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST))) + { + WARN("Failed to get monitor from window.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + index = 0; + while ((hr = IDXGIAdapter_EnumOutputs(adapter, index, &output)) == S_OK) + { + if (FAILED(hr = IDXGIOutput_GetDesc(output, &desc))) + { + WARN("Failed to get output desc %u, hr %#x.\n", index, hr); + ++index; + continue; + } + + if (desc.Monitor == monitor) + { + *dxgi_output = output; + return S_OK; + } + + IDXGIOutput_Release(output); + ++index; + } + if (hr != DXGI_ERROR_NOT_FOUND) + WARN("Failed to enumerate outputs, hr %#x.\n", hr); + + WARN("Output could not be found.\n"); + return DXGI_ERROR_NOT_FOUND; +} + +static HRESULT dxgi_swapchain_set_fullscreen_state(struct wined3d_swapchain_state *state, + const struct wined3d_swapchain_desc *swapchain_desc, IDXGIOutput *output) +{ + struct dxgi_output *dxgi_output; + struct dxgi_adapter *adapter; + HRESULT hr; + + dxgi_output = unsafe_impl_from_IDXGIOutput(output); + adapter = dxgi_output->adapter; + + wined3d_mutex_lock(); + hr = wined3d_swapchain_state_set_fullscreen(state, swapchain_desc, + adapter->factory->wined3d, adapter->ordinal, NULL); + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT dxgi_swapchain_resize_target(IDXGISwapChain1 *swapchain, + struct wined3d_swapchain_state *state, const DXGI_MODE_DESC *target_mode_desc) +{ + struct wined3d_display_mode mode; + struct dxgi_output *dxgi_output; + struct dxgi_adapter *adapter; + IDXGIOutput *output; + HRESULT hr; + + if (!target_mode_desc) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(swapchain, &output))) + return hr; + dxgi_output = unsafe_impl_from_IDXGIOutput(output); + adapter = dxgi_output->adapter; + IDXGIOutput_Release(output); + + TRACE("Mode: %s.\n", debug_dxgi_mode(target_mode_desc)); + + if (target_mode_desc->Scaling) + FIXME("Ignoring scaling %#x.\n", target_mode_desc->Scaling); + + wined3d_display_mode_from_dxgi(&mode, target_mode_desc); + + return wined3d_swapchain_state_resize_target(state, adapter->factory->wined3d, adapter->ordinal, &mode); +} + +static HWND d3d11_swapchain_get_hwnd(struct d3d11_swapchain *swapchain) +{ + struct wined3d_swapchain_desc wined3d_desc; + + wined3d_mutex_lock(); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); + wined3d_mutex_unlock(); + + return wined3d_desc.device_window; +} + +static inline struct d3d11_swapchain *d3d11_swapchain_from_IDXGISwapChain1(IDXGISwapChain1 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_swapchain, IDXGISwapChain1_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_QueryInterface(IDXGISwapChain1 *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject) + || IsEqualGUID(riid, &IID_IDXGISwapChain) + || IsEqualGUID(riid, &IID_IDXGISwapChain1)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_swapchain_AddRef(IDXGISwapChain1 *iface) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + ULONG refcount = InterlockedIncrement(&swapchain->refcount); + + TRACE("%p increasing refcount to %u.\n", swapchain, refcount); + + if (refcount == 1) + wined3d_swapchain_incref(swapchain->wined3d_swapchain); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_swapchain_Release(IDXGISwapChain1 *iface) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + ULONG refcount = InterlockedDecrement(&swapchain->refcount); + + TRACE("%p decreasing refcount to %u.\n", swapchain, refcount); + + if (!refcount) + { + IWineDXGIDevice *device = swapchain->device; + if (swapchain->target) + { + WARN("Releasing fullscreen swapchain.\n"); + IDXGIOutput_Release(swapchain->target); + } + if (swapchain->factory) + IDXGIFactory_Release(swapchain->factory); + wined3d_swapchain_decref(swapchain->wined3d_swapchain); + if (device) + IWineDXGIDevice_Release(device); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_SetPrivateData(IDXGISwapChain1 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&swapchain->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_SetPrivateDataInterface(IDXGISwapChain1 *iface, + REFGUID guid, const IUnknown *object) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&swapchain->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetPrivateData(IDXGISwapChain1 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&swapchain->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetParent(IDXGISwapChain1 *iface, REFIID riid, void **parent) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + if (!swapchain->factory) + { + ERR("Implicit swapchain does not store reference to parent.\n"); + *parent = NULL; + return E_NOINTERFACE; + } + + return IDXGIFactory_QueryInterface(swapchain->factory, riid, parent); +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDevice(IDXGISwapChain1 *iface, REFIID riid, void **device) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device); + + if (!swapchain->device) + { + ERR("Implicit swapchain does not store reference to device.\n"); + *device = NULL; + return E_NOINTERFACE; + } + + return IWineDXGIDevice_QueryInterface(swapchain->device, riid, device); +} + +/* IDXGISwapChain1 methods */ + +static HRESULT d3d11_swapchain_present(struct d3d11_swapchain *swapchain, + unsigned int sync_interval, unsigned int flags) +{ + if (sync_interval > 4) + { + WARN("Invalid sync interval %u.\n", sync_interval); + return DXGI_ERROR_INVALID_CALL; + } + + if (IsIconic(d3d11_swapchain_get_hwnd(swapchain))) + return DXGI_STATUS_OCCLUDED; + + if (flags & ~DXGI_PRESENT_TEST) + FIXME("Unimplemented flags %#x.\n", flags); + if (flags & DXGI_PRESENT_TEST) + { + WARN("Returning S_OK for DXGI_PRESENT_TEST.\n"); + return S_OK; + } + + return wined3d_swapchain_present(swapchain->wined3d_swapchain, NULL, NULL, NULL, sync_interval, 0); +} + +static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_Present(IDXGISwapChain1 *iface, UINT sync_interval, UINT flags) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, sync_interval %u, flags %#x.\n", iface, sync_interval, flags); + + return d3d11_swapchain_present(swapchain, sync_interval, flags); +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetBuffer(IDXGISwapChain1 *iface, + UINT buffer_idx, REFIID riid, void **surface) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_texture *texture; + IUnknown *parent; + HRESULT hr; + + TRACE("iface %p, buffer_idx %u, riid %s, surface %p\n", + iface, buffer_idx, debugstr_guid(riid), surface); + + wined3d_mutex_lock(); + + if (!(texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, buffer_idx))) + { + wined3d_mutex_unlock(); + return DXGI_ERROR_INVALID_CALL; + } + + parent = wined3d_texture_get_parent(texture); + hr = IUnknown_QueryInterface(parent, riid, surface); + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreenState(IDXGISwapChain1 *iface, + BOOL fullscreen, IDXGIOutput *target) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_desc swapchain_desc; + struct wined3d_swapchain_state *state; + HRESULT hr; + + TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); + + if (!fullscreen && target) + { + WARN("Invalid call.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (target) + { + IDXGIOutput_AddRef(target); + } + else if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(iface, &target))) + { + WARN("Failed to get target output for swapchain, hr %#x.\n", hr); + return hr; + } + + wined3d_mutex_lock(); + state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &swapchain_desc); + swapchain_desc.windowed = !fullscreen; + hr = dxgi_swapchain_set_fullscreen_state(state, &swapchain_desc, target); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + IDXGIOutput_Release(target); + + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + } + + if (!fullscreen) + { + IDXGIOutput_Release(target); + target = NULL; + } + + if (swapchain->target) + IDXGIOutput_Release(swapchain->target); + swapchain->target = target; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFullscreenState(IDXGISwapChain1 *iface, + BOOL *fullscreen, IDXGIOutput **target) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_desc swapchain_desc; + HRESULT hr; + + TRACE("iface %p, fullscreen %p, target %p.\n", iface, fullscreen, target); + + if (fullscreen || target) + { + wined3d_mutex_lock(); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &swapchain_desc); + wined3d_mutex_unlock(); + } + + if (fullscreen) + *fullscreen = !swapchain_desc.windowed; + + if (target) + { + if (!swapchain_desc.windowed) + { + if (!swapchain->target && FAILED(hr = IDXGISwapChain1_GetContainingOutput(iface, &swapchain->target))) + return hr; + + *target = swapchain->target; + IDXGIOutput_AddRef(*target); + } + else + { + *target = NULL; + } + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDesc(IDXGISwapChain1 *iface, DXGI_SWAP_CHAIN_DESC *desc) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_desc wined3d_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); + wined3d_mutex_unlock(); + + FIXME("Ignoring ScanlineOrdering and Scaling.\n"); + + desc->BufferDesc.Width = wined3d_desc.backbuffer_width; + desc->BufferDesc.Height = wined3d_desc.backbuffer_height; + desc->BufferDesc.RefreshRate.Numerator = wined3d_desc.refresh_rate; + desc->BufferDesc.RefreshRate.Denominator = 1; + desc->BufferDesc.Format = dxgi_format_from_wined3dformat(wined3d_desc.backbuffer_format); + desc->BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + desc->BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + dxgi_sample_desc_from_wined3d(&desc->SampleDesc, + wined3d_desc.multisample_type, wined3d_desc.multisample_quality); + desc->BufferUsage = dxgi_usage_from_wined3d_bind_flags(wined3d_desc.backbuffer_bind_flags); + desc->BufferCount = wined3d_desc.backbuffer_count; + desc->OutputWindow = wined3d_desc.device_window; + desc->Windowed = wined3d_desc.windowed; + desc->SwapEffect = dxgi_swap_effect_from_wined3d(wined3d_desc.swap_effect); + desc->Flags = dxgi_swapchain_flags_from_wined3d(wined3d_desc.flags); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeBuffers(IDXGISwapChain1 *iface, + UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_desc wined3d_desc; + struct wined3d_texture *texture; + IUnknown *parent; + unsigned int i; + HRESULT hr; + + TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x.\n", + iface, buffer_count, width, height, debug_dxgi_format(format), flags); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + wined3d_mutex_lock(); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); + for (i = 0; i < wined3d_desc.backbuffer_count; ++i) + { + texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, i); + parent = wined3d_texture_get_parent(texture); + IUnknown_AddRef(parent); + if (IUnknown_Release(parent)) + { + wined3d_mutex_unlock(); + return DXGI_ERROR_INVALID_CALL; + } + } + if (format != DXGI_FORMAT_UNKNOWN) + wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(format); + hr = wined3d_swapchain_resize_buffers(swapchain->wined3d_swapchain, buffer_count, width, height, + wined3d_desc.backbuffer_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality); + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *iface, + const DXGI_MODE_DESC *target_mode_desc) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_state *state; + + TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc); + + state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); + + return dxgi_swapchain_resize_target(iface, state, target_mode_desc); +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapChain1 *iface, IDXGIOutput **output) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + IDXGIAdapter *adapter; + IDXGIDevice *device; + HRESULT hr; + + TRACE("iface %p, output %p.\n", iface, output); + + if (swapchain->target) + { + IDXGIOutput_AddRef(*output = swapchain->target); + return S_OK; + } + + if (SUCCEEDED(hr = d3d11_swapchain_GetDevice(iface, &IID_IDXGIDevice, (void **)&device))) + { + hr = IDXGIDevice_GetAdapter(device, &adapter); + IDXGIDevice_Release(device); + } + + if (SUCCEEDED(hr)) + { + HWND hwnd = d3d11_swapchain_get_hwnd(swapchain); + hr = dxgi_get_output_from_window(adapter, hwnd, output); + IDXGIAdapter_Release(adapter); + } + else + { + WARN("Failed to get adapter, hr %#x.\n", hr); + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFrameStatistics(IDXGISwapChain1 *iface, + DXGI_FRAME_STATISTICS *stats) +{ + FIXME("iface %p, stats %p stub!\n", iface, stats); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetLastPresentCount(IDXGISwapChain1 *iface, + UINT *last_present_count) +{ + FIXME("iface %p, last_present_count %p stub!\n", iface, last_present_count); + + return E_NOTIMPL; +} + +/* IDXGISwapChain1 methods */ + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDesc1(IDXGISwapChain1 *iface, DXGI_SWAP_CHAIN_DESC1 *desc) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_desc wined3d_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); + wined3d_mutex_unlock(); + + FIXME("Ignoring Stereo, Scaling and AlphaMode.\n"); + + desc->Width = wined3d_desc.backbuffer_width; + desc->Height = wined3d_desc.backbuffer_height; + desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.backbuffer_format); + desc->Stereo = FALSE; + dxgi_sample_desc_from_wined3d(&desc->SampleDesc, + wined3d_desc.multisample_type, wined3d_desc.multisample_quality); + desc->BufferUsage = dxgi_usage_from_wined3d_bind_flags(wined3d_desc.backbuffer_bind_flags); + desc->BufferCount = wined3d_desc.backbuffer_count; + desc->Scaling = DXGI_SCALING_STRETCH; + desc->SwapEffect = dxgi_swap_effect_from_wined3d(wined3d_desc.swap_effect); + desc->AlphaMode = DXGI_ALPHA_MODE_IGNORE; + desc->Flags = dxgi_swapchain_flags_from_wined3d(wined3d_desc.flags); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFullscreenDesc(IDXGISwapChain1 *iface, + DXGI_SWAP_CHAIN_FULLSCREEN_DESC *desc) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + struct wined3d_swapchain_desc wined3d_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); + wined3d_mutex_unlock(); + + FIXME("Ignoring ScanlineOrdering and Scaling.\n"); + + desc->RefreshRate.Numerator = wined3d_desc.refresh_rate; + desc->RefreshRate.Denominator = 1; + desc->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + desc->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + desc->Windowed = wined3d_desc.windowed; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetHwnd(IDXGISwapChain1 *iface, HWND *hwnd) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, hwnd %p.\n", iface, hwnd); + + if (!hwnd) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + *hwnd = d3d11_swapchain_get_hwnd(swapchain); + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetCoreWindow(IDXGISwapChain1 *iface, + REFIID iid, void **core_window) +{ + FIXME("iface %p, iid %s, core_window %p stub!\n", iface, debugstr_guid(iid), core_window); + + if (core_window) + *core_window = NULL; + + return DXGI_ERROR_INVALID_CALL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_Present1(IDXGISwapChain1 *iface, + UINT sync_interval, UINT flags, const DXGI_PRESENT_PARAMETERS *present_parameters) +{ + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + + TRACE("iface %p, sync_interval %u, flags %#x, present_parameters %p.\n", + iface, sync_interval, flags, present_parameters); + + if (present_parameters) + FIXME("Ignored present parameters %p.\n", present_parameters); + + return d3d11_swapchain_present(swapchain, sync_interval, flags); +} + +static BOOL STDMETHODCALLTYPE d3d11_swapchain_IsTemporaryMonoSupported(IDXGISwapChain1 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetRestrictToOutput(IDXGISwapChain1 *iface, IDXGIOutput **output) +{ + FIXME("iface %p, output %p stub!\n", iface, output); + + if (!output) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + *output = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_SetBackgroundColor(IDXGISwapChain1 *iface, const DXGI_RGBA *color) +{ + FIXME("iface %p, color %p stub!\n", iface, color); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetBackgroundColor(IDXGISwapChain1 *iface, DXGI_RGBA *color) +{ + FIXME("iface %p, color %p stub!\n", iface, color); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_SetRotation(IDXGISwapChain1 *iface, DXGI_MODE_ROTATION rotation) +{ + FIXME("iface %p, rotation %#x stub!\n", iface, rotation); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetRotation(IDXGISwapChain1 *iface, DXGI_MODE_ROTATION *rotation) +{ + FIXME("iface %p, rotation %p stub!\n", iface, rotation); + + return E_NOTIMPL; +} + +static const struct IDXGISwapChain1Vtbl d3d11_swapchain_vtbl = +{ + /* IUnknown methods */ + d3d11_swapchain_QueryInterface, + d3d11_swapchain_AddRef, + d3d11_swapchain_Release, + /* IDXGIObject methods */ + d3d11_swapchain_SetPrivateData, + d3d11_swapchain_SetPrivateDataInterface, + d3d11_swapchain_GetPrivateData, + d3d11_swapchain_GetParent, + /* IDXGIDeviceSubObject methods */ + d3d11_swapchain_GetDevice, + /* IDXGISwapChain methods */ + d3d11_swapchain_Present, + d3d11_swapchain_GetBuffer, + d3d11_swapchain_SetFullscreenState, + d3d11_swapchain_GetFullscreenState, + d3d11_swapchain_GetDesc, + d3d11_swapchain_ResizeBuffers, + d3d11_swapchain_ResizeTarget, + d3d11_swapchain_GetContainingOutput, + d3d11_swapchain_GetFrameStatistics, + d3d11_swapchain_GetLastPresentCount, + /* IDXGISwapChain1 methods */ + d3d11_swapchain_GetDesc1, + d3d11_swapchain_GetFullscreenDesc, + d3d11_swapchain_GetHwnd, + d3d11_swapchain_GetCoreWindow, + d3d11_swapchain_Present1, + d3d11_swapchain_IsTemporaryMonoSupported, + d3d11_swapchain_GetRestrictToOutput, + d3d11_swapchain_SetBackgroundColor, + d3d11_swapchain_GetBackgroundColor, + d3d11_swapchain_SetRotation, + d3d11_swapchain_GetRotation, +}; + +static void STDMETHODCALLTYPE d3d11_swapchain_wined3d_object_released(void *parent) +{ + struct d3d11_swapchain *swapchain = parent; + + wined3d_private_store_cleanup(&swapchain->private_store); + heap_free(parent); +} + +static const struct wined3d_parent_ops d3d11_swapchain_wined3d_parent_ops = +{ + d3d11_swapchain_wined3d_object_released, +}; + +HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device, + struct wined3d_swapchain_desc *desc) +{ + BOOL fullscreen; + HRESULT hr; + + /* A reference to the implicit swapchain is held by the wined3d device. In + * order to avoid circular references we do not keep a reference to the + * device in the implicit swapchain. */ + if (!(desc->flags & WINED3D_SWAPCHAIN_IMPLICIT)) + { + if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) + return E_INVALIDARG; + + if (FAILED(hr = IWineDXGIAdapter_GetParent(device->adapter, &IID_IDXGIFactory, + (void **)&swapchain->factory))) + { + WARN("Failed to get adapter parent, hr %#x.\n", hr); + return hr; + } + IWineDXGIDevice_AddRef(swapchain->device = &device->IWineDXGIDevice_iface); + } + else + { + swapchain->device = NULL; + swapchain->factory = NULL; + } + + swapchain->IDXGISwapChain1_iface.lpVtbl = &d3d11_swapchain_vtbl; + swapchain->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&swapchain->private_store); + + if (!desc->windowed && (!desc->backbuffer_width || !desc->backbuffer_height)) + FIXME("Fullscreen swapchain with back buffer width/height equal to 0 not supported properly.\n"); + + fullscreen = !desc->windowed; + desc->windowed = TRUE; + if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, + &d3d11_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) + { + WARN("Failed to create wined3d swapchain, hr %#x.\n", hr); + goto cleanup; + } + + swapchain->target = NULL; + if (fullscreen) + { + struct wined3d_swapchain_state *state; + + desc->windowed = FALSE; + state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); + + if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(&swapchain->IDXGISwapChain1_iface, + &swapchain->target))) + { + WARN("Failed to get target output for fullscreen swapchain, hr %#x.\n", hr); + wined3d_swapchain_decref(swapchain->wined3d_swapchain); + goto cleanup; + } + + if (FAILED(hr = dxgi_swapchain_set_fullscreen_state(state, desc, swapchain->target))) + { + WARN("Failed to set fullscreen state, hr %#x.\n", hr); + IDXGIOutput_Release(swapchain->target); + wined3d_swapchain_decref(swapchain->wined3d_swapchain); + goto cleanup; + } + + } + wined3d_mutex_unlock(); + + return S_OK; + +cleanup: + wined3d_private_store_cleanup(&swapchain->private_store); + wined3d_mutex_unlock(); + if (swapchain->factory) + IDXGIFactory_Release(swapchain->factory); + if (swapchain->device) + IWineDXGIDevice_Release(swapchain->device); + return hr; +} + +#ifdef SONAME_LIBVKD3D + +#ifdef USE_WIN32_VULKAN + +static void *load_library(const char *name) +{ + return LoadLibraryA(name); +} + +static void *get_library_proc(void *handle, const char *name) +{ + return (void *)GetProcAddress(handle, name); +} + +static void close_library(void *handle) +{ + if (handle) + FreeLibrary(handle); +} + +static PFN_vkGetInstanceProcAddr load_vulkan(void **vulkan_handle) +{ + *vulkan_handle = LoadLibraryA("vulkan-1.dll"); + return (void *)GetProcAddress(*vulkan_handle, "vkGetInstanceProcAddr"); +} + +#else + +static void *load_library(const char *name) +{ + return wine_dlopen(name, RTLD_NOW, NULL, 0); +} + +static void *get_library_proc(void *handle, const char *name) +{ + return wine_dlsym(handle, name, NULL, 0); +} + +static void close_library(void *handle) +{ + if (handle) + wine_dlclose(handle, NULL, 0); +} + +static PFN_vkGetInstanceProcAddr load_vulkan(void **vulkan_handle) +{ + const struct vulkan_funcs *vk_funcs; + HDC hdc; + + *vulkan_handle = NULL; + + hdc = GetDC(0); + vk_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); + ReleaseDC(0, hdc); + + if (vk_funcs) + return (PFN_vkGetInstanceProcAddr)vk_funcs->p_vkGetInstanceProcAddr; + + return NULL; +} + +#endif /* USE_WIN32_VULKAN */ + +static PFN_vkd3d_acquire_vk_queue vkd3d_acquire_vk_queue; +static PFN_vkd3d_create_image_resource vkd3d_create_image_resource; +static PFN_vkd3d_get_device_parent vkd3d_get_device_parent; +static PFN_vkd3d_get_vk_device vkd3d_get_vk_device; +static PFN_vkd3d_get_vk_format vkd3d_get_vk_format; +static PFN_vkd3d_get_vk_physical_device vkd3d_get_vk_physical_device; +static PFN_vkd3d_get_vk_queue_family_index vkd3d_get_vk_queue_family_index; +static PFN_vkd3d_instance_from_device vkd3d_instance_from_device; +static PFN_vkd3d_instance_get_vk_instance vkd3d_instance_get_vk_instance; +static PFN_vkd3d_release_vk_queue vkd3d_release_vk_queue; +static PFN_vkd3d_resource_decref vkd3d_resource_decref; +static PFN_vkd3d_resource_incref vkd3d_resource_incref; + +struct dxgi_vk_funcs +{ + PFN_vkAcquireNextImageKHR p_vkAcquireNextImageKHR; + PFN_vkAllocateCommandBuffers p_vkAllocateCommandBuffers; + PFN_vkAllocateMemory p_vkAllocateMemory; + PFN_vkBeginCommandBuffer p_vkBeginCommandBuffer; + PFN_vkBindImageMemory p_vkBindImageMemory; + PFN_vkCmdBlitImage p_vkCmdBlitImage; + PFN_vkCmdPipelineBarrier p_vkCmdPipelineBarrier; + PFN_vkCreateCommandPool p_vkCreateCommandPool; + PFN_vkCreateFence p_vkCreateFence; + PFN_vkCreateImage p_vkCreateImage; + PFN_vkCreateSemaphore p_vkCreateSemaphore; + PFN_vkCreateSwapchainKHR p_vkCreateSwapchainKHR; + PFN_vkCreateWin32SurfaceKHR p_vkCreateWin32SurfaceKHR; + PFN_vkDestroyCommandPool p_vkDestroyCommandPool; + PFN_vkDestroyFence p_vkDestroyFence; + PFN_vkDestroyImage p_vkDestroyImage; + PFN_vkDestroySemaphore p_vkDestroySemaphore; + PFN_vkDestroySurfaceKHR p_vkDestroySurfaceKHR; + PFN_vkResetCommandBuffer p_vkResetCommandBuffer; + PFN_vkDestroySwapchainKHR p_vkDestroySwapchainKHR; + PFN_vkEndCommandBuffer p_vkEndCommandBuffer; + PFN_vkFreeMemory p_vkFreeMemory; + PFN_vkGetImageMemoryRequirements p_vkGetImageMemoryRequirements; + PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr; + PFN_vkGetPhysicalDeviceMemoryProperties p_vkGetPhysicalDeviceMemoryProperties; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR p_vkGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR p_vkGetPhysicalDeviceSurfacePresentModesKHR; + PFN_vkGetPhysicalDeviceSurfaceSupportKHR p_vkGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR p_vkGetPhysicalDeviceWin32PresentationSupportKHR; + PFN_vkGetSwapchainImagesKHR p_vkGetSwapchainImagesKHR; + PFN_vkQueuePresentKHR p_vkQueuePresentKHR; + PFN_vkQueueSubmit p_vkQueueSubmit; + PFN_vkQueueWaitIdle p_vkQueueWaitIdle; + PFN_vkResetFences p_vkResetFences; + PFN_vkWaitForFences p_vkWaitForFences; + + void *vulkan_module; +}; + +static HRESULT hresult_from_vk_result(VkResult vr) +{ + switch (vr) + { + case VK_SUCCESS: + return S_OK; + case VK_ERROR_OUT_OF_HOST_MEMORY: + case VK_ERROR_OUT_OF_DEVICE_MEMORY: + return E_OUTOFMEMORY; + default: + FIXME("Unhandled VkResult %d.\n", vr); + return E_FAIL; + } +} + +#define INVALID_VK_IMAGE_INDEX (~(uint32_t)0) + +struct d3d12_swapchain +{ + IDXGISwapChain3 IDXGISwapChain3_iface; + LONG refcount; + struct wined3d_private_store private_store; + + struct wined3d_swapchain_state *state; + + VkSwapchainKHR vk_swapchain; + VkSurfaceKHR vk_surface; + VkFence vk_fence; + VkInstance vk_instance; + VkDevice vk_device; + VkPhysicalDevice vk_physical_device; + VkDeviceMemory vk_memory; + VkCommandPool vk_cmd_pool; + VkImage vk_images[DXGI_MAX_SWAP_CHAIN_BUFFERS]; + VkImage vk_swapchain_images[DXGI_MAX_SWAP_CHAIN_BUFFERS]; + VkCommandBuffer vk_cmd_buffers[DXGI_MAX_SWAP_CHAIN_BUFFERS]; + VkSemaphore vk_semaphores[DXGI_MAX_SWAP_CHAIN_BUFFERS]; + ID3D12Resource *buffers[DXGI_MAX_SWAP_CHAIN_BUFFERS]; + unsigned int buffer_count; + unsigned int vk_swapchain_width; + unsigned int vk_swapchain_height; + VkPresentModeKHR present_mode; + + uint32_t vk_image_index; + unsigned int current_buffer_index; + struct dxgi_vk_funcs vk_funcs; + + ID3D12CommandQueue *command_queue; + ID3D12Device *device; + IWineDXGIFactory *factory; + + HWND window; + IDXGIOutput *target; + DXGI_SWAP_CHAIN_DESC1 desc; + DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; +}; + +static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) +{ + switch (vk_format) + { + case VK_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM; + case VK_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return DXGI_FORMAT_R10G10B10A2_UNORM; + case VK_FORMAT_R16G16B16A16_SFLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + default: + WARN("Unhandled format %#x.\n", vk_format); + return DXGI_FORMAT_UNKNOWN; + } +} + +static VkFormat get_swapchain_fallback_format(VkFormat vk_format) +{ + switch (vk_format) + { + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + case VK_FORMAT_R16G16B16A16_SFLOAT: + return VK_FORMAT_B8G8R8A8_UNORM; + default: + WARN("Unhandled format %#x.\n", vk_format); + return VK_FORMAT_UNDEFINED; + } +} + +static HRESULT select_vk_format(const struct dxgi_vk_funcs *vk_funcs, + VkPhysicalDevice vk_physical_device, VkSurfaceKHR vk_surface, + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, VkFormat *vk_format) +{ + VkSurfaceFormatKHR *formats; + uint32_t format_count; + VkFormat format; + unsigned int i; + VkResult vr; + + *vk_format = VK_FORMAT_UNDEFINED; + + format = vkd3d_get_vk_format(swapchain_desc->Format); + + vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(vk_physical_device, vk_surface, &format_count, NULL); + if (vr < 0 || !format_count) + { + WARN("Failed to get supported surface formats, vr %d.\n", vr); + return DXGI_ERROR_INVALID_CALL; + } + + if (!(formats = heap_calloc(format_count, sizeof(*formats)))) + return E_OUTOFMEMORY; + + if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(vk_physical_device, + vk_surface, &format_count, formats)) < 0) + { + WARN("Failed to enumerate supported surface formats, vr %d.\n", vr); + heap_free(formats); + return hresult_from_vk_result(vr); + } + + for (i = 0; i < format_count; ++i) + { + if (formats[i].format == format && formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + break; + } + if (i == format_count) + { + /* Try to create a swapchain with format conversion. */ + format = get_swapchain_fallback_format(format); + WARN("Failed to find Vulkan swapchain format for %s.\n", debug_dxgi_format(swapchain_desc->Format)); + for (i = 0; i < format_count; ++i) + { + if (formats[i].format == format && formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + { + format = formats[i].format; + break; + } + } + } + heap_free(formats); + if (i == format_count) + { + FIXME("Failed to find Vulkan swapchain format for %s.\n", debug_dxgi_format(swapchain_desc->Format)); + return DXGI_ERROR_UNSUPPORTED; + } + + TRACE("Using Vulkan swapchain format %#x.\n", format); + + *vk_format = format; + return S_OK; +} + +static HRESULT vk_select_memory_type(const struct dxgi_vk_funcs *vk_funcs, + VkPhysicalDevice vk_physical_device, uint32_t memory_type_mask, + VkMemoryPropertyFlags flags, uint32_t *memory_type_index) +{ + VkPhysicalDeviceMemoryProperties memory_properties; + unsigned int i; + + vk_funcs->p_vkGetPhysicalDeviceMemoryProperties(vk_physical_device, &memory_properties); + for (i = 0; i < memory_properties.memoryTypeCount; ++i) + { + if (!(memory_type_mask & (1u << i))) + continue; + + if ((memory_properties.memoryTypes[i].propertyFlags & flags) == flags) + { + *memory_type_index = i; + return S_OK; + } + } + + FIXME("Failed to find memory type (allowed types %#x).\n", memory_type_mask); + return E_FAIL; +} + +static BOOL d3d12_swapchain_is_present_mode_supported(struct d3d12_swapchain *swapchain, + VkPresentModeKHR present_mode) +{ + VkPhysicalDevice vk_physical_device = swapchain->vk_physical_device; + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkPresentModeKHR *modes; + uint32_t count, i; + BOOL supported; + VkResult vr; + + if (present_mode == VK_PRESENT_MODE_FIFO_KHR) + return TRUE; + + if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfacePresentModesKHR(vk_physical_device, + swapchain->vk_surface, &count, NULL)) < 0) + { + WARN("Failed to get count of available present modes, vr %d.\n", vr); + return FALSE; + } + + supported = FALSE; + + if (!(modes = heap_calloc(count, sizeof(*modes)))) + return FALSE; + if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfacePresentModesKHR(vk_physical_device, + swapchain->vk_surface, &count, modes)) >= 0) + { + for (i = 0; i < count; ++i) + { + if (modes[i] == present_mode) + { + supported = TRUE; + break; + } + } + } + else + { + WARN("Failed to get available present modes, vr %d.\n", vr); + } + heap_free(modes); + + return supported; +} + +static BOOL d3d12_swapchain_has_user_images(struct d3d12_swapchain *swapchain) +{ + return !!swapchain->vk_images[0]; +} + +static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapchain, VkFormat vk_format) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkDeviceSize image_offset[DXGI_MAX_SWAP_CHAIN_BUFFERS]; + VkDevice vk_device = swapchain->vk_device; + VkMemoryAllocateInfo allocate_info; + VkMemoryRequirements requirements; + VkImageCreateInfo image_info; + uint32_t memory_type_mask; + VkDeviceSize memory_size; + unsigned int i; + VkResult vr; + HRESULT hr; + + if (d3d12_swapchain_has_user_images(swapchain)) + return S_OK; + + memset(&image_info, 0, sizeof(image_info)); + image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.format = vk_format; + image_info.extent.width = swapchain->desc.Width; + image_info.extent.height = swapchain->desc.Height; + image_info.extent.depth = 1; + image_info.mipLevels = 1; + image_info.arrayLayers = 1; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT + | VK_IMAGE_USAGE_TRANSFER_DST_BIT + | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_info.queueFamilyIndexCount = 0; + image_info.pQueueFamilyIndices = NULL; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + for (i = 0; i < swapchain->desc.BufferCount; ++i) + { + assert(swapchain->vk_images[i] == VK_NULL_HANDLE); + if ((vr = vk_funcs->p_vkCreateImage(vk_device, &image_info, NULL, &swapchain->vk_images[i])) < 0) + { + WARN("Failed to create Vulkan image, vr %d.\n", vr); + swapchain->vk_images[i] = VK_NULL_HANDLE; + return hresult_from_vk_result(vr); + } + } + + memory_size = 0; + memory_type_mask = ~0u; + for (i = 0; i < swapchain->desc.BufferCount; ++i) + { + vk_funcs->p_vkGetImageMemoryRequirements(vk_device, swapchain->vk_images[i], &requirements); + + TRACE("Size %s, alignment %s, memory types %#x.\n", + wine_dbgstr_longlong(requirements.size), wine_dbgstr_longlong(requirements.alignment), + requirements.memoryTypeBits); + + image_offset[i] = (memory_size + (requirements.alignment - 1)) & ~(requirements.alignment - 1); + memory_size = image_offset[i] + requirements.size; + + memory_type_mask &= requirements.memoryTypeBits; + } + + TRACE("Allocating %s bytes for user images.\n", wine_dbgstr_longlong(memory_size)); + + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.pNext = NULL; + allocate_info.allocationSize = memory_size; + + if (FAILED(hr = vk_select_memory_type(vk_funcs, swapchain->vk_physical_device, + memory_type_mask, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &allocate_info.memoryTypeIndex))) + return hr; + + assert(swapchain->vk_memory == VK_NULL_HANDLE); + if ((vr = vk_funcs->p_vkAllocateMemory(vk_device, &allocate_info, NULL, &swapchain->vk_memory)) < 0) + { + WARN("Failed to allocate device memory, vr %d.\n", vr); + swapchain->vk_memory = VK_NULL_HANDLE; + return hresult_from_vk_result(vr); + } + + for (i = 0; i < swapchain->desc.BufferCount; ++i) + { + if ((vr = vk_funcs->p_vkBindImageMemory(vk_device, swapchain->vk_images[i], + swapchain->vk_memory, image_offset[i])) < 0) + { + WARN("Failed to bind image memory, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + } + + return S_OK; +} + +static void vk_cmd_image_barrier(const struct dxgi_vk_funcs *vk_funcs, VkCommandBuffer cmd_buffer, + VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, + VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask, + VkImageLayout old_layout, VkImageLayout new_layout, VkImage image) +{ + VkImageMemoryBarrier barrier; + + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.pNext = NULL; + barrier.srcAccessMask = src_access_mask; + barrier.dstAccessMask = dst_access_mask; + barrier.oldLayout = old_layout; + barrier.newLayout = new_layout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + + vk_funcs->p_vkCmdPipelineBarrier(cmd_buffer, + src_stage_mask, dst_stage_mask, 0, 0, NULL, 0, NULL, 1, &barrier); +} + +static VkResult d3d12_swapchain_record_swapchain_blit(struct d3d12_swapchain *swapchain, + VkCommandBuffer vk_cmd_buffer, VkImage vk_dst_image, VkImage vk_src_image) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkCommandBufferBeginInfo begin_info; + VkImageBlit blit; + VkFilter filter; + VkResult vr; + + if (swapchain->desc.Width != swapchain->vk_swapchain_width + || swapchain->desc.Height != swapchain->vk_swapchain_height) + filter = VK_FILTER_LINEAR; + else + filter = VK_FILTER_NEAREST; + + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.pNext = NULL; + begin_info.flags = 0; + begin_info.pInheritanceInfo = NULL; + + if ((vr = vk_funcs->p_vkBeginCommandBuffer(vk_cmd_buffer, &begin_info)) < 0) + { + WARN("Failed to begin command buffer, vr %d.\n", vr); + return vr; + } + + vk_cmd_image_barrier(vk_funcs, vk_cmd_buffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_dst_image); + + blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + blit.srcSubresource.mipLevel = 0; + blit.srcSubresource.baseArrayLayer = 0; + blit.srcSubresource.layerCount = 1; + blit.srcOffsets[0].x = 0; + blit.srcOffsets[0].y = 0; + blit.srcOffsets[0].z = 0; + blit.srcOffsets[1].x = swapchain->desc.Width; + blit.srcOffsets[1].y = swapchain->desc.Height; + blit.srcOffsets[1].z = 1; + blit.dstSubresource = blit.srcSubresource; + blit.dstOffsets[0].x = 0; + blit.dstOffsets[0].y = 0; + blit.dstOffsets[0].z = 0; + blit.dstOffsets[1].x = swapchain->vk_swapchain_width; + blit.dstOffsets[1].y = swapchain->vk_swapchain_height; + blit.dstOffsets[1].z = 1; + + vk_funcs->p_vkCmdBlitImage(vk_cmd_buffer, + vk_src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vk_dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &blit, filter); + + vk_cmd_image_barrier(vk_funcs, vk_cmd_buffer, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, 0, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, vk_dst_image); + + if ((vr = vk_funcs->p_vkEndCommandBuffer(vk_cmd_buffer)) < 0) + WARN("Failed to end command buffer, vr %d.\n", vr); + + return vr; +} + +static HRESULT d3d12_swapchain_prepare_command_buffers(struct d3d12_swapchain *swapchain, + uint32_t queue_family_index) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkDevice vk_device = swapchain->vk_device; + VkCommandBufferAllocateInfo allocate_info; + VkSemaphoreCreateInfo semaphore_info; + VkCommandPoolCreateInfo pool_info; + unsigned int i; + VkResult vr; + + pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + pool_info.pNext = NULL; + pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + pool_info.queueFamilyIndex = queue_family_index; + + assert(swapchain->vk_cmd_pool == VK_NULL_HANDLE); + if ((vr = vk_funcs->p_vkCreateCommandPool(vk_device, &pool_info, + NULL, &swapchain->vk_cmd_pool)) < 0) + { + WARN("Failed to create command pool, vr %d.\n", vr); + swapchain->vk_cmd_pool = VK_NULL_HANDLE; + return hresult_from_vk_result(vr); + } + + allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocate_info.pNext = NULL; + allocate_info.commandPool = swapchain->vk_cmd_pool; + allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocate_info.commandBufferCount = swapchain->buffer_count; + + if ((vr = vk_funcs->p_vkAllocateCommandBuffers(vk_device, &allocate_info, + swapchain->vk_cmd_buffers)) < 0) + { + WARN("Failed to allocate command buffers, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + for (i = 0; i < swapchain->buffer_count; ++i) + { + semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphore_info.pNext = NULL; + semaphore_info.flags = 0; + + assert(swapchain->vk_semaphores[i] == VK_NULL_HANDLE); + if ((vr = vk_funcs->p_vkCreateSemaphore(vk_device, &semaphore_info, + NULL, &swapchain->vk_semaphores[i])) < 0) + { + WARN("Failed to create semaphore, vr %d.\n", vr); + swapchain->vk_semaphores[i] = VK_NULL_HANDLE; + return hresult_from_vk_result(vr); + } + } + + return S_OK; +} + +static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, + VkFormat vk_swapchain_format, VkFormat vk_format) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + struct vkd3d_image_resource_create_info resource_info; + VkSwapchainKHR vk_swapchain = swapchain->vk_swapchain; + ID3D12CommandQueue *queue = swapchain->command_queue; + VkDevice vk_device = swapchain->vk_device; + ID3D12Device *device = swapchain->device; + uint32_t image_count, queue_family_index; + D3D12_COMMAND_QUEUE_DESC queue_desc; + unsigned int i; + VkResult vr; + HRESULT hr; + + if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL)) < 0) + { + WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + if (image_count > ARRAY_SIZE(swapchain->vk_swapchain_images)) + { + FIXME("Unsupported Vulkan swapchain image count %u.\n", image_count); + return E_FAIL; + } + swapchain->buffer_count = image_count; + if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, + &image_count, swapchain->vk_swapchain_images)) < 0) + { + WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + resource_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO; + resource_info.next = NULL; + resource_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_info.desc.Alignment = 0; + resource_info.desc.Width = swapchain->desc.Width; + resource_info.desc.Height = swapchain->desc.Height; + resource_info.desc.DepthOrArraySize = 1; + resource_info.desc.MipLevels = 1; + resource_info.desc.Format = dxgi_format_from_vk_format(vk_format); + resource_info.desc.SampleDesc.Count = 1; + resource_info.desc.SampleDesc.Quality = 0; + resource_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resource_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION; + + queue_desc = ID3D12CommandQueue_GetDesc(queue); + if (queue_desc.Type != D3D12_COMMAND_LIST_TYPE_DIRECT) + { + /* vkCmdBlitImage() is only supported for graphics queues. */ + FIXME("Swapchain blit not implemented for command queue type %#x.\n", queue_desc.Type); + if (vk_swapchain_format != vk_format) + return E_NOTIMPL; + if (image_count != swapchain->desc.BufferCount) + { + FIXME("Got %u swapchain images, expected %u.\n", image_count, swapchain->desc.BufferCount); + return E_NOTIMPL; + } + } + queue_family_index = vkd3d_get_vk_queue_family_index(queue); + + if (queue_desc.Type == D3D12_COMMAND_LIST_TYPE_DIRECT) + { + TRACE("Creating user swapchain buffers.\n"); + + if (FAILED(hr = d3d12_swapchain_create_user_buffers(swapchain, vk_format))) + return hr; + + if (FAILED(hr = d3d12_swapchain_prepare_command_buffers(swapchain, queue_family_index))) + return hr; + } + + if (swapchain->buffers[0]) + return S_OK; + + for (i = 0; i < swapchain->desc.BufferCount; ++i) + { + if (swapchain->vk_images[i]) + { + resource_info.vk_image = swapchain->vk_images[i]; + resource_info.present_state = D3D12_RESOURCE_STATE_COPY_SOURCE; + } + else + { + resource_info.vk_image = swapchain->vk_swapchain_images[i]; + resource_info.present_state = D3D12_RESOURCE_STATE_PRESENT; + } + + if (FAILED(hr = vkd3d_create_image_resource(device, &resource_info, &swapchain->buffers[i]))) + { + WARN("Failed to create vkd3d resource for Vulkan image %u, hr %#x.\n", i, hr); + return hr; + } + + vkd3d_resource_incref(swapchain->buffers[i]); + ID3D12Resource_Release(swapchain->buffers[i]); + } + + return S_OK; +} + +static VkResult d3d12_swapchain_acquire_next_vulkan_image(struct d3d12_swapchain *swapchain) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkDevice vk_device = swapchain->vk_device; + VkFence vk_fence = swapchain->vk_fence; + VkResult vr; + + swapchain->vk_image_index = INVALID_VK_IMAGE_INDEX; + + if ((vr = vk_funcs->p_vkAcquireNextImageKHR(vk_device, swapchain->vk_swapchain, UINT64_MAX, + VK_NULL_HANDLE, vk_fence, &swapchain->vk_image_index)) < 0) + { + WARN("Failed to acquire next Vulkan image, vr %d.\n", vr); + return vr; + } + + if ((vr = vk_funcs->p_vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX)) != VK_SUCCESS) + { + ERR("Failed to wait for fence, vr %d.\n", vr); + return vr; + } + if ((vr = vk_funcs->p_vkResetFences(vk_device, 1, &vk_fence)) < 0) + ERR("Failed to reset fence, vr %d.\n", vr); + + return vr; +} + +static VkResult d3d12_swapchain_acquire_next_back_buffer(struct d3d12_swapchain *swapchain) +{ + VkResult vr; + + /* If we don't have user images, we need to acquire a Vulkan image in order + * to get the correct value for the current back buffer index. */ + if (d3d12_swapchain_has_user_images(swapchain)) + return VK_SUCCESS; + + if ((vr = d3d12_swapchain_acquire_next_vulkan_image(swapchain)) >= 0) + swapchain->current_buffer_index = swapchain->vk_image_index; + else + ERR("Failed to acquire Vulkan image, vr %d.\n", vr); + + return vr; +} + +static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain, BOOL destroy_user_buffers) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkQueue vk_queue; + unsigned int i; + + if (swapchain->command_queue) + { + if ((vk_queue = vkd3d_acquire_vk_queue(swapchain->command_queue))) + { + vk_funcs->p_vkQueueWaitIdle(vk_queue); + + vkd3d_release_vk_queue(swapchain->command_queue); + } + else + { + WARN("Failed to acquire Vulkan queue.\n"); + } + } + + for (i = 0; i < swapchain->desc.BufferCount; ++i) + { + if (swapchain->buffers[i] && (destroy_user_buffers || !d3d12_swapchain_has_user_images(swapchain))) + { + vkd3d_resource_decref(swapchain->buffers[i]); + swapchain->buffers[i] = NULL; + } + if (swapchain->vk_device && destroy_user_buffers) + { + vk_funcs->p_vkDestroyImage(swapchain->vk_device, swapchain->vk_images[i], NULL); + swapchain->vk_images[i] = VK_NULL_HANDLE; + } + } + + if (swapchain->vk_device) + { + for (i = 0; i < swapchain->buffer_count; ++i) + { + vk_funcs->p_vkDestroySemaphore(swapchain->vk_device, swapchain->vk_semaphores[i], NULL); + swapchain->vk_semaphores[i] = VK_NULL_HANDLE; + } + if (destroy_user_buffers) + { + vk_funcs->p_vkFreeMemory(swapchain->vk_device, swapchain->vk_memory, NULL); + swapchain->vk_memory = VK_NULL_HANDLE; + } + vk_funcs->p_vkDestroyCommandPool(swapchain->vk_device, swapchain->vk_cmd_pool, NULL); + swapchain->vk_cmd_pool = VK_NULL_HANDLE; + } +} + +static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *swapchain) +{ + VkPhysicalDevice vk_physical_device = swapchain->vk_physical_device; + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkSwapchainCreateInfoKHR vk_swapchain_desc; + VkDevice vk_device = swapchain->vk_device; + VkFormat vk_format, vk_swapchain_format; + unsigned int width, height, image_count; + VkSurfaceCapabilitiesKHR surface_caps; + VkSwapchainKHR vk_swapchain; + VkImageUsageFlags usage; + VkResult vr; + HRESULT hr; + + if (!(vk_format = vkd3d_get_vk_format(swapchain->desc.Format))) + { + WARN("Invalid format %#x.\n", swapchain->desc.Format); + return DXGI_ERROR_INVALID_CALL; + } + + if (FAILED(hr = select_vk_format(vk_funcs, vk_physical_device, + swapchain->vk_surface, &swapchain->desc, &vk_swapchain_format))) + return hr; + + if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device, + swapchain->vk_surface, &surface_caps)) < 0) + { + WARN("Failed to get surface capabilities, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + image_count = swapchain->desc.BufferCount; + image_count = max(image_count, surface_caps.minImageCount); + if (surface_caps.maxImageCount) + image_count = min(image_count, surface_caps.maxImageCount); + + if (image_count != swapchain->desc.BufferCount) + { + WARN("Buffer count %u is not supported (%u-%u).\n", swapchain->desc.BufferCount, + surface_caps.minImageCount, surface_caps.maxImageCount); + } + + width = swapchain->desc.Width; + height = swapchain->desc.Height; + width = max(width, surface_caps.minImageExtent.width); + width = min(width, surface_caps.maxImageExtent.width); + height = max(height, surface_caps.minImageExtent.height); + height = min(height, surface_caps.maxImageExtent.height); + + if (width != swapchain->desc.Width || height != swapchain->desc.Height) + { + WARN("Swapchain dimensions %ux%u are not supported (%u-%u x %u-%u).\n", + swapchain->desc.Width, swapchain->desc.Height, + surface_caps.minImageExtent.width, surface_caps.maxImageExtent.width, + surface_caps.minImageExtent.height, surface_caps.maxImageExtent.height); + } + + TRACE("Vulkan swapchain extent %ux%u.\n", width, height); + + if (!(surface_caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)) + { + FIXME("Unsupported alpha mode.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + + usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + usage |= surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + usage |= surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT; + if (!(usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) || !(usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) + WARN("Transfer not supported for swapchain images.\n"); + + vk_swapchain_desc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + vk_swapchain_desc.pNext = NULL; + vk_swapchain_desc.flags = 0; + vk_swapchain_desc.surface = swapchain->vk_surface; + vk_swapchain_desc.minImageCount = image_count; + vk_swapchain_desc.imageFormat = vk_swapchain_format; + vk_swapchain_desc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + vk_swapchain_desc.imageExtent.width = width; + vk_swapchain_desc.imageExtent.height = height; + vk_swapchain_desc.imageArrayLayers = 1; + vk_swapchain_desc.imageUsage = usage; + vk_swapchain_desc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + vk_swapchain_desc.queueFamilyIndexCount = 0; + vk_swapchain_desc.pQueueFamilyIndices = NULL; + vk_swapchain_desc.preTransform = surface_caps.currentTransform; + vk_swapchain_desc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + vk_swapchain_desc.presentMode = swapchain->present_mode; + vk_swapchain_desc.clipped = VK_TRUE; + vk_swapchain_desc.oldSwapchain = swapchain->vk_swapchain; + if ((vr = vk_funcs->p_vkCreateSwapchainKHR(vk_device, &vk_swapchain_desc, NULL, &vk_swapchain)) < 0) + { + WARN("Failed to create Vulkan swapchain, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + if (swapchain->vk_swapchain) + vk_funcs->p_vkDestroySwapchainKHR(swapchain->vk_device, swapchain->vk_swapchain, NULL); + + swapchain->vk_swapchain = vk_swapchain; + swapchain->vk_swapchain_width = width; + swapchain->vk_swapchain_height = height; + + swapchain->vk_image_index = INVALID_VK_IMAGE_INDEX; + + return d3d12_swapchain_create_buffers(swapchain, vk_swapchain_format, vk_format); +} + +static HRESULT d3d12_swapchain_recreate_vulkan_swapchain(struct d3d12_swapchain *swapchain) +{ + VkResult vr; + HRESULT hr; + + if (SUCCEEDED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain))) + { + vr = d3d12_swapchain_acquire_next_back_buffer(swapchain); + hr = hresult_from_vk_result(vr); + } + else + { + ERR("Failed to recreate Vulkan swapchain, hr %#x.\n", hr); + } + + return hr; +} + +static inline struct d3d12_swapchain *d3d12_swapchain_from_IDXGISwapChain3(IDXGISwapChain3 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d12_swapchain, IDXGISwapChain3_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_QueryInterface(IDXGISwapChain3 *iface, REFIID iid, void **object) +{ + TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IDXGIObject) + || IsEqualGUID(iid, &IID_IDXGIDeviceSubObject) + || IsEqualGUID(iid, &IID_IDXGISwapChain) + || IsEqualGUID(iid, &IID_IDXGISwapChain1) + || IsEqualGUID(iid, &IID_IDXGISwapChain2) + || IsEqualGUID(iid, &IID_IDXGISwapChain3)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d12_swapchain_AddRef(IDXGISwapChain3 *iface) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + ULONG refcount = InterlockedIncrement(&swapchain->refcount); + + TRACE("%p increasing refcount to %u.\n", swapchain, refcount); + + return refcount; +} + +static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + void *vulkan_module = vk_funcs->vulkan_module; + + d3d12_swapchain_destroy_buffers(swapchain, TRUE); + + if (swapchain->command_queue) + ID3D12CommandQueue_Release(swapchain->command_queue); + + wined3d_private_store_cleanup(&swapchain->private_store); + + if (swapchain->vk_device) + { + vk_funcs->p_vkDestroyFence(swapchain->vk_device, swapchain->vk_fence, NULL); + vk_funcs->p_vkDestroySwapchainKHR(swapchain->vk_device, swapchain->vk_swapchain, NULL); + } + + if (swapchain->vk_instance) + vk_funcs->p_vkDestroySurfaceKHR(swapchain->vk_instance, swapchain->vk_surface, NULL); + + if (swapchain->target) + { + WARN("Destroying fullscreen swapchain.\n"); + IDXGIOutput_Release(swapchain->target); + } + + if (swapchain->device) + ID3D12Device_Release(swapchain->device); + + if (swapchain->factory) + IWineDXGIFactory_Release(swapchain->factory); + + close_library(vulkan_module); + + wined3d_swapchain_state_destroy(swapchain->state); +} + +static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + ULONG refcount = InterlockedDecrement(&swapchain->refcount); + + TRACE("%p decreasing refcount to %u.\n", swapchain, refcount); + + if (!refcount) + { + d3d12_swapchain_destroy(swapchain); + heap_free(swapchain); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetPrivateData(IDXGISwapChain3 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&swapchain->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetPrivateDataInterface(IDXGISwapChain3 *iface, + REFGUID guid, const IUnknown *object) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&swapchain->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetPrivateData(IDXGISwapChain3 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&swapchain->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetParent(IDXGISwapChain3 *iface, REFIID iid, void **parent) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, iid %s, parent %p.\n", iface, debugstr_guid(iid), parent); + + return IWineDXGIFactory_QueryInterface(swapchain->factory, iid, parent); +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDevice(IDXGISwapChain3 *iface, REFIID iid, void **device) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device); + + return ID3D12Device_QueryInterface(swapchain->device, iid, device); +} + +/* IDXGISwapChain methods */ + +static HRESULT d3d12_swapchain_set_sync_interval(struct d3d12_swapchain *swapchain, + unsigned int sync_interval) +{ + VkPresentModeKHR present_mode; + + switch (sync_interval) + { + case 0: + present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; + break; + default: + FIXME("Unsupported sync interval %u.\n", sync_interval); + case 1: + present_mode = VK_PRESENT_MODE_FIFO_KHR; + break; + } + + if (swapchain->present_mode == present_mode) + return S_OK; + + if (!d3d12_swapchain_has_user_images(swapchain)) + { + FIXME("Cannot recreate swapchain without user images.\n"); + return S_OK; + } + + if (!d3d12_swapchain_is_present_mode_supported(swapchain, present_mode)) + { + FIXME("Vulkan present mode %#x is not supported.\n", present_mode); + return S_OK; + } + + d3d12_swapchain_destroy_buffers(swapchain, FALSE); + swapchain->present_mode = present_mode; + return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); +} + +static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain, VkQueue vk_queue) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + VkPresentInfoKHR present_info; + VkSubmitInfo submit_info; + VkResult vr; + + if (swapchain->vk_image_index == INVALID_VK_IMAGE_INDEX) + { + if ((vr = d3d12_swapchain_acquire_next_vulkan_image(swapchain)) < 0) + return vr; + } + + assert(swapchain->vk_image_index < swapchain->buffer_count); + + present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + present_info.pNext = NULL; + present_info.waitSemaphoreCount = 0; + present_info.pWaitSemaphores = NULL; + present_info.swapchainCount = 1; + present_info.pSwapchains = &swapchain->vk_swapchain; + present_info.pImageIndices = &swapchain->vk_image_index; + present_info.pResults = NULL; + + if (d3d12_swapchain_has_user_images(swapchain)) + { + /* blit */ + VkCommandBuffer vk_cmd_buffer = swapchain->vk_cmd_buffers[swapchain->vk_image_index]; + VkImage vk_dst_image = swapchain->vk_swapchain_images[swapchain->vk_image_index]; + VkImage vk_src_image = swapchain->vk_images[swapchain->current_buffer_index]; + + if ((vr = vk_funcs->p_vkResetCommandBuffer(vk_cmd_buffer, 0)) < 0) + { + ERR("Failed to reset command buffer, vr %d.\n", vr); + return vr; + } + + if ((vr = d3d12_swapchain_record_swapchain_blit(swapchain, + vk_cmd_buffer, vk_dst_image, vk_src_image)) < 0 ) + return vr; + + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = NULL; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = NULL; + submit_info.pWaitDstStageMask = NULL; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &vk_cmd_buffer; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &swapchain->vk_semaphores[swapchain->vk_image_index]; + + if ((vr = vk_funcs->p_vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE)) < 0) + { + ERR("Failed to blit swapchain buffer, vr %d.\n", vr); + return vr; + } + + present_info.waitSemaphoreCount = 1; + present_info.pWaitSemaphores = &swapchain->vk_semaphores[swapchain->vk_image_index]; + } + + if ((vr = vk_funcs->p_vkQueuePresentKHR(vk_queue, &present_info)) >= 0) + swapchain->vk_image_index = INVALID_VK_IMAGE_INDEX; + + return vr; +} + +static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, + unsigned int sync_interval, unsigned int flags) +{ + VkQueue vk_queue; + VkResult vr; + HRESULT hr; + + if (sync_interval > 4) + { + WARN("Invalid sync interval %u.\n", sync_interval); + return DXGI_ERROR_INVALID_CALL; + } + + if (flags & ~DXGI_PRESENT_TEST) + FIXME("Unimplemented flags %#x.\n", flags); + if (flags & DXGI_PRESENT_TEST) + { + WARN("Returning S_OK for DXGI_PRESENT_TEST.\n"); + return S_OK; + } + + if (FAILED(hr = d3d12_swapchain_set_sync_interval(swapchain, sync_interval))) + return hr; + + if (!(vk_queue = vkd3d_acquire_vk_queue(swapchain->command_queue))) + { + ERR("Failed to acquire Vulkan queue.\n"); + return E_FAIL; + } + + vr = d3d12_swapchain_queue_present(swapchain, vk_queue); + if (vr == VK_ERROR_OUT_OF_DATE_KHR) + { + vkd3d_release_vk_queue(swapchain->command_queue); + + if (!d3d12_swapchain_has_user_images(swapchain)) + { + FIXME("Cannot recreate swapchain without user images.\n"); + return DXGI_STATUS_MODE_CHANGED; + } + + TRACE("Recreating Vulkan swapchain.\n"); + + d3d12_swapchain_destroy_buffers(swapchain, FALSE); + if (FAILED(hr = d3d12_swapchain_recreate_vulkan_swapchain(swapchain))) + return hr; + + if (!(vk_queue = vkd3d_acquire_vk_queue(swapchain->command_queue))) + { + ERR("Failed to acquire Vulkan queue.\n"); + return E_FAIL; + } + + if ((vr = d3d12_swapchain_queue_present(swapchain, vk_queue)) < 0) + ERR("Failed to present after recreating swapchain, vr %d.\n", vr); + } + + vkd3d_release_vk_queue(swapchain->command_queue); + + if (vr < 0) + { + ERR("Failed to queue present, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount; + vr = d3d12_swapchain_acquire_next_back_buffer(swapchain); + if (vr == VK_ERROR_OUT_OF_DATE_KHR) + { + if (!d3d12_swapchain_has_user_images(swapchain)) + { + FIXME("Cannot recreate swapchain without user images.\n"); + return DXGI_STATUS_MODE_CHANGED; + } + + TRACE("Recreating Vulkan swapchain.\n"); + + d3d12_swapchain_destroy_buffers(swapchain, FALSE); + return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); + } + if (vr < 0) + ERR("Failed to acquire next Vulkan image, vr %d.\n", vr); + return hresult_from_vk_result(vr); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_Present(IDXGISwapChain3 *iface, UINT sync_interval, UINT flags) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, sync_interval %u, flags %#x.\n", iface, sync_interval, flags); + + return d3d12_swapchain_present(swapchain, sync_interval, flags); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetBuffer(IDXGISwapChain3 *iface, + UINT buffer_idx, REFIID iid, void **surface) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, buffer_idx %u, iid %s, surface %p.\n", + iface, buffer_idx, debugstr_guid(iid), surface); + + if (buffer_idx >= swapchain->desc.BufferCount) + { + WARN("Invalid buffer index %u.\n", buffer_idx); + return DXGI_ERROR_INVALID_CALL; + } + + assert(swapchain->buffers[buffer_idx]); + return ID3D12Resource_QueryInterface(swapchain->buffers[buffer_idx], iid, surface); +} + +static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreenState(IDXGISwapChain3 *iface, + BOOL fullscreen, IDXGIOutput *target) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc = &swapchain->fullscreen_desc; + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc; + struct wined3d_swapchain_desc wined3d_desc; + HWND window = swapchain->window; + HRESULT hr; + + TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); + + if (!fullscreen && target) + { + WARN("Invalid call.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (target) + { + IDXGIOutput_AddRef(target); + } + else if (FAILED(hr = IDXGISwapChain3_GetContainingOutput(iface, &target))) + { + WARN("Failed to get target output for swapchain, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, swapchain_desc, fullscreen_desc))) + goto fail; + wined3d_mutex_lock(); + wined3d_desc.windowed = !fullscreen; + hr = dxgi_swapchain_set_fullscreen_state(swapchain->state, &wined3d_desc, target); + wined3d_mutex_unlock(); + if (FAILED(hr)) + goto fail; + + fullscreen_desc->Windowed = wined3d_desc.windowed; + if (!fullscreen) + { + IDXGIOutput_Release(target); + target = NULL; + } + + if (swapchain->target) + IDXGIOutput_Release(swapchain->target); + swapchain->target = target; + + return S_OK; + +fail: + IDXGIOutput_Release(target); + + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFullscreenState(IDXGISwapChain3 *iface, + BOOL *fullscreen, IDXGIOutput **target) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, fullscreen %p, target %p.\n", iface, fullscreen, target); + + if (fullscreen) + *fullscreen = !swapchain->fullscreen_desc.Windowed; + + if (target && (*target = swapchain->target)) + IDXGIOutput_AddRef(*target); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDesc(IDXGISwapChain3 *iface, DXGI_SWAP_CHAIN_DESC *desc) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc = &swapchain->fullscreen_desc; + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + desc->BufferDesc.Width = swapchain_desc->Width; + desc->BufferDesc.Height = swapchain_desc->Height; + desc->BufferDesc.RefreshRate = fullscreen_desc->RefreshRate; + desc->BufferDesc.Format = swapchain_desc->Format; + desc->BufferDesc.ScanlineOrdering = fullscreen_desc->ScanlineOrdering; + desc->BufferDesc.Scaling = fullscreen_desc->Scaling; + desc->SampleDesc = swapchain_desc->SampleDesc; + desc->BufferUsage = swapchain_desc->BufferUsage; + desc->BufferCount = swapchain_desc->BufferCount; + desc->OutputWindow = swapchain->window; + desc->Windowed = fullscreen_desc->Windowed; + desc->SwapEffect = swapchain_desc->SwapEffect; + desc->Flags = swapchain_desc->Flags; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 *iface, + UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + DXGI_SWAP_CHAIN_DESC1 *desc, new_desc; + unsigned int i; + ULONG refcount; + + TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x.\n", + iface, buffer_count, width, height, debug_dxgi_format(format), flags); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + for (i = 0; i < swapchain->desc.BufferCount; ++i) + { + ID3D12Resource_AddRef(swapchain->buffers[i]); + if ((refcount = ID3D12Resource_Release(swapchain->buffers[i]))) + { + WARN("Buffer %p has %u references left.\n", swapchain->buffers[i], refcount); + return DXGI_ERROR_INVALID_CALL; + } + } + + desc = &swapchain->desc; + new_desc = swapchain->desc; + + if (buffer_count) + new_desc.BufferCount = buffer_count; + if (!width || !height) + { + RECT client_rect; + + if (!GetClientRect(swapchain->window, &client_rect)) + { + WARN("Failed to get client rect, last error %#x.\n", GetLastError()); + return DXGI_ERROR_INVALID_CALL; + } + + if (!width) + width = client_rect.right; + if (!height) + height = client_rect.bottom; + } + new_desc.Width = width; + new_desc.Height = height; + + if (format) + new_desc.Format = format; + + if (!dxgi_validate_swapchain_desc(&new_desc)) + return DXGI_ERROR_INVALID_CALL; + + if (desc->Width == new_desc.Width && desc->Height == new_desc.Height + && desc->Format == new_desc.Format && desc->BufferCount == new_desc.BufferCount) + return S_OK; + + d3d12_swapchain_destroy_buffers(swapchain, TRUE); + swapchain->desc = new_desc; + return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain3 *iface, + const DXGI_MODE_DESC *target_mode_desc) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc); + + return dxgi_swapchain_resize_target((IDXGISwapChain1 *)iface, swapchain->state, target_mode_desc); +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapChain3 *iface, + IDXGIOutput **output) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + IUnknown *device_parent; + IDXGIAdapter *adapter; + HRESULT hr; + + TRACE("iface %p, output %p.\n", iface, output); + + if (swapchain->target) + { + IDXGIOutput_AddRef(*output = swapchain->target); + return S_OK; + } + + device_parent = vkd3d_get_device_parent(swapchain->device); + + if (SUCCEEDED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter))) + { + hr = dxgi_get_output_from_window(adapter, swapchain->window, output); + IDXGIAdapter_Release(adapter); + } + else + { + WARN("Failed to get adapter, hr %#x.\n", hr); + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFrameStatistics(IDXGISwapChain3 *iface, + DXGI_FRAME_STATISTICS *stats) +{ + FIXME("iface %p, stats %p stub!\n", iface, stats); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetLastPresentCount(IDXGISwapChain3 *iface, + UINT *last_present_count) +{ + FIXME("iface %p, last_present_count %p stub!\n", iface, last_present_count); + + return E_NOTIMPL; +} + +/* IDXGISwapChain1 methods */ + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDesc1(IDXGISwapChain3 *iface, DXGI_SWAP_CHAIN_DESC1 *desc) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + *desc = swapchain->desc; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFullscreenDesc(IDXGISwapChain3 *iface, + DXGI_SWAP_CHAIN_FULLSCREEN_DESC *desc) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + *desc = swapchain->fullscreen_desc; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetHwnd(IDXGISwapChain3 *iface, HWND *hwnd) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, hwnd %p.\n", iface, hwnd); + + if (!hwnd) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + *hwnd = swapchain->window; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetCoreWindow(IDXGISwapChain3 *iface, + REFIID iid, void **core_window) +{ + FIXME("iface %p, iid %s, core_window %p stub!\n", iface, debugstr_guid(iid), core_window); + + if (core_window) + *core_window = NULL; + + return DXGI_ERROR_INVALID_CALL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_Present1(IDXGISwapChain3 *iface, + UINT sync_interval, UINT flags, const DXGI_PRESENT_PARAMETERS *present_parameters) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, sync_interval %u, flags %#x, present_parameters %p.\n", + iface, sync_interval, flags, present_parameters); + + if (present_parameters) + FIXME("Ignored present parameters %p.\n", present_parameters); + + return d3d12_swapchain_present(swapchain, sync_interval, flags); +} + +static BOOL STDMETHODCALLTYPE d3d12_swapchain_IsTemporaryMonoSupported(IDXGISwapChain3 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetRestrictToOutput(IDXGISwapChain3 *iface, IDXGIOutput **output) +{ + FIXME("iface %p, output %p stub!\n", iface, output); + + if (!output) + { + WARN("Invalid pointer.\n"); + return E_INVALIDARG; + } + + *output = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetBackgroundColor(IDXGISwapChain3 *iface, const DXGI_RGBA *color) +{ + FIXME("iface %p, color %p stub!\n", iface, color); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetBackgroundColor(IDXGISwapChain3 *iface, DXGI_RGBA *color) +{ + FIXME("iface %p, color %p stub!\n", iface, color); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetRotation(IDXGISwapChain3 *iface, DXGI_MODE_ROTATION rotation) +{ + FIXME("iface %p, rotation %#x stub!\n", iface, rotation); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetRotation(IDXGISwapChain3 *iface, DXGI_MODE_ROTATION *rotation) +{ + FIXME("iface %p, rotation %p stub!\n", iface, rotation); + + return E_NOTIMPL; +} + +/* IDXGISwapChain2 methods */ + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetSourceSize(IDXGISwapChain3 *iface, UINT width, UINT height) +{ + FIXME("iface %p, width %u, height %u stub!\n", iface, width, height); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetSourceSize(IDXGISwapChain3 *iface, UINT *width, UINT *height) +{ + FIXME("iface %p, width %p, height %p stub!\n", iface, width, height); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT max_latency) +{ + FIXME("iface %p, max_latency %u stub!\n", iface, max_latency); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT *max_latency) +{ + FIXME("iface %p, max_latency %p stub!\n", iface, max_latency); + + return E_NOTIMPL; +} + +static HANDLE STDMETHODCALLTYPE d3d12_swapchain_GetFrameLatencyWaitableObject(IDXGISwapChain3 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMatrixTransform(IDXGISwapChain3 *iface, + const DXGI_MATRIX_3X2_F *matrix) +{ + FIXME("iface %p, matrix %p stub!\n", iface, matrix); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMatrixTransform(IDXGISwapChain3 *iface, + DXGI_MATRIX_3X2_F *matrix) +{ + FIXME("iface %p, matrix %p stub!\n", iface, matrix); + + return E_NOTIMPL; +} + +/* IDXGISwapChain3 methods */ + +static UINT STDMETHODCALLTYPE d3d12_swapchain_GetCurrentBackBufferIndex(IDXGISwapChain3 *iface) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p.\n", iface); + + TRACE("Current back buffer index %u.\n", swapchain->current_buffer_index); + assert(swapchain->current_buffer_index < swapchain->desc.BufferCount); + return swapchain->current_buffer_index; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_CheckColorSpaceSupport(IDXGISwapChain3 *iface, + DXGI_COLOR_SPACE_TYPE colour_space, UINT *colour_space_support) +{ + FIXME("iface %p, colour_space %#x, colour_space_support %p stub!\n", + iface, colour_space, colour_space_support); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetColorSpace1(IDXGISwapChain3 *iface, + DXGI_COLOR_SPACE_TYPE colour_space) +{ + FIXME("iface %p, colour_space %#x stub!\n", iface, colour_space); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers1(IDXGISwapChain3 *iface, + UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags, + const UINT *node_mask, IUnknown * const *present_queue) +{ + FIXME("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x, " + "node_mask %p, present_queue %p stub!\n", + iface, buffer_count, width, height, debug_dxgi_format(format), flags, node_mask, present_queue); + + return E_NOTIMPL; +} + +static const struct IDXGISwapChain3Vtbl d3d12_swapchain_vtbl = +{ + /* IUnknown methods */ + d3d12_swapchain_QueryInterface, + d3d12_swapchain_AddRef, + d3d12_swapchain_Release, + /* IDXGIObject methods */ + d3d12_swapchain_SetPrivateData, + d3d12_swapchain_SetPrivateDataInterface, + d3d12_swapchain_GetPrivateData, + d3d12_swapchain_GetParent, + /* IDXGIDeviceSubObject methods */ + d3d12_swapchain_GetDevice, + /* IDXGISwapChain methods */ + d3d12_swapchain_Present, + d3d12_swapchain_GetBuffer, + d3d12_swapchain_SetFullscreenState, + d3d12_swapchain_GetFullscreenState, + d3d12_swapchain_GetDesc, + d3d12_swapchain_ResizeBuffers, + d3d12_swapchain_ResizeTarget, + d3d12_swapchain_GetContainingOutput, + d3d12_swapchain_GetFrameStatistics, + d3d12_swapchain_GetLastPresentCount, + /* IDXGISwapChain1 methods */ + d3d12_swapchain_GetDesc1, + d3d12_swapchain_GetFullscreenDesc, + d3d12_swapchain_GetHwnd, + d3d12_swapchain_GetCoreWindow, + d3d12_swapchain_Present1, + d3d12_swapchain_IsTemporaryMonoSupported, + d3d12_swapchain_GetRestrictToOutput, + d3d12_swapchain_SetBackgroundColor, + d3d12_swapchain_GetBackgroundColor, + d3d12_swapchain_SetRotation, + d3d12_swapchain_GetRotation, + /* IDXGISwapChain2 methods */ + d3d12_swapchain_SetSourceSize, + d3d12_swapchain_GetSourceSize, + d3d12_swapchain_SetMaximumFrameLatency, + d3d12_swapchain_GetMaximumFrameLatency, + d3d12_swapchain_GetFrameLatencyWaitableObject, + d3d12_swapchain_SetMatrixTransform, + d3d12_swapchain_GetMatrixTransform, + /* IDXGISwapChain3 methods */ + d3d12_swapchain_GetCurrentBackBufferIndex, + d3d12_swapchain_CheckColorSpaceSupport, + d3d12_swapchain_SetColorSpace1, + d3d12_swapchain_ResizeBuffers1, +}; + +static BOOL load_vkd3d_functions(void *vkd3d_handle) +{ +#define LOAD_FUNCPTR(f) if (!(f = get_library_proc(vkd3d_handle, #f))) return FALSE; + LOAD_FUNCPTR(vkd3d_acquire_vk_queue) + LOAD_FUNCPTR(vkd3d_create_image_resource) + LOAD_FUNCPTR(vkd3d_get_device_parent) + LOAD_FUNCPTR(vkd3d_get_vk_device) + LOAD_FUNCPTR(vkd3d_get_vk_format) + LOAD_FUNCPTR(vkd3d_get_vk_physical_device) + LOAD_FUNCPTR(vkd3d_get_vk_queue_family_index) + LOAD_FUNCPTR(vkd3d_instance_from_device) + LOAD_FUNCPTR(vkd3d_instance_get_vk_instance) + LOAD_FUNCPTR(vkd3d_release_vk_queue) + LOAD_FUNCPTR(vkd3d_resource_decref) + LOAD_FUNCPTR(vkd3d_resource_incref) +#undef LOAD_FUNCPTR + + return TRUE; +} + +static void *vkd3d_handle; + +static BOOL WINAPI init_vkd3d_once(INIT_ONCE *once, void *param, void **context) +{ + TRACE("Loading vkd3d %s.\n", SONAME_LIBVKD3D); + + if (!(vkd3d_handle = load_library(SONAME_LIBVKD3D))) + return FALSE; + + if (!load_vkd3d_functions(vkd3d_handle)) + { + ERR("Failed to load vkd3d functions.\n"); + close_library(vkd3d_handle); + vkd3d_handle = NULL; + return FALSE; + } + + return TRUE; +} + +static BOOL init_vkd3d(void) +{ + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + InitOnceExecuteOnce(&init_once, init_vkd3d_once, NULL, NULL); + return !!vkd3d_handle; +} + +static BOOL init_vk_funcs(struct dxgi_vk_funcs *dxgi, VkInstance vk_instance, VkDevice vk_device) +{ + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; + + dxgi->vulkan_module = NULL; + + if (!(vkGetInstanceProcAddr = load_vulkan(&dxgi->vulkan_module))) + { + ERR_(winediag)("Failed to load Vulkan.\n"); + return FALSE; + } + + vkGetDeviceProcAddr = (void *)vkGetInstanceProcAddr(vk_instance, "vkGetDeviceProcAddr"); + +#define LOAD_INSTANCE_PFN(name) \ + if (!(dxgi->p_##name = (void *)vkGetInstanceProcAddr(vk_instance, #name))) \ + { \ + ERR("Failed to get instance proc "#name".\n"); \ + close_library(dxgi->vulkan_module); \ + return FALSE; \ + } + LOAD_INSTANCE_PFN(vkCreateWin32SurfaceKHR) + LOAD_INSTANCE_PFN(vkDestroySurfaceKHR) + LOAD_INSTANCE_PFN(vkGetPhysicalDeviceMemoryProperties) + LOAD_INSTANCE_PFN(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) + LOAD_INSTANCE_PFN(vkGetPhysicalDeviceSurfaceFormatsKHR) + LOAD_INSTANCE_PFN(vkGetPhysicalDeviceSurfacePresentModesKHR) + LOAD_INSTANCE_PFN(vkGetPhysicalDeviceSurfaceSupportKHR) + LOAD_INSTANCE_PFN(vkGetPhysicalDeviceWin32PresentationSupportKHR) +#undef LOAD_INSTANCE_PFN + +#define LOAD_DEVICE_PFN(name) \ + if (!(dxgi->p_##name = (void *)vkGetDeviceProcAddr(vk_device, #name))) \ + { \ + ERR("Failed to get device proc "#name".\n"); \ + close_library(dxgi->vulkan_module); \ + return FALSE; \ + } + LOAD_DEVICE_PFN(vkAcquireNextImageKHR) + LOAD_DEVICE_PFN(vkAllocateCommandBuffers) + LOAD_DEVICE_PFN(vkAllocateMemory) + LOAD_DEVICE_PFN(vkBeginCommandBuffer) + LOAD_DEVICE_PFN(vkBindImageMemory) + LOAD_DEVICE_PFN(vkCmdBlitImage) + LOAD_DEVICE_PFN(vkCmdPipelineBarrier) + LOAD_DEVICE_PFN(vkCreateCommandPool) + LOAD_DEVICE_PFN(vkCreateFence) + LOAD_DEVICE_PFN(vkCreateImage) + LOAD_DEVICE_PFN(vkCreateSemaphore) + LOAD_DEVICE_PFN(vkCreateSwapchainKHR) + LOAD_DEVICE_PFN(vkDestroyCommandPool) + LOAD_DEVICE_PFN(vkDestroyFence) + LOAD_DEVICE_PFN(vkDestroyImage) + LOAD_DEVICE_PFN(vkDestroySemaphore) + LOAD_DEVICE_PFN(vkDestroySwapchainKHR) + LOAD_DEVICE_PFN(vkEndCommandBuffer) + LOAD_DEVICE_PFN(vkFreeMemory) + LOAD_DEVICE_PFN(vkResetCommandBuffer) + LOAD_DEVICE_PFN(vkGetImageMemoryRequirements) + LOAD_DEVICE_PFN(vkGetSwapchainImagesKHR) + LOAD_DEVICE_PFN(vkQueuePresentKHR) + LOAD_DEVICE_PFN(vkQueueSubmit) + LOAD_DEVICE_PFN(vkQueueWaitIdle) + LOAD_DEVICE_PFN(vkResetFences) + LOAD_DEVICE_PFN(vkWaitForFences) +#undef LOAD_DEVICE_PFN + + return TRUE; +} + +static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGIFactory *factory, + ID3D12Device *device, ID3D12CommandQueue *queue, HWND window, + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc) +{ + const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + struct wined3d_swapchain_desc wined3d_desc; + VkWin32SurfaceCreateInfoKHR surface_desc; + VkPhysicalDevice vk_physical_device; + struct dxgi_adapter *dxgi_adapter; + VkFenceCreateInfo fence_desc; + uint32_t queue_family_index; + VkSurfaceKHR vk_surface; + IUnknown *device_parent; + VkInstance vk_instance; + IDXGIAdapter *adapter; + VkBool32 supported; + VkDevice vk_device; + VkFence vk_fence; + VkResult vr; + HRESULT hr; + + if (window == GetDesktopWindow()) + { + WARN("D3D12 swapchain cannot be created on desktop window.\n"); + return E_ACCESSDENIED; + } + + swapchain->IDXGISwapChain3_iface.lpVtbl = &d3d12_swapchain_vtbl; + swapchain->refcount = 1; + + swapchain->window = window; + swapchain->desc = *swapchain_desc; + swapchain->fullscreen_desc = *fullscreen_desc; + + swapchain->present_mode = VK_PRESENT_MODE_FIFO_KHR; + + switch (swapchain_desc->SwapEffect) + { + case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: + case DXGI_SWAP_EFFECT_FLIP_DISCARD: + FIXME("Ignoring swap effect %#x.\n", swapchain_desc->SwapEffect); + break; + default: + WARN("Invalid swap effect %#x.\n", swapchain_desc->SwapEffect); + return DXGI_ERROR_INVALID_CALL; + } + + if (!init_vkd3d()) + { + ERR_(winediag)("libvkd3d could not be loaded.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + + device_parent = vkd3d_get_device_parent(device); + if (FAILED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter))) + return hr; + dxgi_adapter = unsafe_impl_from_IDXGIAdapter(adapter); + IDXGIAdapter_Release(adapter); + if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, swapchain_desc, fullscreen_desc))) + return hr; + if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, + dxgi_adapter->factory->wined3d, dxgi_adapter->ordinal, &swapchain->state))) + return hr; + + if (swapchain_desc->BufferUsage && swapchain_desc->BufferUsage != DXGI_USAGE_RENDER_TARGET_OUTPUT) + FIXME("Ignoring buffer usage %#x.\n", swapchain_desc->BufferUsage); + if (swapchain_desc->Scaling != DXGI_SCALING_STRETCH) + FIXME("Ignoring scaling %#x.\n", swapchain_desc->Scaling); + if (swapchain_desc->AlphaMode && swapchain_desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE) + FIXME("Ignoring alpha mode %#x.\n", swapchain_desc->AlphaMode); + if (swapchain_desc->Flags) + FIXME("Ignoring swapchain flags %#x.\n", swapchain_desc->Flags); + + FIXME("Ignoring refresh rate.\n"); + if (fullscreen_desc->ScanlineOrdering) + FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc->ScanlineOrdering); + if (fullscreen_desc->Scaling) + FIXME("Unhandled mode scaling %#x.\n", fullscreen_desc->Scaling); + if (!fullscreen_desc->Windowed) + FIXME("Fullscreen not supported yet.\n"); + + vk_instance = vkd3d_instance_get_vk_instance(vkd3d_instance_from_device(device)); + vk_physical_device = vkd3d_get_vk_physical_device(device); + vk_device = vkd3d_get_vk_device(device); + + swapchain->vk_instance = vk_instance; + swapchain->vk_device = vk_device; + swapchain->vk_physical_device = vk_physical_device; + + if (!init_vk_funcs(&swapchain->vk_funcs, vk_instance, vk_device)) + { + wined3d_swapchain_state_destroy(swapchain->state); + return E_FAIL; + } + + wined3d_private_store_init(&swapchain->private_store); + + surface_desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + surface_desc.pNext = NULL; + surface_desc.flags = 0; + surface_desc.hinstance = GetModuleHandleA("dxgi.dll"); + surface_desc.hwnd = window; + if ((vr = vk_funcs->p_vkCreateWin32SurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface)) < 0) + { + WARN("Failed to create Vulkan surface, vr %d.\n", vr); + d3d12_swapchain_destroy(swapchain); + return hresult_from_vk_result(vr); + } + swapchain->vk_surface = vk_surface; + + queue_family_index = vkd3d_get_vk_queue_family_index(queue); + if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceSupportKHR(vk_physical_device, + queue_family_index, vk_surface, &supported)) < 0 || !supported) + { + FIXME("Queue family does not support presentation, vr %d.\n", vr); + d3d12_swapchain_destroy(swapchain); + return DXGI_ERROR_UNSUPPORTED; + } + + ID3D12CommandQueue_AddRef(swapchain->command_queue = queue); + ID3D12Device_AddRef(swapchain->device = device); + + if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain))) + { + d3d12_swapchain_destroy(swapchain); + return hr; + } + + fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_desc.pNext = NULL; + fence_desc.flags = 0; + if ((vr = vk_funcs->p_vkCreateFence(vk_device, &fence_desc, NULL, &vk_fence)) < 0) + { + WARN("Failed to create Vulkan fence, vr %d.\n", vr); + d3d12_swapchain_destroy(swapchain); + return hresult_from_vk_result(vr); + } + swapchain->vk_fence = vk_fence; + + swapchain->current_buffer_index = 0; + if ((vr = d3d12_swapchain_acquire_next_back_buffer(swapchain)) < 0) + { + d3d12_swapchain_destroy(swapchain); + return hresult_from_vk_result(vr); + } + + IWineDXGIFactory_AddRef(swapchain->factory = factory); + + return S_OK; +} + +HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window, + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, + IDXGISwapChain1 **swapchain) +{ + DXGI_SWAP_CHAIN_FULLSCREEN_DESC default_fullscreen_desc; + struct d3d12_swapchain *object; + ID3D12Device *device; + HRESULT hr; + + if (swapchain_desc->Format == DXGI_FORMAT_UNKNOWN) + return DXGI_ERROR_INVALID_CALL; + + if (!fullscreen_desc) + { + memset(&default_fullscreen_desc, 0, sizeof(default_fullscreen_desc)); + default_fullscreen_desc.Windowed = TRUE; + fullscreen_desc = &default_fullscreen_desc; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = ID3D12CommandQueue_GetDevice(queue, &IID_ID3D12Device, (void **)&device))) + { + ERR("Failed to get D3D12 device, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + hr = d3d12_swapchain_init(object, factory, device, queue, window, swapchain_desc, fullscreen_desc); + ID3D12Device_Release(device); + if (FAILED(hr)) + { + heap_free(object); + return hr; + } + + TRACE("Created swapchain %p.\n", object); + + *swapchain = (IDXGISwapChain1 *)&object->IDXGISwapChain3_iface; + + return S_OK; +} + +#else + +HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window, + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, + IDXGISwapChain1 **swapchain) +{ + ERR_(winediag)("Wine was built without Direct3D 12 support.\n"); + return DXGI_ERROR_UNSUPPORTED; +} + +#endif /* SONAME_LIBVKD3D */ diff --git a/dll/directx/wine/dxgi/utils.c b/dll/directx/wine/dxgi/utils.c new file mode 100644 index 00000000000..aece3a6af1c --- /dev/null +++ b/dll/directx/wine/dxgi/utils.c @@ -0,0 +1,695 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +#define WINE_DXGI_TO_STR(x) case x: return #x + +static const char *debug_feature_level(D3D_FEATURE_LEVEL feature_level) +{ + switch (feature_level) + { + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_9_1); + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_9_2); + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_9_3); + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_10_0); + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_10_1); + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_11_0); + WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_11_1); + default: + FIXME("Unrecognized D3D_FEATURE_LEVEL %#x.\n", feature_level); + return "unrecognized"; + } +} + +const char *debug_dxgi_format(DXGI_FORMAT format) +{ + switch(format) + { + WINE_DXGI_TO_STR(DXGI_FORMAT_UNKNOWN); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G8X24_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10A2_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10A2_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10A2_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R11G11B10_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_D32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R24G8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_D24_UNORM_S8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_X24_TYPELESS_G8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_D16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_A8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R1_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_B8G8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_G8R8_G8B8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC1_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC1_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC1_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC2_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC2_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC2_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC3_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC3_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC3_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC4_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC4_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC4_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC5_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC5_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC5_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B5G6R5_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B5G5R5A1_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8A8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8X8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC6H_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC6H_UF16); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC6H_SF16); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC7_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC7_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC7_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_B4G4R4A4_UNORM); + default: + FIXME("Unrecognized DXGI_FORMAT %#x.\n", format); + return "unrecognized"; + } +} + +#undef WINE_DXGI_TO_STR + +DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) +{ + switch(format) + { + case WINED3DFMT_UNKNOWN: return DXGI_FORMAT_UNKNOWN; + case WINED3DFMT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS; + case WINED3DFMT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case WINED3DFMT_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT; + case WINED3DFMT_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_SINT; + case WINED3DFMT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_TYPELESS; + case WINED3DFMT_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT; + case WINED3DFMT_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_UINT; + case WINED3DFMT_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_SINT; + case WINED3DFMT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_TYPELESS; + case WINED3DFMT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case WINED3DFMT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case WINED3DFMT_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_UINT; + case WINED3DFMT_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM; + case WINED3DFMT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SINT; + case WINED3DFMT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_TYPELESS; + case WINED3DFMT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT; + case WINED3DFMT_R32G32_UINT: return DXGI_FORMAT_R32G32_UINT; + case WINED3DFMT_R32G32_SINT: return DXGI_FORMAT_R32G32_SINT; + case WINED3DFMT_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS; + case WINED3DFMT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case WINED3DFMT_R32_FLOAT_X8X24_TYPELESS: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + case WINED3DFMT_X32_TYPELESS_G8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case WINED3DFMT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_TYPELESS; + case WINED3DFMT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM; + case WINED3DFMT_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UINT; + case WINED3DFMT_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT; + case WINED3DFMT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS; + case WINED3DFMT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case WINED3DFMT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + case WINED3DFMT_R8G8B8A8_UINT: return DXGI_FORMAT_R8G8B8A8_UINT; + case WINED3DFMT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM; + case WINED3DFMT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SINT; + case WINED3DFMT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_TYPELESS; + case WINED3DFMT_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT; + case WINED3DFMT_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM; + case WINED3DFMT_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT; + case WINED3DFMT_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM; + case WINED3DFMT_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT; + case WINED3DFMT_R32_TYPELESS: return DXGI_FORMAT_R32_TYPELESS; + case WINED3DFMT_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT; + case WINED3DFMT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case WINED3DFMT_R32_UINT: return DXGI_FORMAT_R32_UINT; + case WINED3DFMT_R32_SINT: return DXGI_FORMAT_R32_SINT; + case WINED3DFMT_R24G8_TYPELESS: return DXGI_FORMAT_R24G8_TYPELESS; + case WINED3DFMT_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case WINED3DFMT_R24_UNORM_X8_TYPELESS: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case WINED3DFMT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + case WINED3DFMT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_TYPELESS; + case WINED3DFMT_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM; + case WINED3DFMT_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT; + case WINED3DFMT_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM; + case WINED3DFMT_R8G8_SINT: return DXGI_FORMAT_R8G8_SINT; + case WINED3DFMT_R16_TYPELESS: return DXGI_FORMAT_R16_TYPELESS; + case WINED3DFMT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case WINED3DFMT_D16_UNORM: return DXGI_FORMAT_D16_UNORM; + case WINED3DFMT_R16_UNORM: return DXGI_FORMAT_R16_UNORM; + case WINED3DFMT_R16_UINT: return DXGI_FORMAT_R16_UINT; + case WINED3DFMT_R16_SNORM: return DXGI_FORMAT_R16_SNORM; + case WINED3DFMT_R16_SINT: return DXGI_FORMAT_R16_SINT; + case WINED3DFMT_R8_TYPELESS: return DXGI_FORMAT_R8_TYPELESS; + case WINED3DFMT_R8_UNORM: return DXGI_FORMAT_R8_UNORM; + case WINED3DFMT_R8_UINT: return DXGI_FORMAT_R8_UINT; + case WINED3DFMT_R8_SNORM: return DXGI_FORMAT_R8_SNORM; + case WINED3DFMT_R8_SINT: return DXGI_FORMAT_R8_SINT; + case WINED3DFMT_A8_UNORM: return DXGI_FORMAT_A8_UNORM; + case WINED3DFMT_R1_UNORM: return DXGI_FORMAT_R1_UNORM; + case WINED3DFMT_R9G9B9E5_SHAREDEXP: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + case WINED3DFMT_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM; + case WINED3DFMT_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case WINED3DFMT_BC1_TYPELESS: return DXGI_FORMAT_BC1_TYPELESS; + case WINED3DFMT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM; + case WINED3DFMT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB; + case WINED3DFMT_BC2_TYPELESS: return DXGI_FORMAT_BC2_TYPELESS; + case WINED3DFMT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM; + case WINED3DFMT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB; + case WINED3DFMT_BC3_TYPELESS: return DXGI_FORMAT_BC3_TYPELESS; + case WINED3DFMT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM; + case WINED3DFMT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB; + case WINED3DFMT_BC4_TYPELESS: return DXGI_FORMAT_BC4_TYPELESS; + case WINED3DFMT_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM; + case WINED3DFMT_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM; + case WINED3DFMT_BC5_TYPELESS: return DXGI_FORMAT_BC5_TYPELESS; + case WINED3DFMT_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM; + case WINED3DFMT_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM; + case WINED3DFMT_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM; + case WINED3DFMT_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM; + case WINED3DFMT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM; + case WINED3DFMT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM; + case WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM: return DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM; + case WINED3DFMT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS; + case WINED3DFMT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case WINED3DFMT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_TYPELESS; + case WINED3DFMT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + case WINED3DFMT_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_TYPELESS; + case WINED3DFMT_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16; + case WINED3DFMT_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16; + case WINED3DFMT_BC7_TYPELESS: return DXGI_FORMAT_BC7_TYPELESS; + case WINED3DFMT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM; + case WINED3DFMT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB; + case WINED3DFMT_B4G4R4A4_UNORM: return DXGI_FORMAT_B4G4R4A4_UNORM; + default: + FIXME("Unhandled wined3d format %#x.\n", format); + return DXGI_FORMAT_UNKNOWN; + } +} + +enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) +{ + switch(format) + { + case DXGI_FORMAT_UNKNOWN: return WINED3DFMT_UNKNOWN; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: return WINED3DFMT_R32G32B32A32_TYPELESS; + case DXGI_FORMAT_R32G32B32A32_FLOAT: return WINED3DFMT_R32G32B32A32_FLOAT; + case DXGI_FORMAT_R32G32B32A32_UINT: return WINED3DFMT_R32G32B32A32_UINT; + case DXGI_FORMAT_R32G32B32A32_SINT: return WINED3DFMT_R32G32B32A32_SINT; + case DXGI_FORMAT_R32G32B32_TYPELESS: return WINED3DFMT_R32G32B32_TYPELESS; + case DXGI_FORMAT_R32G32B32_FLOAT: return WINED3DFMT_R32G32B32_FLOAT; + case DXGI_FORMAT_R32G32B32_UINT: return WINED3DFMT_R32G32B32_UINT; + case DXGI_FORMAT_R32G32B32_SINT: return WINED3DFMT_R32G32B32_SINT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: return WINED3DFMT_R16G16B16A16_TYPELESS; + case DXGI_FORMAT_R16G16B16A16_FLOAT: return WINED3DFMT_R16G16B16A16_FLOAT; + case DXGI_FORMAT_R16G16B16A16_UNORM: return WINED3DFMT_R16G16B16A16_UNORM; + case DXGI_FORMAT_R16G16B16A16_UINT: return WINED3DFMT_R16G16B16A16_UINT; + case DXGI_FORMAT_R16G16B16A16_SNORM: return WINED3DFMT_R16G16B16A16_SNORM; + case DXGI_FORMAT_R16G16B16A16_SINT: return WINED3DFMT_R16G16B16A16_SINT; + case DXGI_FORMAT_R32G32_TYPELESS: return WINED3DFMT_R32G32_TYPELESS; + case DXGI_FORMAT_R32G32_FLOAT: return WINED3DFMT_R32G32_FLOAT; + case DXGI_FORMAT_R32G32_UINT: return WINED3DFMT_R32G32_UINT; + case DXGI_FORMAT_R32G32_SINT: return WINED3DFMT_R32G32_SINT; + case DXGI_FORMAT_R32G8X24_TYPELESS: return WINED3DFMT_R32G8X24_TYPELESS; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return WINED3DFMT_D32_FLOAT_S8X24_UINT; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return WINED3DFMT_R32_FLOAT_X8X24_TYPELESS; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return WINED3DFMT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: return WINED3DFMT_R10G10B10A2_TYPELESS; + case DXGI_FORMAT_R10G10B10A2_UNORM: return WINED3DFMT_R10G10B10A2_UNORM; + case DXGI_FORMAT_R10G10B10A2_UINT: return WINED3DFMT_R10G10B10A2_UINT; + case DXGI_FORMAT_R11G11B10_FLOAT: return WINED3DFMT_R11G11B10_FLOAT; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: return WINED3DFMT_R8G8B8A8_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_UNORM: return WINED3DFMT_R8G8B8A8_UNORM; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return WINED3DFMT_R8G8B8A8_UNORM_SRGB; + case DXGI_FORMAT_R8G8B8A8_UINT: return WINED3DFMT_R8G8B8A8_UINT; + case DXGI_FORMAT_R8G8B8A8_SNORM: return WINED3DFMT_R8G8B8A8_SNORM; + case DXGI_FORMAT_R8G8B8A8_SINT: return WINED3DFMT_R8G8B8A8_SINT; + case DXGI_FORMAT_R16G16_TYPELESS: return WINED3DFMT_R16G16_TYPELESS; + case DXGI_FORMAT_R16G16_FLOAT: return WINED3DFMT_R16G16_FLOAT; + case DXGI_FORMAT_R16G16_UNORM: return WINED3DFMT_R16G16_UNORM; + case DXGI_FORMAT_R16G16_UINT: return WINED3DFMT_R16G16_UINT; + case DXGI_FORMAT_R16G16_SNORM: return WINED3DFMT_R16G16_SNORM; + case DXGI_FORMAT_R16G16_SINT: return WINED3DFMT_R16G16_SINT; + case DXGI_FORMAT_R32_TYPELESS: return WINED3DFMT_R32_TYPELESS; + case DXGI_FORMAT_D32_FLOAT: return WINED3DFMT_D32_FLOAT; + case DXGI_FORMAT_R32_FLOAT: return WINED3DFMT_R32_FLOAT; + case DXGI_FORMAT_R32_UINT: return WINED3DFMT_R32_UINT; + case DXGI_FORMAT_R32_SINT: return WINED3DFMT_R32_SINT; + case DXGI_FORMAT_R24G8_TYPELESS: return WINED3DFMT_R24G8_TYPELESS; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return WINED3DFMT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return WINED3DFMT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return WINED3DFMT_X24_TYPELESS_G8_UINT; + case DXGI_FORMAT_R8G8_TYPELESS: return WINED3DFMT_R8G8_TYPELESS; + case DXGI_FORMAT_R8G8_UNORM: return WINED3DFMT_R8G8_UNORM; + case DXGI_FORMAT_R8G8_UINT: return WINED3DFMT_R8G8_UINT; + case DXGI_FORMAT_R8G8_SNORM: return WINED3DFMT_R8G8_SNORM; + case DXGI_FORMAT_R8G8_SINT: return WINED3DFMT_R8G8_SINT; + case DXGI_FORMAT_R16_TYPELESS: return WINED3DFMT_R16_TYPELESS; + case DXGI_FORMAT_R16_FLOAT: return WINED3DFMT_R16_FLOAT; + case DXGI_FORMAT_D16_UNORM: return WINED3DFMT_D16_UNORM; + case DXGI_FORMAT_R16_UNORM: return WINED3DFMT_R16_UNORM; + case DXGI_FORMAT_R16_UINT: return WINED3DFMT_R16_UINT; + case DXGI_FORMAT_R16_SNORM: return WINED3DFMT_R16_SNORM; + case DXGI_FORMAT_R16_SINT: return WINED3DFMT_R16_SINT; + case DXGI_FORMAT_R8_TYPELESS: return WINED3DFMT_R8_TYPELESS; + case DXGI_FORMAT_R8_UNORM: return WINED3DFMT_R8_UNORM; + case DXGI_FORMAT_R8_UINT: return WINED3DFMT_R8_UINT; + case DXGI_FORMAT_R8_SNORM: return WINED3DFMT_R8_SNORM; + case DXGI_FORMAT_R8_SINT: return WINED3DFMT_R8_SINT; + case DXGI_FORMAT_A8_UNORM: return WINED3DFMT_A8_UNORM; + case DXGI_FORMAT_R1_UNORM: return WINED3DFMT_R1_UNORM; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return WINED3DFMT_R9G9B9E5_SHAREDEXP; + case DXGI_FORMAT_R8G8_B8G8_UNORM: return WINED3DFMT_R8G8_B8G8_UNORM; + case DXGI_FORMAT_G8R8_G8B8_UNORM: return WINED3DFMT_G8R8_G8B8_UNORM; + case DXGI_FORMAT_BC1_TYPELESS: return WINED3DFMT_BC1_TYPELESS; + case DXGI_FORMAT_BC1_UNORM: return WINED3DFMT_BC1_UNORM; + case DXGI_FORMAT_BC1_UNORM_SRGB: return WINED3DFMT_BC1_UNORM_SRGB; + case DXGI_FORMAT_BC2_TYPELESS: return WINED3DFMT_BC2_TYPELESS; + case DXGI_FORMAT_BC2_UNORM: return WINED3DFMT_BC2_UNORM; + case DXGI_FORMAT_BC2_UNORM_SRGB: return WINED3DFMT_BC2_UNORM_SRGB; + case DXGI_FORMAT_BC3_TYPELESS: return WINED3DFMT_BC3_TYPELESS; + case DXGI_FORMAT_BC3_UNORM: return WINED3DFMT_BC3_UNORM; + case DXGI_FORMAT_BC3_UNORM_SRGB: return WINED3DFMT_BC3_UNORM_SRGB; + case DXGI_FORMAT_BC4_TYPELESS: return WINED3DFMT_BC4_TYPELESS; + case DXGI_FORMAT_BC4_UNORM: return WINED3DFMT_BC4_UNORM; + case DXGI_FORMAT_BC4_SNORM: return WINED3DFMT_BC4_SNORM; + case DXGI_FORMAT_BC5_TYPELESS: return WINED3DFMT_BC5_TYPELESS; + case DXGI_FORMAT_BC5_UNORM: return WINED3DFMT_BC5_UNORM; + case DXGI_FORMAT_BC5_SNORM: return WINED3DFMT_BC5_SNORM; + case DXGI_FORMAT_B5G6R5_UNORM: return WINED3DFMT_B5G6R5_UNORM; + case DXGI_FORMAT_B5G5R5A1_UNORM: return WINED3DFMT_B5G5R5A1_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM: return WINED3DFMT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_UNORM: return WINED3DFMT_B8G8R8X8_UNORM; + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: return WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return WINED3DFMT_B8G8R8A8_TYPELESS; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return WINED3DFMT_B8G8R8A8_UNORM_SRGB; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return WINED3DFMT_B8G8R8X8_TYPELESS; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return WINED3DFMT_B8G8R8X8_UNORM_SRGB; + case DXGI_FORMAT_BC6H_TYPELESS: return WINED3DFMT_BC6H_TYPELESS; + case DXGI_FORMAT_BC6H_UF16: return WINED3DFMT_BC6H_UF16; + case DXGI_FORMAT_BC6H_SF16: return WINED3DFMT_BC6H_SF16; + case DXGI_FORMAT_BC7_TYPELESS: return WINED3DFMT_BC7_TYPELESS; + case DXGI_FORMAT_BC7_UNORM: return WINED3DFMT_BC7_UNORM; + case DXGI_FORMAT_BC7_UNORM_SRGB: return WINED3DFMT_BC7_UNORM_SRGB; + case DXGI_FORMAT_B4G4R4A4_UNORM: return WINED3DFMT_B4G4R4A4_UNORM; + default: + FIXME("Unhandled DXGI_FORMAT %#x.\n", format); + return WINED3DFMT_UNKNOWN; + } +} + +const char *debug_dxgi_mode(const DXGI_MODE_DESC *desc) +{ + if (!desc) + return "(null)"; + + return wine_dbg_sprintf("resolution %ux%u, refresh rate %u / %u, " + "format %s, scanline ordering %#x, scaling %#x", + desc->Width, desc->Height, desc->RefreshRate.Numerator, desc->RefreshRate.Denominator, + debug_dxgi_format(desc->Format), desc->ScanlineOrdering, desc->Scaling); +} + +const char *debug_dxgi_mode1(const DXGI_MODE_DESC1 *desc) +{ + if (!desc) + return "(null)"; + + return wine_dbg_sprintf("resolution %ux%u, refresh rate %u / %u, " + "format %s, scanline ordering %#x, scaling %#x, stereo %#x", + desc->Width, desc->Height, desc->RefreshRate.Numerator, desc->RefreshRate.Denominator, + debug_dxgi_format(desc->Format), desc->ScanlineOrdering, desc->Scaling, desc->Stereo); +} + +void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) +{ + unsigned int i; + + if (!feature_levels || !level_count) + { + TRACE("Feature levels: (null).\n"); + return; + } + + TRACE("Feature levels (count = %u):\n", level_count); + for (i = 0; i < level_count; ++i) + TRACE(" [%u] = %s.\n", i, debug_feature_level(feature_levels[i])); +} + +static unsigned int dxgi_rational_to_uint(const DXGI_RATIONAL *rational) +{ + if (rational->Denominator) + return rational->Numerator / rational->Denominator; + else + return rational->Numerator; +} + +static enum wined3d_scanline_ordering wined3d_scanline_ordering_from_dxgi(DXGI_MODE_SCANLINE_ORDER scanline_order) +{ + switch (scanline_order) + { + case DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED: + return WINED3D_SCANLINE_ORDERING_UNKNOWN; + case DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE: + return WINED3D_SCANLINE_ORDERING_PROGRESSIVE; + default: + FIXME("Unhandled scanline ordering %#x.\n", scanline_order); + return WINED3D_SCANLINE_ORDERING_UNKNOWN; + } +} + +void dxgi_sample_desc_from_wined3d(DXGI_SAMPLE_DESC *desc, + enum wined3d_multisample_type wined3d_type, unsigned int wined3d_quality) +{ + desc->Count = wined3d_type == WINED3D_MULTISAMPLE_NONE ? 1 : wined3d_type; + desc->Quality = wined3d_quality; +} + +void wined3d_sample_desc_from_dxgi(enum wined3d_multisample_type *wined3d_type, + unsigned int *wined3d_quality, const DXGI_SAMPLE_DESC *dxgi_desc) +{ + if (dxgi_desc->Count > 1) + { + *wined3d_type = dxgi_desc->Count; + *wined3d_quality = dxgi_desc->Quality; + } + else + { + *wined3d_type = WINED3D_MULTISAMPLE_NONE; + *wined3d_quality = 0; + } +} + +void wined3d_display_mode_from_dxgi(struct wined3d_display_mode *wined3d_mode, + const DXGI_MODE_DESC *mode) +{ + wined3d_mode->width = mode->Width; + wined3d_mode->height = mode->Height; + wined3d_mode->refresh_rate = dxgi_rational_to_uint(&mode->RefreshRate); + wined3d_mode->format_id = wined3dformat_from_dxgi_format(mode->Format); + wined3d_mode->scanline_ordering = wined3d_scanline_ordering_from_dxgi(mode->ScanlineOrdering); +} + +void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode, + const DXGI_MODE_DESC1 *mode) +{ + wined3d_mode->width = mode->Width; + wined3d_mode->height = mode->Height; + wined3d_mode->refresh_rate = dxgi_rational_to_uint(&mode->RefreshRate); + wined3d_mode->format_id = wined3dformat_from_dxgi_format(mode->Format); + wined3d_mode->scanline_ordering = wined3d_scanline_ordering_from_dxgi(mode->ScanlineOrdering); + FIXME("Ignoring stereo %#x.\n", mode->Stereo); +} + +DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) +{ + DXGI_USAGE dxgi_usage = 0; + + if (wined3d_bind_flags & WINED3D_BIND_SHADER_RESOURCE) + dxgi_usage |= DXGI_USAGE_SHADER_INPUT; + if (wined3d_bind_flags & WINED3D_BIND_RENDER_TARGET) + dxgi_usage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; + + wined3d_bind_flags &= ~(WINED3D_BIND_SHADER_RESOURCE | WINED3D_BIND_RENDER_TARGET); + if (wined3d_bind_flags) + FIXME("Unhandled wined3d bind flags %#x.\n", wined3d_bind_flags); + return dxgi_usage; +} + +unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE dxgi_usage) +{ + unsigned int wined3d_bind_flags = 0; + + if (dxgi_usage & DXGI_USAGE_SHADER_INPUT) + wined3d_bind_flags |= WINED3D_BIND_SHADER_RESOURCE; + if (dxgi_usage & DXGI_USAGE_RENDER_TARGET_OUTPUT) + wined3d_bind_flags |= WINED3D_BIND_RENDER_TARGET; + + dxgi_usage &= ~(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT); + if (dxgi_usage) + FIXME("Unhandled DXGI usage %#x.\n", dxgi_usage); + return wined3d_bind_flags; +} + +#define DXGI_WINED3D_SWAPCHAIN_FLAGS \ + (WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE | WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT | WINED3D_SWAPCHAIN_HOOK) + +unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) +{ + unsigned int flags = 0; + + wined3d_flags &= ~DXGI_WINED3D_SWAPCHAIN_FLAGS; + + if (wined3d_flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) + { + wined3d_flags &= ~WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; + flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + } + + if (wined3d_flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + { + wined3d_flags &= ~WINED3D_SWAPCHAIN_GDI_COMPATIBLE; + flags |= DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; + } + + if (wined3d_flags) + FIXME("Unhandled flags %#x.\n", flags); + + return flags; +} + +static unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) +{ + unsigned int wined3d_flags = DXGI_WINED3D_SWAPCHAIN_FLAGS; /* WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL? */ + + if (flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) + { + flags &= ~DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + wined3d_flags |= WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; + } + + if (flags & DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) + { + flags &= ~DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; + wined3d_flags |= WINED3D_SWAPCHAIN_GDI_COMPATIBLE; + } + + if (flags) + FIXME("Unhandled flags %#x.\n", flags); + + return wined3d_flags; +} + +HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc, HWND window, + const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *dxgi_fullscreen_desc) +{ + if (dxgi_desc->Scaling != DXGI_SCALING_STRETCH) + FIXME("Ignoring scaling %#x.\n", dxgi_desc->Scaling); + if (dxgi_desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE) + FIXME("Ignoring alpha mode %#x.\n", dxgi_desc->AlphaMode); + if (dxgi_fullscreen_desc && dxgi_fullscreen_desc->ScanlineOrdering) + FIXME("Unhandled scanline ordering %#x.\n", dxgi_fullscreen_desc->ScanlineOrdering); + if (dxgi_fullscreen_desc && dxgi_fullscreen_desc->Scaling) + FIXME("Unhandled mode scaling %#x.\n", dxgi_fullscreen_desc->Scaling); + + switch (dxgi_desc->SwapEffect) + { + case DXGI_SWAP_EFFECT_DISCARD: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_DISCARD; + break; + case DXGI_SWAP_EFFECT_SEQUENTIAL: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_SEQUENTIAL; + break; + case DXGI_SWAP_EFFECT_FLIP_DISCARD: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_FLIP_DISCARD; + break; + case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL; + break; + default: + WARN("Invalid swap effect %#x.\n", dxgi_desc->SwapEffect); + return DXGI_ERROR_INVALID_CALL; + } + + wined3d_desc->backbuffer_width = dxgi_desc->Width; + wined3d_desc->backbuffer_height = dxgi_desc->Height; + wined3d_desc->backbuffer_format = wined3dformat_from_dxgi_format(dxgi_desc->Format); + wined3d_desc->backbuffer_count = dxgi_desc->BufferCount; + wined3d_desc->backbuffer_bind_flags = wined3d_bind_flags_from_dxgi_usage(dxgi_desc->BufferUsage); + wined3d_sample_desc_from_dxgi(&wined3d_desc->multisample_type, + &wined3d_desc->multisample_quality, &dxgi_desc->SampleDesc); + wined3d_desc->device_window = window; + wined3d_desc->windowed = dxgi_fullscreen_desc ? dxgi_fullscreen_desc->Windowed : TRUE; + wined3d_desc->enable_auto_depth_stencil = FALSE; + wined3d_desc->auto_depth_stencil_format = 0; + wined3d_desc->flags = wined3d_swapchain_flags_from_dxgi(dxgi_desc->Flags); + wined3d_desc->refresh_rate = dxgi_fullscreen_desc ? dxgi_rational_to_uint(&dxgi_fullscreen_desc->RefreshRate) : 0; + wined3d_desc->auto_restore_display_mode = TRUE; + + return S_OK; +} + +HRESULT dxgi_get_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT *data_size, void *data) +{ + const struct wined3d_private_data *stored_data; + DWORD size_in; + HRESULT hr; + + if (!data_size) + return E_INVALIDARG; + + wined3d_mutex_lock(); + if (!(stored_data = wined3d_private_store_get_private_data(store, guid))) + { + hr = DXGI_ERROR_NOT_FOUND; + *data_size = 0; + goto done; + } + + size_in = *data_size; + *data_size = stored_data->size; + if (!data) + { + hr = S_OK; + goto done; + } + if (size_in < stored_data->size) + { + hr = DXGI_ERROR_MORE_DATA; + goto done; + } + + if (stored_data->flags & WINED3DSPD_IUNKNOWN) + IUnknown_AddRef(stored_data->content.object); + memcpy(data, stored_data->content.data, stored_data->size); + hr = S_OK; + +done: + wined3d_mutex_unlock(); + + return hr; +} + +HRESULT dxgi_set_private_data(struct wined3d_private_store *store, + REFGUID guid, UINT data_size, const void *data) +{ + struct wined3d_private_data *entry; + HRESULT hr; + + if (!data) + { + wined3d_mutex_lock(); + if (!(entry = wined3d_private_store_get_private_data(store, guid))) + { + wined3d_mutex_unlock(); + return S_FALSE; + } + + wined3d_private_store_free_private_data(store, entry); + wined3d_mutex_unlock(); + + return S_OK; + } + + wined3d_mutex_lock(); + hr = wined3d_private_store_set_private_data(store, guid, data, data_size, 0); + wined3d_mutex_unlock(); + + return hr; +} + +HRESULT dxgi_set_private_data_interface(struct wined3d_private_store *store, + REFGUID guid, const IUnknown *object) +{ + HRESULT hr; + + if (!object) + return dxgi_set_private_data(store, guid, sizeof(object), &object); + + wined3d_mutex_lock(); + hr = wined3d_private_store_set_private_data(store, + guid, object, sizeof(object), WINED3DSPD_IUNKNOWN); + wined3d_mutex_unlock(); + + return hr; +} diff --git a/dll/directx/wine/dxgi/version.rc b/dll/directx/wine/dxgi/version.rc new file mode 100644 index 00000000000..bd51eb8c55b --- /dev/null +++ b/dll/directx/wine/dxgi/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine DXGI" +#define WINE_FILENAME_STR "dxgi.dll" +#define WINE_FILEVERSION 6,0,6000,16386 +#define WINE_FILEVERSION_STR "6.0.6000.16386" +#define WINE_PRODUCTVERSION 6,0,6000,16386 +#define WINE_PRODUCTVERSION_STR "6.0.6000.16386" + +#include "wine/wine_common_ver.rc" diff --git a/dll/directx/wine/wined3d/CMakeLists.txt b/dll/directx/wine/wined3d/CMakeLists.txt index 58f15cfbc14..d2694747d91 100644 --- a/dll/directx/wine/wined3d/CMakeLists.txt +++ b/dll/directx/wine/wined3d/CMakeLists.txt @@ -13,6 +13,8 @@ include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(d3dwine.dll wined3d.spec ADD_IMPORTLIB) list(APPEND SOURCE + adapter_gl.c + adapter_vk.c arb_program_shader.c ati_fragment_shader.c buffer.c @@ -28,9 +30,9 @@ list(APPEND SOURCE query.c resource.c sampler.c - shader.c shader_sm1.c shader_sm4.c + shader.c state.c stateblock.c surface.c diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c new file mode 100644 index 00000000000..4830769faf6 --- /dev/null +++ b/dll/directx/wine/wined3d/adapter_gl.c @@ -0,0 +1,5367 @@ +/* + * Copyright 2002-2004 Jason Edmeades + * Copyright 2003-2004 Raphael Junqueira + * Copyright 2004 Christian Costa + * Copyright 2005 Oliver Stieber + * Copyright 2007-2008 Stefan Dösinger for CodeWeavers + * Copyright 2009-2011, 2018 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include + +#include "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); +WINE_DECLARE_DEBUG_CHANNEL(winediag); + +enum wined3d_gl_vendor +{ + GL_VENDOR_UNKNOWN, + GL_VENDOR_APPLE, + GL_VENDOR_FGLRX, + GL_VENDOR_MESA, + GL_VENDOR_NVIDIA, +}; + +struct wined3d_extension_map +{ + const char *extension_string; + enum wined3d_gl_extension extension; +}; + +static const struct wined3d_extension_map gl_extension_map[] = +{ + /* APPLE */ + {"GL_APPLE_fence", APPLE_FENCE }, + {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS }, + {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE }, + {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422 }, + + /* ARB */ + {"GL_ARB_base_instance", ARB_BASE_INSTANCE }, + {"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED }, + {"GL_ARB_buffer_storage", ARB_BUFFER_STORAGE }, + {"GL_ARB_clear_buffer_object", ARB_CLEAR_BUFFER_OBJECT }, + {"GL_ARB_clear_texture", ARB_CLEAR_TEXTURE }, + {"GL_ARB_clip_control", ARB_CLIP_CONTROL }, + {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT }, + {"GL_ARB_compute_shader", ARB_COMPUTE_SHADER }, + {"GL_ARB_conservative_depth", ARB_CONSERVATIVE_DEPTH }, + {"GL_ARB_copy_buffer", ARB_COPY_BUFFER }, + {"GL_ARB_copy_image", ARB_COPY_IMAGE }, + {"GL_ARB_cull_distance", ARB_CULL_DISTANCE }, + {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT }, + {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT }, + {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP }, + {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE }, + {"GL_ARB_derivative_control", ARB_DERIVATIVE_CONTROL }, + {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS }, + {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX }, + {"GL_ARB_draw_indirect", ARB_DRAW_INDIRECT }, + {"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED }, + {"GL_ARB_ES2_compatibility", ARB_ES2_COMPATIBILITY }, + {"GL_ARB_ES3_compatibility", ARB_ES3_COMPATIBILITY }, + {"GL_ARB_explicit_attrib_location", ARB_EXPLICIT_ATTRIB_LOCATION }, + {"GL_ARB_fragment_coord_conventions", ARB_FRAGMENT_COORD_CONVENTIONS}, + {"GL_ARB_fragment_layer_viewport", ARB_FRAGMENT_LAYER_VIEWPORT }, + {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, + {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER }, + {"GL_ARB_framebuffer_no_attachments", ARB_FRAMEBUFFER_NO_ATTACHMENTS}, + {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, + {"GL_ARB_framebuffer_sRGB", ARB_FRAMEBUFFER_SRGB }, + {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4 }, + {"GL_ARB_gpu_shader5", ARB_GPU_SHADER5 }, + {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL }, + {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX }, + {"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS }, + {"GL_ARB_internalformat_query", ARB_INTERNALFORMAT_QUERY }, + {"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2 }, + {"GL_ARB_map_buffer_alignment", ARB_MAP_BUFFER_ALIGNMENT }, + {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE }, + {"GL_ARB_multisample", ARB_MULTISAMPLE }, + {"GL_ARB_multitexture", ARB_MULTITEXTURE }, + {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY }, + {"GL_ARB_pipeline_statistics_query", ARB_PIPELINE_STATISTICS_QUERY }, + {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT }, + {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS }, + {"GL_ARB_point_sprite", ARB_POINT_SPRITE }, + {"GL_ARB_polygon_offset_clamp", ARB_POLYGON_OFFSET_CLAMP }, + {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX }, + {"GL_ARB_query_buffer_object", ARB_QUERY_BUFFER_OBJECT }, + {"GL_ARB_sample_shading", ARB_SAMPLE_SHADING }, + {"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS }, + {"GL_ARB_seamless_cube_map", ARB_SEAMLESS_CUBE_MAP }, + {"GL_ARB_shader_atomic_counters", ARB_SHADER_ATOMIC_COUNTERS }, + {"GL_ARB_shader_bit_encoding", ARB_SHADER_BIT_ENCODING }, + {"GL_ARB_shader_image_load_store", ARB_SHADER_IMAGE_LOAD_STORE }, + {"GL_ARB_shader_image_size", ARB_SHADER_IMAGE_SIZE }, + {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT}, + {"GL_ARB_shader_texture_image_samples", ARB_SHADER_TEXTURE_IMAGE_SAMPLES}, + {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD }, + {"GL_ARB_shader_viewport_layer_array", ARB_SHADER_VIEWPORT_LAYER_ARRAY}, + {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 }, + {"GL_ARB_shading_language_420pack", ARB_SHADING_LANGUAGE_420PACK }, + {"GL_ARB_shading_language_packing", ARB_SHADING_LANGUAGE_PACKING }, + {"GL_ARB_shadow", ARB_SHADOW }, + {"GL_ARB_stencil_texturing", ARB_STENCIL_TEXTURING }, + {"GL_ARB_sync", ARB_SYNC }, + {"GL_ARB_tessellation_shader", ARB_TESSELLATION_SHADER }, + {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP }, + {"GL_ARB_texture_buffer_object", ARB_TEXTURE_BUFFER_OBJECT }, + {"GL_ARB_texture_buffer_range", ARB_TEXTURE_BUFFER_RANGE }, + {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION }, + {"GL_ARB_texture_compression_bptc", ARB_TEXTURE_COMPRESSION_BPTC }, + {"GL_ARB_texture_compression_rgtc", ARB_TEXTURE_COMPRESSION_RGTC }, + {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP }, + {"GL_ARB_texture_cube_map_array", ARB_TEXTURE_CUBE_MAP_ARRAY }, + {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE }, + {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3 }, + {"GL_ARB_texture_filter_anisotropic", ARB_TEXTURE_FILTER_ANISOTROPIC}, + {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT }, + {"GL_ARB_texture_gather", ARB_TEXTURE_GATHER }, + {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT }, + {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE}, + {"GL_ARB_texture_multisample", ARB_TEXTURE_MULTISAMPLE }, + {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO }, + {"GL_ARB_texture_query_levels", ARB_TEXTURE_QUERY_LEVELS }, + {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE }, + {"GL_ARB_texture_rg", ARB_TEXTURE_RG }, + {"GL_ARB_texture_rgb10_a2ui", ARB_TEXTURE_RGB10_A2UI }, + {"GL_ARB_texture_storage", ARB_TEXTURE_STORAGE }, + {"GL_ARB_texture_storage_multisample", ARB_TEXTURE_STORAGE_MULTISAMPLE}, + {"GL_ARB_texture_swizzle", ARB_TEXTURE_SWIZZLE }, + {"GL_ARB_texture_view", ARB_TEXTURE_VIEW }, + {"GL_ARB_timer_query", ARB_TIMER_QUERY }, + {"GL_ARB_transform_feedback2", ARB_TRANSFORM_FEEDBACK2 }, + {"GL_ARB_transform_feedback3", ARB_TRANSFORM_FEEDBACK3 }, + {"GL_ARB_uniform_buffer_object", ARB_UNIFORM_BUFFER_OBJECT }, + {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA }, + {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT }, + {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM }, + {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER }, + {"GL_ARB_vertex_type_2_10_10_10_rev", ARB_VERTEX_TYPE_2_10_10_10_REV}, + {"GL_ARB_viewport_array", ARB_VIEWPORT_ARRAY }, + + /* ATI */ + {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER }, + {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL }, + {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC }, + {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3 }, + {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE }, + + /* EXT */ + {"GL_EXT_blend_color", EXT_BLEND_COLOR }, + {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE }, + {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE }, + {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX }, + {"GL_EXT_blend_subtract", EXT_BLEND_SUBTRACT }, + {"GL_EXT_depth_bounds_test", EXT_DEPTH_BOUNDS_TEST }, + {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2 }, + {"GL_EXT_fog_coord", EXT_FOG_COORD }, + {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT }, + {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE }, + {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT }, + {"GL_EXT_memory_object", EXT_MEMORY_OBJECT }, + {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS }, + {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4 }, + {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL }, + {"GL_EXT_packed_float", EXT_PACKED_FLOAT }, + {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS }, + {"GL_EXT_polygon_offset_clamp", ARB_POLYGON_OFFSET_CLAMP }, + {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX }, + {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR }, + {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE }, + {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP }, + {"GL_EXT_texture3D", EXT_TEXTURE3D }, + {"GL_EXT_texture_array", EXT_TEXTURE_ARRAY }, + {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC }, + {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC }, + {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE }, + {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3 }, + {"GL_EXT_texture_filter_anisotropic", ARB_TEXTURE_FILTER_ANISOTROPIC}, + {"GL_EXT_texture_integer", EXT_TEXTURE_INTEGER }, + {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS }, + {"GL_EXT_texture_mirror_clamp", EXT_TEXTURE_MIRROR_CLAMP }, + {"GL_EXT_texture_shadow_lod", EXT_TEXTURE_SHADOW_LOD }, + {"GL_EXT_texture_shared_exponent", EXT_TEXTURE_SHARED_EXPONENT }, + {"GL_EXT_texture_snorm", EXT_TEXTURE_SNORM }, + {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB }, + {"GL_EXT_texture_sRGB_decode", EXT_TEXTURE_SRGB_DECODE }, + {"GL_EXT_texture_swizzle", ARB_TEXTURE_SWIZZLE }, + {"GL_EXT_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA }, + + /* NV */ + {"GL_NV_fence", NV_FENCE }, + {"GL_NV_fog_distance", NV_FOG_DISTANCE }, + {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM }, + {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2 }, + {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION }, + {"GL_NV_half_float", NV_HALF_FLOAT }, + {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT }, + {"GL_NV_point_sprite", NV_POINT_SPRITE }, + {"GL_NV_register_combiners", NV_REGISTER_COMBINERS }, + {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2 }, + {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION }, + {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4 }, + {"GL_NV_texture_shader", NV_TEXTURE_SHADER }, + {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2 }, + {"GL_NV_vertex_program", NV_VERTEX_PROGRAM }, + {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1 }, + {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 }, + {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION }, + {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 }, + {"GL_NVX_gpu_memory_info", NVX_GPU_MEMORY_INFO }, +}; + +static const struct wined3d_extension_map wgl_extension_map[] = +{ + {"WGL_ARB_pixel_format", WGL_ARB_PIXEL_FORMAT }, + {"WGL_EXT_swap_control", WGL_EXT_SWAP_CONTROL }, + {"WGL_WINE_pixel_format_passthrough", WGL_WINE_PIXEL_FORMAT_PASSTHROUGH}, + {"WGL_WINE_query_renderer", WGL_WINE_QUERY_RENDERER }, +}; + +static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx) +{ + const struct wined3d_gl_info *gl_info = ctx->gl_info; + + TRACE("Destroying caps GL context.\n"); + + /* Both glDeleteProgram and glDeleteBuffers silently ignore 0 IDs but + * this function might be called before the relevant function pointers + * in gl_info are initialized. */ + if (ctx->test_program_id || ctx->test_vbo) + { + GL_EXTCALL(glDeleteProgram(ctx->test_program_id)); + GL_EXTCALL(glDeleteBuffers(1, &ctx->test_vbo)); + } + + if (!wglMakeCurrent(NULL, NULL)) + ERR("Failed to disable caps GL context.\n"); + + if (!wglDeleteContext(ctx->gl_ctx)) + { + DWORD err = GetLastError(); + ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err); + } + + wined3d_release_dc(ctx->wnd, ctx->dc); + DestroyWindow(ctx->wnd); + + if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx)) + ERR("Failed to restore previous GL context.\n"); +} + +static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx, + struct wined3d_gl_info *gl_info) +{ + HGLRC new_ctx; + + if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB"))) + return TRUE; + + if (!(new_ctx = context_create_wgl_attribs(gl_info, caps_gl_ctx->dc, NULL))) + { + gl_info->p_wglCreateContextAttribsARB = NULL; + return FALSE; + } + + if (!wglMakeCurrent(caps_gl_ctx->dc, new_ctx)) + { + ERR("Failed to make new context current, last error %#x.\n", GetLastError()); + if (!wglDeleteContext(new_ctx)) + ERR("Failed to delete new context, last error %#x.\n", GetLastError()); + gl_info->p_wglCreateContextAttribsARB = NULL; + return TRUE; + } + + if (!wglDeleteContext(caps_gl_ctx->gl_ctx)) + ERR("Failed to delete old context, last error %#x.\n", GetLastError()); + caps_gl_ctx->gl_ctx = new_ctx; + + return TRUE; +} + +static BOOL wined3d_caps_gl_ctx_create(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) +{ + PIXELFORMATDESCRIPTOR pfd; + int iPixelFormat; + + TRACE("getting context...\n"); + + ctx->restore_dc = wglGetCurrentDC(); + ctx->restore_gl_ctx = wglGetCurrentContext(); + + /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */ + ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", + WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL); + if (!ctx->wnd) + { + ERR("Failed to create a window.\n"); + goto fail; + } + + ctx->dc = GetDC(ctx->wnd); + if (!ctx->dc) + { + ERR("Failed to get a DC.\n"); + goto fail; + } + + /* PixelFormat selection */ + ZeroMemory(&pfd, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */ + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.iLayerType = PFD_MAIN_PLANE; + + if (!(iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd))) + { + /* If this happens something is very wrong as ChoosePixelFormat barely fails. */ + ERR("Failed to find a suitable pixel format.\n"); + goto fail; + } + DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd); + SetPixelFormat(ctx->dc, iPixelFormat, &pfd); + + /* Create a GL context. */ + if (!(ctx->gl_ctx = wglCreateContext(ctx->dc))) + { + WARN("Failed to create default context for capabilities initialization.\n"); + goto fail; + } + + /* Make it the current GL context. */ + if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx)) + { + ERR("Failed to make caps GL context current.\n"); + goto fail; + } + + ctx->gl_info = &adapter->gl_info; + return TRUE; + +fail: + if (ctx->gl_ctx) wglDeleteContext(ctx->gl_ctx); + ctx->gl_ctx = NULL; + if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc); + ctx->dc = NULL; + if (ctx->wnd) DestroyWindow(ctx->wnd); + ctx->wnd = NULL; + if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx)) + ERR("Failed to restore previous GL context.\n"); + + return FALSE; +} + +/* Context activation is done by the caller. */ +static BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info) +{ + GLuint prog; + BOOL ret = FALSE; + static const char testcode[] = + "!!ARBvp1.0\n" + "PARAM C[66] = { program.env[0..65] };\n" + "ADDRESS A0;" + "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n" + "ARL A0.x, zero.x;\n" + "MOV result.position, C[A0.x + 65];\n" + "END\n"; + + while (gl_info->gl_ops.gl.p_glGetError()); + GL_EXTCALL(glGenProgramsARB(1, &prog)); + if(!prog) { + ERR("Failed to create an ARB offset limit test program\n"); + } + GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog)); + GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(testcode), testcode)); + if (gl_info->gl_ops.gl.p_glGetError()) + { + TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n"); + TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB))); + ret = TRUE; + } else TRACE("OpenGL implementation allows offsets > 63\n"); + + GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0)); + GL_EXTCALL(glDeleteProgramsARB(1, &prog)); + checkGLcall("ARB vp offset limit test cleanup"); + + return ret; +} + +static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + return card_vendor == HW_VENDOR_AMD + && (device == CARD_AMD_RADEON_9500 + || device == CARD_AMD_RADEON_X700 + || device == CARD_AMD_RADEON_X1600); +} + +static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + return card_vendor == HW_VENDOR_NVIDIA + && (device == CARD_NVIDIA_GEFORCEFX_5200 + || device == CARD_NVIDIA_GEFORCEFX_5600 + || device == CARD_NVIDIA_GEFORCEFX_5800); +} + +static BOOL match_apple(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + /* MacOS has various specialities in the extensions it advertises. Some + * have to be loaded from the OpenGL 1.2+ core, while other extensions are + * advertised, but software emulated. So try to detect the Apple OpenGL + * implementation to apply some extension fixups afterwards. + * + * Detecting this isn't really easy. The vendor string doesn't mention + * Apple. Compile-time checks aren't sufficient either because a Linux + * binary may display on a macOS X server via remote X11. So try to detect + * the OpenGL implementation by looking at certain Apple extensions. Some + * extensions like client storage might be supported on other + * implementations too, but GL_APPLE_flush_render is specific to the + * macOS X window management, and GL_APPLE_ycbcr_422 is QuickTime + * specific. So the chance that other implementations support them is + * rather small since Win32 QuickTime uses DirectDraw, not OpenGL. + * + * This test has been moved into wined3d_guess_gl_vendor(). */ + return gl_vendor == GL_VENDOR_APPLE; +} + +/* Context activation is done by the caller. */ +static void test_pbo_functionality(struct wined3d_gl_info *gl_info) +{ + /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs, + * but glTexSubImage from a PBO fails miserably, with the first line repeated over + * all the texture. This function detects this bug by its symptom and disables PBOs + * if the test fails. + * + * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA, + * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use + * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data + * read back is compared to the original. If they are equal PBOs are assumed to work, + * otherwise the PBO extension is disabled. */ + GLuint texture, pbo; + static const unsigned int pattern[] = + { + 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000, + 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff, + 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff, + 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff + }; + unsigned int check[ARRAY_SIZE(pattern)]; + + /* No PBO -> No point in testing them. */ + if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return; + + while (gl_info->gl_ops.gl.p_glGetError()); + gl_info->gl_ops.gl.p_glGenTextures(1, &texture); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture); + + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); + checkGLcall("Specifying the PBO test texture"); + + GL_EXTCALL(glGenBuffers(1, &pbo)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo)); + GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pattern), pattern, GL_STREAM_DRAW)); + checkGLcall("Specifying the PBO test pbo"); + + gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + checkGLcall("Loading the PBO test texture"); + + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + + gl_info->gl_ops.gl.p_glFinish(); /* just to be sure */ + + memset(check, 0, sizeof(check)); + gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check); + checkGLcall("Reading back the PBO test texture"); + + gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture); + GL_EXTCALL(glDeleteBuffers(1, &pbo)); + checkGLcall("PBO test cleanup"); + + if (memcmp(check, pattern, sizeof(check))) + { + WARN_(d3d_perf)("PBO test failed, read back data doesn't match original.\n" + "Disabling PBOs. This may result in slower performance.\n"); + gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE; + } + else + { + TRACE("PBO test successful.\n"); + } +} + +static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE); +} + +static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + if (gl_vendor != GL_VENDOR_APPLE) return FALSE; + if (card_vendor != HW_VENDOR_AMD) return FALSE; + if (device == CARD_AMD_RADEON_X1600) return FALSE; + return TRUE; +} + +static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + /* Direct3D 9 cards support 40 single float varyings in hardware, most + * drivers report 32. ATI misreports 44 varyings. So assume that if we + * have more than 44 varyings we have a Direct3D 10+ card. This detection + * is for the gl_ClipPos varying quirk. If a Direct3D 9 card really + * supports more than 44 varyings and we subtract one in Direct3D 9 + * shaders it's not going to hurt us because the Direct3D 9 limit is + * hardcoded. + * + * Direct3D 10 cards usually have 64 varyings. */ + return gl_info->limits.glsl_varyings > 44; +} + +static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + return !match_dx10_capable(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device); +} + +/* A GL context is provided by the caller */ +static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + GLenum error; + DWORD data[16]; + + if (!gl_info->supported[EXT_SECONDARY_COLOR] || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + return FALSE; + + while (gl_info->gl_ops.gl.p_glGetError()); + GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data); + error = gl_info->gl_ops.gl.p_glGetError(); + + if (error == GL_NO_ERROR) + { + TRACE("GL Implementation accepts 4 component specular color pointers\n"); + return TRUE; + } + else + { + TRACE("GL implementation does not accept 4 component specular colors, error %s\n", + debug_glerror(error)); + return FALSE; + } +} + +/* A GL context is provided by the caller */ +static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + GLuint prog; + BOOL ret = FALSE; + GLint pos; + static const char testcode[] = + "!!ARBvp1.0\n" + "OPTION NV_vertex_program2;\n" + "MOV result.clip[0], 0.0;\n" + "MOV result.position, 0.0;\n" + "END\n"; + + if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE; + + while (gl_info->gl_ops.gl.p_glGetError()); + + GL_EXTCALL(glGenProgramsARB(1, &prog)); + if(!prog) + { + ERR("Failed to create the NVvp clip test program\n"); + return FALSE; + } + GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog)); + GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(testcode), testcode)); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); + if(pos != -1) + { + WARN("GL_NV_vertex_program2_option result.clip[] test failed\n"); + TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB))); + ret = TRUE; + while (gl_info->gl_ops.gl.p_glGetError()); + } + else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n"); + + GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0)); + GL_EXTCALL(glDeleteProgramsARB(1, &prog)); + checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup"); + + return ret; +} + +/* Context activation is done by the caller. */ +static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + char data[4 * 4 * 4]; + GLuint tex, fbo; + GLenum status; + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE; + + memset(data, 0xcc, sizeof(data)); + + gl_info->gl_ops.gl.p_glGenTextures(1, &tex); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + checkGLcall("glTexImage2D"); + + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + checkGLcall("glFramebufferTexture2D"); + + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status); + checkGLcall("glCheckFramebufferStatus"); + + memset(data, 0x11, sizeof(data)); + gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glTexSubImage2D"); + + gl_info->gl_ops.gl.p_glClearColor(0.996f, 0.729f, 0.745f, 0.792f); + gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); + checkGLcall("glClear"); + + gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glGetTexImage"); + + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); + checkGLcall("glBindTexture"); + + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); + checkGLcall("glDeleteTextures"); + + return *(DWORD *)data == 0x11111111; +} + +/* Context activation is done by the caller. */ +static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + /* GL_RGBA16 uses GL_RGBA8 internally on Geforce 7 and older cards. + * This leads to graphical bugs in Half Life 2 and Unreal engine games. */ + GLuint tex; + GLint size; + + gl_info->gl_ops.gl.p_glGenTextures(1, &tex); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL); + checkGLcall("glTexImage2D"); + + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &size); + checkGLcall("glGetTexLevelParameteriv"); + TRACE("Real color depth is %d\n", size); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); + checkGLcall("glBindTexture"); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); + checkGLcall("glDeleteTextures"); + + return size < 16; +} + +static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + return gl_vendor == GL_VENDOR_FGLRX; +} + +static BOOL match_r200(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + if (card_vendor != HW_VENDOR_AMD) return FALSE; + if (device == CARD_AMD_RADEON_8500) return TRUE; + return FALSE; +} + +static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + DWORD data[4]; + GLuint tex, fbo; + GLenum status; + float color[4] = {0.0f, 1.0f, 0.0f, 0.0f}; + GLuint prog; + GLint err_pos; + static const char program_code[] = + "!!ARBfp1.0\n" + "OPTION ARB_fog_linear;\n" + "MOV result.color, {1.0, 0.0, 0.0, 0.0};\n" + "END\n"; + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return FALSE; + if (!gl_info->supported[ARB_FRAGMENT_PROGRAM]) + return FALSE; + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + return FALSE; + + gl_info->gl_ops.gl.p_glGenTextures(1, &tex); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + checkGLcall("glTexImage2D"); + + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + checkGLcall("glFramebufferTexture2D"); + + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status); + checkGLcall("glCheckFramebufferStatus"); + + gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 1.0f, 0.0f); + gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); + checkGLcall("glClear"); + gl_info->gl_ops.gl.p_glViewport(0, 0, 4, 1); + checkGLcall("glViewport"); + + gl_info->gl_ops.gl.p_glEnable(GL_FOG); + gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, 0.5f); + gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, 0.5f); + gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR); + gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST); + gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, color); + checkGLcall("fog setup"); + + GL_EXTCALL(glGenProgramsARB(1, &prog)); + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog)); + GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(program_code), program_code)); + gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); + checkGLcall("Test fragment program setup"); + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err_pos); + if (err_pos != -1) + { + const char *error_str; + error_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB); + FIXME("Fog test program error at position %d: %s\n\n", err_pos, debugstr_a(error_str)); + } + + gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); + gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f); + gl_info->gl_ops.gl.p_glVertex3f( 1.0f, -1.0f, 1.0f); + gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f); + gl_info->gl_ops.gl.p_glVertex3f( 1.0f, 1.0f, 1.0f); + gl_info->gl_ops.gl.p_glEnd(); + checkGLcall("ARBfp fog test draw"); + + gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glGetTexImage"); + data[0] &= 0x00ffffff; + data[1] &= 0x00ffffff; + data[2] &= 0x00ffffff; + data[3] &= 0x00ffffff; + + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); + + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); + gl_info->gl_ops.gl.p_glDisable(GL_FOG); + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); + gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); + GL_EXTCALL(glDeleteProgramsARB(1, &prog)); + checkGLcall("ARBfp fog test teardown"); + + TRACE("Fog test data: %08x %08x %08x %08x\n", data[0], data[1], data[2], data[3]); + return data[0] != 0x00ff0000 || data[3] != 0x0000ff00; +} + +static BOOL match_broken_viewport_subpixel_bits(const struct wined3d_gl_info *gl_info, + struct wined3d_caps_gl_ctx *ctx, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + if (!gl_info->supported[ARB_VIEWPORT_ARRAY]) + return FALSE; + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return FALSE; + return !wined3d_caps_gl_ctx_test_viewport_subpixel_bits(ctx); +} + +static BOOL match_no_independent_bit_depths(const struct wined3d_gl_info *gl_info, + struct wined3d_caps_gl_ctx *ctx, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + GLuint tex[2], fbo; + GLenum status; + + /* ARB_framebuffer_object allows implementation-dependent internal format + * restrictions. The EXT extension explicitly calls out an error in the + * relevant case. */ + if (!gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) + return TRUE; + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return TRUE; + + gl_info->gl_ops.gl.p_glGenTextures(2, tex); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex[0]); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex[1]); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 4, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); + + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[0], 0); + gl_info->fbo_ops.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex[1], 0); + + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + + gl_info->fbo_ops.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + gl_info->gl_ops.gl.p_glDeleteTextures(2, tex); + checkGLcall("testing multiple framebuffer attachments with different bit depths"); + + return status != GL_FRAMEBUFFER_COMPLETE; +} + +static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info) +{ + /* MacOS needs uniforms for relative addressing offsets. This can + * accumulate to quite a few uniforms. Beyond that the general uniform + * isn't optimal, so reserve a number of uniforms. 12 vec4's should allow + * 48 different offsets or other helper immediate values. */ + TRACE("Reserving 12 GLSL constants for compiler private use.\n"); + gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12); +} + +static void quirk_amd_dx9(struct wined3d_gl_info *gl_info) +{ + /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and + * earlier cards, although these cards only support + * GL_ARB_texture_rectangle (D3DPTEXTURECAPS_NONPOW2CONDITIONAL). + * + * If real NP2 textures are used, the driver falls back to software. We + * could just disable the extension and use GL_ARB_texture_rectangle + * instead, but texture_rectangle is inconvenient due to the + * non-normalised texture coordinates. Thus set an internal extension + * flag, GL_WINE_normalized_texrect, which signals the code that it can + * use non-power-of-two textures as per GL_ARB_texture_non_power_of_two, + * but has to stick to the texture_rectangle limits. + * + * Fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it + * advertises OpenGL 2.0, which has this extension promoted to core. The + * extension loading code sets this extension supported due to that, so + * this code works on fglrx as well. */ + if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + { + TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n"); + gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE; + gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE; + } +} + +static void quirk_no_np2(struct wined3d_gl_info *gl_info) +{ + /* The NVIDIA GeForce FX series reports OpenGL 2.0 capabilities with the + * latest drivers versions, but doesn't explicitly advertise the + * ARB_tex_npot extension in the OpenGL extension string. This usually + * means that ARB_tex_npot is supported in hardware as long as the + * application is staying within the limits enforced by the + * ARB_texture_rectangle extension. This however is not true for the + * FX series, which instantly falls back to a slower software path as + * soon as ARB_tex_npot is used. We therefore completely remove + * ARB_tex_npot from the list of supported extensions. + * + * Note that WINE_normalized_texrect can't be used in this case because + * internally it uses ARB_tex_npot, triggering the software fallback. + * There is not much we can do here apart from disabling the + * software-emulated extension and re-enable ARB_tex_rect (which was + * previously disabled in wined3d_adapter_init_gl_caps). + * + * This fixup removes performance problems on both the FX 5900 and + * FX 5700 (e.g. for framebuffer post-processing effects in the game + * "Max Payne 2"). The behaviour can be verified through a simple test + * app attached in bugreport #14724. */ + TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n"); + gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE; + gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE; +} + +static void quirk_texcoord_w(struct wined3d_gl_info *gl_info) +{ + /* The Intel GPUs on macOS set the .w register of texcoords to 0.0 by + * default, which causes problems with fixed-function fragment processing. + * Ideally this flag should be detected with a test shader and OpenGL + * feedback mode, but some OpenGL implementations (macOS ATI at least, + * probably all macOS ones) do not like vertex shaders in feedback mode + * and return an error, even though it should be valid according to the + * spec. + * + * We don't want to enable this on all cards, as it adds an extra + * instruction per texcoord used. This makes the shader slower and eats + * instruction slots which should be available to the Direct3D + * application. + * + * ATI Radeon HD 2xxx cards on macOS have the issue. Instead of checking + * for the buggy cards, blacklist all Radeon cards on macOS and whitelist + * the good ones. That way we're prepared for the future. If this + * workaround is activated on cards that do not need it, it won't break + * things, just affect performance negatively. */ + TRACE("Enabling vertex texture coord fixes in vertex shaders.\n"); + gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W; +} + +static void quirk_clip_varying(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING; +} + +static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA; +} + +static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN; +} + +static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE; +} + +static void quirk_broken_rgba16(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_BROKEN_RGBA16; +} + +static void quirk_infolog_spam(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_INFO_LOG_SPAM; +} + +static void quirk_limited_tex_filtering(struct wined3d_gl_info *gl_info) +{ + /* NVIDIA GeForce 6xxx and 7xxx support accelerated VTF only on a few + * selected texture formats. They are apparently the only Direct3D 9 class + * GPUs supporting VTF. Also, Direct3D 9-era GPUs are somewhat limited + * with float texture filtering and blending. */ + gl_info->quirks |= WINED3D_QUIRK_LIMITED_TEX_FILTERING; +} + +static void quirk_r200_constants(struct wined3d_gl_info *gl_info) +{ + /* The Mesa r200 driver (and there is no other driver for this GPU Wine + * would run on) loads some fog parameters (start, end, exponent, but not + * the colour) into the program. + * + * Apparently the fog hardware is only able to handle linear fog with a + * range of 0.0;1.0, and it is the responsibility of the vertex pipeline + * to handle non-linear fog and linear fog with start and end other than + * 0.0 and 1.0. */ + TRACE("Reserving 1 ARB constant for compiler private use.\n"); + gl_info->reserved_arb_constants = max(gl_info->reserved_arb_constants, 1); +} + +static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG; +} + +static void quirk_broken_viewport_subpixel_bits(struct wined3d_gl_info *gl_info) +{ + if (gl_info->supported[ARB_CLIP_CONTROL]) + { + TRACE("Disabling ARB_clip_control.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } +} + +static void quirk_no_independent_bit_depths(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_NO_INDEPENDENT_BIT_DEPTHS; +} + +static const struct wined3d_gpu_description *query_gpu_description(const struct wined3d_gl_info *gl_info, + UINT64 *vram_bytes) +{ + const struct wined3d_gpu_description *gpu_description = NULL, *gpu_description_override; + enum wined3d_pci_vendor vendor = PCI_VENDOR_NONE; + enum wined3d_pci_device device = PCI_DEVICE_NONE; + GLuint value; + + if (gl_info->supported[WGL_WINE_QUERY_RENDERER]) + { + if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VENDOR_ID_WINE, &value))) + vendor = value; + if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_DEVICE_ID_WINE, &value))) + device = value; + if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VIDEO_MEMORY_WINE, &value))) + *vram_bytes = (UINT64)value * 1024 * 1024; + + TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes of video memory.\n", + vendor, device, wine_dbgstr_longlong(*vram_bytes)); + + gpu_description = wined3d_get_gpu_description(vendor, device); + } + else if (gl_info->supported[NVX_GPU_MEMORY_INFO]) + { + GLint vram_kb; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb); + + *vram_bytes = (UINT64)vram_kb * 1024; + TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n", + wine_dbgstr_longlong(*vram_bytes)); + + gpu_description = wined3d_get_gpu_description(vendor, device); + } + + if ((gpu_description_override = wined3d_get_user_override_gpu_description(vendor, device))) + gpu_description = gpu_description_override; + + return gpu_description; +} + +/* Context activation is done by the caller. */ +static void fixup_extensions(struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + unsigned int i; + + static const struct driver_quirk + { + BOOL (*match)(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device); + void (*apply)(struct wined3d_gl_info *gl_info); + const char *description; + } + quirk_table[] = + { + { + match_amd_r300_to_500, + quirk_amd_dx9, + "AMD normalised texrect quirk" + }, + { + match_apple, + quirk_apple_glsl_constants, + "Apple GLSL uniform override" + }, + { + match_geforce5, + quirk_no_np2, + "Geforce 5 NP2 disable" + }, + { + match_apple_intel, + quirk_texcoord_w, + "Init texcoord .w for Apple Intel GPU driver" + }, + { + match_apple_nonr500ati, + quirk_texcoord_w, + "Init texcoord .w for Apple ATI >= r600 GPU driver" + }, + { + match_dx10_capable, + quirk_clip_varying, + "Reserved varying for gl_ClipPos" + }, + { + /* GL_EXT_secondary_color does not allow 4 component secondary + * colours, but most OpenGL implementations accept it. Apple's + * is the only OpenGL implementation known to reject it. + * + * If we can pass 4-component specular colours, do it, because + * (a) we don't have to screw around with the data, and (b) the + * Direct3D fixed-function vertex pipeline passes specular alpha + * to the pixel shader if any is used. Otherwise the specular + * alpha is used to pass the fog coordinate, which we pass to + * OpenGL via GL_EXT_fog_coord. */ + match_allows_spec_alpha, + quirk_allows_specular_alpha, + "Allow specular alpha quirk" + }, + { + match_broken_nv_clip, + quirk_disable_nvvp_clip, + "Apple NV_vertex_program clip bug quirk" + }, + { + match_fbo_tex_update, + quirk_fbo_tex_update, + "FBO rebind for attachment updates" + }, + { + match_broken_rgba16, + quirk_broken_rgba16, + "True RGBA16 is not available" + }, + { + match_fglrx, + quirk_infolog_spam, + "Not printing GLSL infolog" + }, + { + match_not_dx10_capable, + quirk_limited_tex_filtering, + "Texture filtering, blending and VTF support is limited" + }, + { + match_r200, + quirk_r200_constants, + "r200 vertex shader constants" + }, + { + match_broken_arb_fog, + quirk_broken_arb_fog, + "ARBfp fogstart == fogend workaround" + }, + { + match_broken_viewport_subpixel_bits, + quirk_broken_viewport_subpixel_bits, + "NVIDIA viewport subpixel bits bug" + }, + { + match_no_independent_bit_depths, + quirk_no_independent_bit_depths, + "No support for MRT with independent bit depths" + }, + }; + + for (i = 0; i < ARRAY_SIZE(quirk_table); ++i) + { + if (!quirk_table[i].match(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device)) continue; + TRACE("Applying driver quirk \"%s\".\n", quirk_table[i].description); + quirk_table[i].apply(gl_info); + } + + /* Find out if PBOs work as they are supposed to. */ + test_pbo_functionality(gl_info); +} + +static DWORD wined3d_parse_gl_version(const char *gl_version) +{ + const char *ptr = gl_version; + int major, minor; + + major = atoi(ptr); + if (major <= 0) + ERR("Invalid OpenGL major version %d.\n", major); + + while (isdigit(*ptr)) ++ptr; + if (*ptr++ != '.') + ERR("Invalid OpenGL version string %s.\n", debugstr_a(gl_version)); + + minor = atoi(ptr); + + TRACE("Found OpenGL version %d.%d.\n", major, minor); + + return MAKEDWORD_VERSION(major, minor); +} + +static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info, + const char *gl_vendor_string, const char *gl_renderer, const char *gl_version) +{ + /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from + * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to + * detect the Apple OpenGL implementation to apply some extension fixups afterwards. + * + * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks + * aren't sufficient either because a Linux binary may display on a macos X server via remote X11. + * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions + * like client storage might be supported on other implementations too, but GL_APPLE_flush_render + * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So + * the chance that other implementations support them is rather small since Win32 QuickTime uses + * DirectDraw, not OpenGL. */ + if (gl_info->supported[APPLE_FENCE] && gl_info->supported[APPLE_YCBCR_422]) + return GL_VENDOR_APPLE; + + if (strstr(gl_vendor_string, "NVIDIA")) + return GL_VENDOR_NVIDIA; + + if (strstr(gl_vendor_string, "ATI")) + return GL_VENDOR_FGLRX; + + if (strstr(gl_vendor_string, "Mesa") + || strstr(gl_vendor_string, "Brian Paul") + || strstr(gl_vendor_string, "X.Org") + || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.") + || strstr(gl_vendor_string, "DRI R300 Project") + || strstr(gl_vendor_string, "Tungsten Graphics, Inc") + || strstr(gl_vendor_string, "VMware, Inc.") + || strstr(gl_vendor_string, "Red Hat") + || strstr(gl_vendor_string, "Intel") + || strstr(gl_renderer, "Mesa") + || strstr(gl_renderer, "Gallium") + || strstr(gl_renderer, "Intel") + || strstr(gl_version, "Mesa")) + return GL_VENDOR_MESA; + + FIXME("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n", + debugstr_a(gl_vendor_string)); + + return GL_VENDOR_UNKNOWN; +} + +static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer) +{ + if (strstr(gl_vendor_string, "NVIDIA") + || strstr(gl_vendor_string, "Nouveau") + || strstr(gl_vendor_string, "nouveau")) + return HW_VENDOR_NVIDIA; + + if (strstr(gl_vendor_string, "ATI") + || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.") + || strstr(gl_vendor_string, "X.Org R300 Project") + || strstr(gl_renderer, "AMD") + || strstr(gl_renderer, "FirePro") + || strstr(gl_renderer, "Radeon") + || strstr(gl_renderer, "R100") + || strstr(gl_renderer, "R200") + || strstr(gl_renderer, "R300") + || strstr(gl_renderer, "R600") + || strstr(gl_renderer, "R700")) + return HW_VENDOR_AMD; + + if (strstr(gl_vendor_string, "Intel(R)") + /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */ + || strstr(gl_renderer, "Intel") + || strstr(gl_renderer, "i915") + || strstr(gl_vendor_string, "Intel Inc.")) + return HW_VENDOR_INTEL; + + if (strstr(gl_vendor_string, "Red Hat") + || strstr(gl_renderer, "virgl")) + return HW_VENDOR_REDHAT; + + if (strstr(gl_renderer, "SVGA3D")) + return HW_VENDOR_VMWARE; + + if (strstr(gl_vendor_string, "Mesa") + || strstr(gl_vendor_string, "Brian Paul") + || strstr(gl_vendor_string, "Tungsten Graphics, Inc") + || strstr(gl_vendor_string, "VMware, Inc.")) + return HW_VENDOR_SOFTWARE; + + FIXME("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string)); + + return HW_VENDOR_NVIDIA; +} + +static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_gl_info *gl_info, + const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps) +{ + unsigned int shader_model; + + shader_model = min(shader_caps->vs_version, shader_caps->ps_version); + shader_model = min(shader_model, max(shader_caps->gs_version, 3)); + shader_model = min(shader_model, max(shader_caps->hs_version, 4)); + shader_model = min(shader_model, max(shader_caps->ds_version, 4)); + + if (gl_info->supported[WINED3D_GL_VERSION_3_2] + && gl_info->supported[ARB_POLYGON_OFFSET_CLAMP] + && gl_info->supported[ARB_SAMPLER_OBJECTS]) + { + if (shader_model >= 5 + && gl_info->supported[ARB_DRAW_INDIRECT] + && gl_info->supported[ARB_TEXTURE_COMPRESSION_BPTC]) + return WINED3D_FEATURE_LEVEL_11_1; + + if (shader_model >= 4) + { + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY]) + return WINED3D_FEATURE_LEVEL_10_1; + return WINED3D_FEATURE_LEVEL_10; + } + } + + if (shader_model >= 3 && gl_info->limits.texture_size >= 4096 && gl_info->limits.buffers >= 4) + return WINED3D_FEATURE_LEVEL_9_3; + if (shader_model >= 2) + { + if (gl_info->supported[ARB_OCCLUSION_QUERY] + && gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] + && gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] + && gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) + return WINED3D_FEATURE_LEVEL_9_2; + + return WINED3D_FEATURE_LEVEL_9_1; + } + if (shader_model >= 1) + return WINED3D_FEATURE_LEVEL_8; + + if (fragment_caps->TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3) + return WINED3D_FEATURE_LEVEL_7; + if (fragment_caps->MaxSimultaneousTextures > 1) + return WINED3D_FEATURE_LEVEL_6; + + return WINED3D_FEATURE_LEVEL_5; +} + +static const struct wined3d_renderer_table +{ + const char *renderer; + enum wined3d_pci_device id; +} +cards_nvidia_binary[] = +{ + /* Direct 3D 11 */ + {"RTX 2080 Ti", CARD_NVIDIA_GEFORCE_RTX2080TI}, /* GeForce 2000 - highend */ + {"RTX 2080", CARD_NVIDIA_GEFORCE_RTX2080}, /* GeForce 2000 - highend */ + {"RTX 2070", CARD_NVIDIA_GEFORCE_RTX2070}, /* GeForce 2000 - highend */ + {"RTX 2060", CARD_NVIDIA_GEFORCE_RTX2060}, /* GeForce 2000 - highend */ + {"GTX 1660 Ti", CARD_NVIDIA_GEFORCE_GTX1660TI}, /* GeForce 1600 - highend */ + {"TITAN V", CARD_NVIDIA_TITANV}, /* GeForce 1000 - highend */ + {"TITAN X (Pascal)", CARD_NVIDIA_TITANX_PASCAL}, /* GeForce 1000 - highend */ + {"GTX 1080 Ti", CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */ + {"GTX 1080", CARD_NVIDIA_GEFORCE_GTX1080}, /* GeForce 1000 - highend */ + {"GTX 1070", CARD_NVIDIA_GEFORCE_GTX1070}, /* GeForce 1000 - highend */ + {"GTX 1060", CARD_NVIDIA_GEFORCE_GTX1060}, /* GeForce 1000 - midend high */ + {"GTX 1050 Ti", CARD_NVIDIA_GEFORCE_GTX1050TI}, /* GeForce 1000 - midend */ + {"GTX 1050", CARD_NVIDIA_GEFORCE_GTX1050}, /* GeForce 1000 - midend */ + {"GTX 980 Ti", CARD_NVIDIA_GEFORCE_GTX980TI}, /* GeForce 900 - highend */ + {"GTX 980", CARD_NVIDIA_GEFORCE_GTX980}, /* GeForce 900 - highend */ + {"GTX 970M", CARD_NVIDIA_GEFORCE_GTX970M}, /* GeForce 900 - highend mobile*/ + {"GTX 970", CARD_NVIDIA_GEFORCE_GTX970}, /* GeForce 900 - highend */ + {"GTX TITAN X", CARD_NVIDIA_GEFORCE_GTXTITANX}, /* Geforce 900 - highend */ + {"GTX 960M", CARD_NVIDIA_GEFORCE_GTX960M}, /* GeForce 900 - midend high mobile */ + {"GTX 960", CARD_NVIDIA_GEFORCE_GTX960}, /* GeForce 900 - midend high */ + {"GTX 950M", CARD_NVIDIA_GEFORCE_GTX950M}, /* GeForce 900 - midend mobile */ + {"GTX 950", CARD_NVIDIA_GEFORCE_GTX950}, /* GeForce 900 - midend */ + {"GeForce 940M", CARD_NVIDIA_GEFORCE_940M}, /* GeForce 900 - midend mobile */ + {"GTX 880M", CARD_NVIDIA_GEFORCE_GTX880M}, /* GeForce 800 - mobile */ + {"GTX 870M", CARD_NVIDIA_GEFORCE_GTX870M}, /* GeForce 800 - mobile */ + {"GTX 860M", CARD_NVIDIA_GEFORCE_GTX860M}, /* GeForce 800 - mobile */ + {"GTX 850M", CARD_NVIDIA_GEFORCE_GTX850M}, /* GeForce 800 - mobile */ + {"GeForce 845M", CARD_NVIDIA_GEFORCE_845M}, /* GeForce 800 - mobile */ + {"GeForce 840M", CARD_NVIDIA_GEFORCE_840M}, /* GeForce 800 - mobile */ + {"GeForce 830M", CARD_NVIDIA_GEFORCE_830M}, /* GeForce 800 - mobile */ + {"GeForce 820M", CARD_NVIDIA_GEFORCE_820M}, /* GeForce 800 - mobile */ + {"GTX 780 Ti", CARD_NVIDIA_GEFORCE_GTX780TI}, /* Geforce 700 - highend */ + {"GTX TITAN Black", CARD_NVIDIA_GEFORCE_GTXTITANB}, /* Geforce 700 - highend */ + {"GTX TITAN Z", CARD_NVIDIA_GEFORCE_GTXTITANZ}, /* Geforce 700 - highend */ + {"GTX TITAN", CARD_NVIDIA_GEFORCE_GTXTITAN}, /* Geforce 700 - highend */ + {"GTX 780", CARD_NVIDIA_GEFORCE_GTX780}, /* Geforce 700 - highend */ + {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */ + {"GTX 770", CARD_NVIDIA_GEFORCE_GTX770}, /* Geforce 700 - highend */ + {"GTX 765M", CARD_NVIDIA_GEFORCE_GTX765M}, /* Geforce 700 - midend high mobile */ + {"GTX 760 Ti", CARD_NVIDIA_GEFORCE_GTX760TI}, /* Geforce 700 - midend high */ + {"GTX 760", CARD_NVIDIA_GEFORCE_GTX760}, /* Geforce 700 - midend high */ + {"GTX 750 Ti", CARD_NVIDIA_GEFORCE_GTX750TI}, /* Geforce 700 - midend */ + {"GTX 750", CARD_NVIDIA_GEFORCE_GTX750}, /* Geforce 700 - midend */ + {"GT 750M", CARD_NVIDIA_GEFORCE_GT750M}, /* Geforce 700 - midend mobile */ + {"GT 740M", CARD_NVIDIA_GEFORCE_GT740M}, /* Geforce 700 - midend mobile */ + {"GT 730M", CARD_NVIDIA_GEFORCE_GT730M}, /* Geforce 700 - midend mobile */ + {"GT 730", CARD_NVIDIA_GEFORCE_GT730}, /* Geforce 700 - lowend */ + {"GTX 690", CARD_NVIDIA_GEFORCE_GTX690}, /* Geforce 600 - highend */ + {"GTX 680", CARD_NVIDIA_GEFORCE_GTX680}, /* Geforce 600 - highend */ + {"GTX 675MX", CARD_NVIDIA_GEFORCE_GTX675MX_1},/* Geforce 600 - highend */ + {"GTX 670MX", CARD_NVIDIA_GEFORCE_GTX670MX}, /* Geforce 600 - highend */ + {"GTX 670", CARD_NVIDIA_GEFORCE_GTX670}, /* Geforce 600 - midend high */ + {"GTX 660 Ti", CARD_NVIDIA_GEFORCE_GTX660TI}, /* Geforce 600 - midend high */ + {"GTX 660M", CARD_NVIDIA_GEFORCE_GTX660M}, /* Geforce 600 - midend high mobile */ + {"GTX 660", CARD_NVIDIA_GEFORCE_GTX660}, /* Geforce 600 - midend high */ + {"GTX 650 Ti", CARD_NVIDIA_GEFORCE_GTX650TI}, /* Geforce 600 - lowend */ + {"GTX 650", CARD_NVIDIA_GEFORCE_GTX650}, /* Geforce 600 - lowend */ + {"GT 650M", CARD_NVIDIA_GEFORCE_GT650M}, /* Geforce 600 - midend mobile */ + {"GT 640M", CARD_NVIDIA_GEFORCE_GT640M}, /* Geforce 600 - midend mobile */ + {"GT 630M", CARD_NVIDIA_GEFORCE_GT630M}, /* Geforce 600 - midend mobile */ + {"GT 630", CARD_NVIDIA_GEFORCE_GT630}, /* Geforce 600 - lowend */ + {"GT 610", CARD_NVIDIA_GEFORCE_GT610}, /* Geforce 600 - lowend */ + {"GTX 580", CARD_NVIDIA_GEFORCE_GTX580}, /* Geforce 500 - highend */ + {"GTX 570", CARD_NVIDIA_GEFORCE_GTX570}, /* Geforce 500 - midend high */ + {"GTX 560 Ti", CARD_NVIDIA_GEFORCE_GTX560TI}, /* Geforce 500 - midend */ + {"GTX 560M", CARD_NVIDIA_GEFORCE_GTX560M}, /* Geforce 500 - midend mobile */ + {"GTX 560", CARD_NVIDIA_GEFORCE_GTX560}, /* Geforce 500 - midend */ + {"GT 555M", CARD_NVIDIA_GEFORCE_GT555M}, /* Geforce 500 - midend mobile */ + {"GTX 550 Ti", CARD_NVIDIA_GEFORCE_GTX550}, /* Geforce 500 - midend */ + {"GT 540M", CARD_NVIDIA_GEFORCE_GT540M}, /* Geforce 500 - midend mobile */ + {"GT 525M", CARD_NVIDIA_GEFORCE_GT525M}, /* Geforce 500 - lowend mobile */ + {"GT 520", CARD_NVIDIA_GEFORCE_GT520}, /* Geforce 500 - lowend */ + {"GTX 480", CARD_NVIDIA_GEFORCE_GTX480}, /* Geforce 400 - highend */ + {"GTX 470", CARD_NVIDIA_GEFORCE_GTX470}, /* Geforce 400 - midend high */ + /* Direct 3D 10 */ + {"GTX 465", CARD_NVIDIA_GEFORCE_GTX465}, /* Geforce 400 - midend */ + {"GTX 460M", CARD_NVIDIA_GEFORCE_GTX460M}, /* Geforce 400 - highend mobile */ + {"GTX 460", CARD_NVIDIA_GEFORCE_GTX460}, /* Geforce 400 - midend */ + {"GTS 450", CARD_NVIDIA_GEFORCE_GTS450}, /* Geforce 400 - midend low */ + {"GT 440", CARD_NVIDIA_GEFORCE_GT440}, /* Geforce 400 - lowend */ + {"GT 430", CARD_NVIDIA_GEFORCE_GT430}, /* Geforce 400 - lowend */ + {"GT 425M", CARD_NVIDIA_GEFORCE_GT425M}, /* Geforce 400 - lowend mobile */ + {"GT 420", CARD_NVIDIA_GEFORCE_GT420}, /* Geforce 400 - lowend */ + {"410M", CARD_NVIDIA_GEFORCE_410M}, /* Geforce 400 - lowend mobile */ + {"GT 330", CARD_NVIDIA_GEFORCE_GT330}, /* Geforce 300 - highend */ + {"GTS 360M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */ + {"GTS 350M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */ + {"GT 330M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */ + {"GT 325M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */ + {"GT 320M", CARD_NVIDIA_GEFORCE_GT320M}, /* Geforce 300 - midend mobile */ + {"320M", CARD_NVIDIA_GEFORCE_320M}, /* Geforce 300 - midend mobile */ + {"315M", CARD_NVIDIA_GEFORCE_315M}, /* Geforce 300 - midend mobile */ + {"GTX 295", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ + {"GTX 285", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ + {"GTX 280", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ + {"GTX 275", CARD_NVIDIA_GEFORCE_GTX275}, /* Geforce 200 - midend high */ + {"GTX 260", CARD_NVIDIA_GEFORCE_GTX260}, /* Geforce 200 - midend */ + {"GTS 250", CARD_NVIDIA_GEFORCE_GTS250}, /* Geforce 200 - midend */ + {"GT 240", CARD_NVIDIA_GEFORCE_GT240}, /* Geforce 200 - midend */ + {"GT 220", CARD_NVIDIA_GEFORCE_GT220}, /* Geforce 200 - lowend */ + {"GeForce 310", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ + {"GeForce 305", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ + {"GeForce 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ + {"G 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ + {"GTS 150", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ + {"9800", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ + {"9700M GT", CARD_NVIDIA_GEFORCE_9700MGT}, /* Geforce 9 - midend */ + {"GT 140", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */ + {"9600", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */ + {"GT 130", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ + {"GT 120", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ + {"9500", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ + {"9400M", CARD_NVIDIA_GEFORCE_9400M}, /* Geforce 9 - lowend */ + {"9400", CARD_NVIDIA_GEFORCE_9400GT}, /* Geforce 9 - lowend */ + {"9300", CARD_NVIDIA_GEFORCE_9300}, /* Geforce 9 - lowend low */ + {"9200", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */ + {"9100", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */ + {"G 100", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */ + {"8800 GTX", CARD_NVIDIA_GEFORCE_8800GTX}, /* Geforce 8 - highend high */ + {"8800", CARD_NVIDIA_GEFORCE_8800GTS}, /* Geforce 8 - highend */ + {"8600M", CARD_NVIDIA_GEFORCE_8600MGT}, /* Geforce 8 - midend mobile */ + {"8600 M", CARD_NVIDIA_GEFORCE_8600MGT}, /* Geforce 8 - midend mobile */ + {"8700", CARD_NVIDIA_GEFORCE_8600GT}, /* Geforce 8 - midend */ + {"8600", CARD_NVIDIA_GEFORCE_8600GT}, /* Geforce 8 - midend */ + {"8500", CARD_NVIDIA_GEFORCE_8500GT}, /* Geforce 8 - mid-lowend */ + {"8400", CARD_NVIDIA_GEFORCE_8400GS}, /* Geforce 8 - mid-lowend */ + {"8300", CARD_NVIDIA_GEFORCE_8300GS}, /* Geforce 8 - lowend */ + {"8200", CARD_NVIDIA_GEFORCE_8200}, /* Geforce 8 - lowend */ + {"8100", CARD_NVIDIA_GEFORCE_8200}, /* Geforce 8 - lowend */ + /* Direct 3D 9 SM3 */ + {"Quadro FX 5", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ + {"Quadro FX 4", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ + {"7950", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ + {"7900", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ + {"7800", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ + {"7700", CARD_NVIDIA_GEFORCE_7600}, /* Geforce 7 - midend */ + {"7600", CARD_NVIDIA_GEFORCE_7600}, /* Geforce 7 - midend */ + {"7400", CARD_NVIDIA_GEFORCE_7400}, /* Geforce 7 - lower medium */ + {"7300", CARD_NVIDIA_GEFORCE_7300}, /* Geforce 7 - lowend */ + {"6800", CARD_NVIDIA_GEFORCE_6800}, /* Geforce 6 - highend */ + {"6700", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */ + {"6610", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */ + {"6600", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */ + /* Direct 3D 9 SM2 */ + {"Quadro FX", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ + {"5950", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ + {"5900", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ + {"5800", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ + {"5750", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ + {"5700", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ + {"5650", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ + {"5600", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ + {"5500", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ + {"5300", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ + {"5250", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ + {"5200", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ + {"5100", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ + /* Direct 3D 8 */ + {"Quadro4", CARD_NVIDIA_GEFORCE4_TI4200}, + {"GeForce4 Ti", CARD_NVIDIA_GEFORCE4_TI4200}, /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800 */ + /* Direct 3D 7 */ + {"GeForce4 MX", CARD_NVIDIA_GEFORCE4_MX}, /* MX420/MX440/MX460/MX4000 */ + {"Quadro2 MXR", CARD_NVIDIA_GEFORCE2_MX}, + {"GeForce2 MX", CARD_NVIDIA_GEFORCE2_MX}, /* Geforce2 standard/MX100/MX200/MX400 */ + {"Quadro2", CARD_NVIDIA_GEFORCE2}, + {"GeForce2", CARD_NVIDIA_GEFORCE2}, /* Geforce2 GTS/Pro/Ti/Ultra */ + /* Direct 3D 6 */ + {"TNT2", CARD_NVIDIA_RIVA_TNT2}, /* Riva TNT2 standard/M64/Pro/Ultra */ +}, +/* See http://developer.amd.com/resources/hardware-drivers/ati-catalyst-pc-vendor-id-1002-li/ + * + * Beware: renderer string do not match exact card model, + * e.g. HD 4800 is returned for multiple cards, even for RV790 based ones. */ +cards_amd_binary[] = +{ + {"RX 480", CARD_AMD_RADEON_RX_480}, + {"RX 460", CARD_AMD_RADEON_RX_460}, + {"R9 Fury Series", CARD_AMD_RADEON_R9_FURY}, + /* Southern Islands */ + {"HD 7900", CARD_AMD_RADEON_HD7900}, + {"HD 7800", CARD_AMD_RADEON_HD7800}, + {"HD 7700", CARD_AMD_RADEON_HD7700}, + /* Northern Islands */ + {"HD 6970", CARD_AMD_RADEON_HD6900}, + {"HD 6900", CARD_AMD_RADEON_HD6900}, + {"HD 6800", CARD_AMD_RADEON_HD6800}, + {"HD 6770M", CARD_AMD_RADEON_HD6600M}, + {"HD 6750M", CARD_AMD_RADEON_HD6600M}, + {"HD 6700", CARD_AMD_RADEON_HD6700}, + {"HD 6670", CARD_AMD_RADEON_HD6600}, + {"HD 6630M", CARD_AMD_RADEON_HD6600M}, + {"HD 6600M", CARD_AMD_RADEON_HD6600M}, + {"HD 6600", CARD_AMD_RADEON_HD6600}, + {"HD 6570", CARD_AMD_RADEON_HD6600}, + {"HD 6500M", CARD_AMD_RADEON_HD6600M}, + {"HD 6500", CARD_AMD_RADEON_HD6600}, + {"HD 6480G", CARD_AMD_RADEON_HD6480G}, + {"HD 6400", CARD_AMD_RADEON_HD6400}, + {"HD 6300", CARD_AMD_RADEON_HD6300}, + {"HD 6200", CARD_AMD_RADEON_HD6300}, + /* Evergreen */ + {"HD 5870", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS PRO */ + {"HD 5850", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS XT */ + {"HD 5800", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS HD58xx generic renderer string */ + {"HD 5770", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER XT */ + {"HD 5750", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER LE */ + {"HD 5700", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER HD57xx generic renderer string */ + {"HD 5670", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD XT */ + {"HD 5570", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD PRO mapped to HD5600 series */ + {"HD 5550", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD LE mapped to HD5600 series */ + {"HD 5450", CARD_AMD_RADEON_HD5400}, /* Radeon EG CEDAR PRO */ + {"HD 5000", CARD_AMD_RADEON_HD5600}, /* Defaulting to HD 5600 */ + /* R700 */ + {"HD 4890", CARD_AMD_RADEON_HD4800}, /* Radeon RV790 */ + {"HD 4870", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */ + {"HD 4850", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */ + {"HD 4830", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */ + {"HD 4800", CARD_AMD_RADEON_HD4800}, /* Radeon RV7xx HD48xx generic renderer string */ + {"HD 4770", CARD_AMD_RADEON_HD4700}, /* Radeon RV740 */ + {"HD 4700", CARD_AMD_RADEON_HD4700}, /* Radeon RV7xx HD47xx generic renderer string */ + {"HD 4670", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */ + {"HD 4650", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */ + {"HD 4600", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */ + {"HD 4550", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */ + {"HD 4350", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */ + /* R600/R700 integrated */ + {"HD 4200M", CARD_AMD_RADEON_HD4200M}, + {"HD 3300", CARD_AMD_RADEON_HD3200}, + {"HD 3200", CARD_AMD_RADEON_HD3200}, + {"HD 3100", CARD_AMD_RADEON_HD3200}, + /* R600 */ + {"HD 3870", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */ + {"HD 3850", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */ + {"HD 2900", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */ + {"HD 3830", CARD_AMD_RADEON_HD2600}, /* China-only midend */ + {"HD 3690", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */ + {"HD 3650", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */ + {"HD 2600", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */ + {"HD 3470", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ + {"HD 3450", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ + {"HD 3430", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ + {"HD 3400", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ + {"HD 2400", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ + {"HD 2350", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ + /* Radeon R5xx */ + {"X1950", CARD_AMD_RADEON_X1600}, + {"X1900", CARD_AMD_RADEON_X1600}, + {"X1800", CARD_AMD_RADEON_X1600}, + {"X1650", CARD_AMD_RADEON_X1600}, + {"X1600", CARD_AMD_RADEON_X1600}, + /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx) + * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */ + {"HD 2300", CARD_AMD_RADEON_X700}, + {"X2500", CARD_AMD_RADEON_X700}, + {"X2300", CARD_AMD_RADEON_X700}, + {"X1550", CARD_AMD_RADEON_X700}, + {"X1450", CARD_AMD_RADEON_X700}, + {"X1400", CARD_AMD_RADEON_X700}, + {"X1300", CARD_AMD_RADEON_X700}, + {"X850", CARD_AMD_RADEON_X700}, + {"X800", CARD_AMD_RADEON_X700}, + {"X700", CARD_AMD_RADEON_X700}, + /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400 MHz */ + {"Radeon Xpress", CARD_AMD_RADEON_XPRESS_200M}, +}, +cards_intel[] = +{ + /* Skylake */ + {"Iris Pro Graphics P580", CARD_INTEL_IPP580_1}, + {"Skylake", CARD_INTEL_HD520_1}, + /* Broadwell */ + {"Iris Pro P6300", CARD_INTEL_IPP6300}, + {"Iris Pro 6200", CARD_INTEL_IP6200}, + {"Iris 6100", CARD_INTEL_I6100}, + {"Iris(TM) Graphics 6100", CARD_INTEL_I6100}, /* MacOS */ + /* Haswell */ + {"Iris Pro 5200", CARD_INTEL_IP5200_1}, + {"Iris 5100", CARD_INTEL_I5100_1}, + {"HD Graphics 5000", CARD_INTEL_HD5000_1}, /* MacOS */ + {"Haswell Mobile", CARD_INTEL_HWM}, + {"Iris OpenGL Engine", CARD_INTEL_HWM}, /* MacOS */ + /* Ivybridge */ + {"Ivybridge Server", CARD_INTEL_IVBS}, + {"Ivybridge Mobile", CARD_INTEL_IVBM}, + {"Ivybridge Desktop", CARD_INTEL_IVBD}, + {"HD Graphics 4000", CARD_INTEL_IVBD}, /* MacOS */ + /* Sandybridge */ + {"Sandybridge Server", CARD_INTEL_SNBS}, + {"Sandybridge Mobile", CARD_INTEL_SNBM}, + {"Sandybridge Desktop", CARD_INTEL_SNBD}, + /* Ironlake */ + {"Ironlake Mobile", CARD_INTEL_ILKM}, + {"Ironlake Desktop", CARD_INTEL_ILKD}, + /* G4x */ + {"B43", CARD_INTEL_B43}, + {"G41", CARD_INTEL_G41}, + {"G45", CARD_INTEL_G45}, + {"Q45", CARD_INTEL_Q45}, + {"Integrated Graphics Device", CARD_INTEL_IGD}, + {"GM45", CARD_INTEL_GM45}, + /* i965 */ + {"965GME", CARD_INTEL_965GME}, + {"965GM", CARD_INTEL_965GM}, + {"X3100", CARD_INTEL_965GM}, /* MacOS */ + {"946GZ", CARD_INTEL_946GZ}, + {"965G", CARD_INTEL_965G}, + {"965Q", CARD_INTEL_965Q}, + /* i945 */ + {"Pineview M", CARD_INTEL_PNVM}, + {"Pineview G", CARD_INTEL_PNVG}, + {"IGD", CARD_INTEL_PNVG}, + {"Q33", CARD_INTEL_Q33}, + {"G33", CARD_INTEL_G33}, + {"Q35", CARD_INTEL_Q35}, + {"945GME", CARD_INTEL_945GME}, + {"945GM", CARD_INTEL_945GM}, + {"GMA 950", CARD_INTEL_945GM}, /* MacOS */ + {"945G", CARD_INTEL_945G}, + /* i915 */ + {"915GM", CARD_INTEL_915GM}, + {"E7221G", CARD_INTEL_E7221G}, + {"915G", CARD_INTEL_915G}, + /* i8xx */ + {"865G", CARD_INTEL_865G}, + {"845G", CARD_INTEL_845G}, + {"855GM", CARD_INTEL_855GM}, + {"830M", CARD_INTEL_830M}, +}, +/* 20101109 - These are never returned by current Gallium radeon + * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. */ +cards_amd_mesa[] = +{ + /* Polaris 10/11 */ + {"POLARIS10", CARD_AMD_RADEON_RX_480}, + {"POLARIS11", CARD_AMD_RADEON_RX_460}, + /* Volcanic Islands */ + {"FIJI", CARD_AMD_RADEON_R9_FURY}, + {"TONGA", CARD_AMD_RADEON_R9_285}, + /* Sea Islands */ + {"HAWAII", CARD_AMD_RADEON_R9_290}, + {"KAVERI", CARD_AMD_RADEON_R7 }, + {"KABINI", CARD_AMD_RADEON_R3 }, + {"BONAIRE", CARD_AMD_RADEON_HD8770}, + /* Southern Islands */ + {"OLAND", CARD_AMD_RADEON_HD8670}, + {"HAINAN", CARD_AMD_RADEON_HD8600M}, + {"TAHITI", CARD_AMD_RADEON_HD7900}, + {"PITCAIRN", CARD_AMD_RADEON_HD7800}, + {"CAPE VERDE", CARD_AMD_RADEON_HD7700}, + /* Northern Islands */ + {"ARUBA", CARD_AMD_RADEON_HD7660D}, + {"CAYMAN", CARD_AMD_RADEON_HD6900}, + {"BARTS", CARD_AMD_RADEON_HD6800}, + {"TURKS", CARD_AMD_RADEON_HD6600}, + {"SUMO2", CARD_AMD_RADEON_HD6410D}, /* SUMO2 first, because we do a strstr(). */ + {"SUMO", CARD_AMD_RADEON_HD6550D}, + {"CAICOS", CARD_AMD_RADEON_HD6400}, + {"PALM", CARD_AMD_RADEON_HD6300}, + /* Evergreen */ + {"HEMLOCK", CARD_AMD_RADEON_HD5900}, + {"CYPRESS", CARD_AMD_RADEON_HD5800}, + {"JUNIPER", CARD_AMD_RADEON_HD5700}, + {"REDWOOD", CARD_AMD_RADEON_HD5600}, + {"CEDAR", CARD_AMD_RADEON_HD5400}, + /* R700 */ + {"R700", CARD_AMD_RADEON_HD4800}, + {"RV790", CARD_AMD_RADEON_HD4800}, + {"RV770", CARD_AMD_RADEON_HD4800}, + {"RV740", CARD_AMD_RADEON_HD4700}, + {"RV730", CARD_AMD_RADEON_HD4600}, + {"RV710", CARD_AMD_RADEON_HD4350}, + /* R600/R700 integrated */ + {"RS880", CARD_AMD_RADEON_HD4200M}, + {"RS780", CARD_AMD_RADEON_HD3200}, + /* R600 */ + {"R680", CARD_AMD_RADEON_HD2900}, + {"R600", CARD_AMD_RADEON_HD2900}, + {"RV670", CARD_AMD_RADEON_HD3850}, + {"RV635", CARD_AMD_RADEON_HD2600}, + {"RV630", CARD_AMD_RADEON_HD2600}, + {"RV620", CARD_AMD_RADEON_HD2350}, + {"RV610", CARD_AMD_RADEON_HD2350}, + /* R500 */ + {"R580", CARD_AMD_RADEON_X1600}, + {"R520", CARD_AMD_RADEON_X1600}, + {"RV570", CARD_AMD_RADEON_X1600}, + {"RV560", CARD_AMD_RADEON_X1600}, + {"RV535", CARD_AMD_RADEON_X1600}, + {"RV530", CARD_AMD_RADEON_X1600}, + {"RV516", CARD_AMD_RADEON_X700}, + {"RV515", CARD_AMD_RADEON_X700}, + /* R400 */ + {"R481", CARD_AMD_RADEON_X700}, + {"R480", CARD_AMD_RADEON_X700}, + {"R430", CARD_AMD_RADEON_X700}, + {"R423", CARD_AMD_RADEON_X700}, + {"R420", CARD_AMD_RADEON_X700}, + {"R410", CARD_AMD_RADEON_X700}, + {"RV410", CARD_AMD_RADEON_X700}, + /* Radeon Xpress - onboard, DX9b, Shader 2.0, 300-400 MHz */ + {"RS740", CARD_AMD_RADEON_XPRESS_200M}, + {"RS690", CARD_AMD_RADEON_XPRESS_200M}, + {"RS600", CARD_AMD_RADEON_XPRESS_200M}, + {"RS485", CARD_AMD_RADEON_XPRESS_200M}, + {"RS482", CARD_AMD_RADEON_XPRESS_200M}, + {"RS480", CARD_AMD_RADEON_XPRESS_200M}, + {"RS400", CARD_AMD_RADEON_XPRESS_200M}, + {"RC410", CARD_AMD_RADEON_XPRESS_200M}, + /* R300 */ + {"R360", CARD_AMD_RADEON_9500}, + {"R350", CARD_AMD_RADEON_9500}, + {"R300", CARD_AMD_RADEON_9500}, + {"RV380", CARD_AMD_RADEON_9500}, + {"RV370", CARD_AMD_RADEON_9500}, + {"RV360", CARD_AMD_RADEON_9500}, + {"RV351", CARD_AMD_RADEON_9500}, + {"RV350", CARD_AMD_RADEON_9500}, +}, +cards_nvidia_mesa[] = +{ + /* Maxwell */ + {"NV124", CARD_NVIDIA_GEFORCE_GTX970}, + {"NV120", CARD_NVIDIA_GEFORCE_GTX980TI}, + {"NV118", CARD_NVIDIA_GEFORCE_840M}, + {"NV117", CARD_NVIDIA_GEFORCE_GTX750}, + /* Kepler */ + {"NV108", CARD_NVIDIA_GEFORCE_GT740M}, + {"NV106", CARD_NVIDIA_GEFORCE_GT720}, + {"NVF1", CARD_NVIDIA_GEFORCE_GTX780TI}, + {"NVF0", CARD_NVIDIA_GEFORCE_GTX780}, + {"NVE6", CARD_NVIDIA_GEFORCE_GTX770M}, + {"NVE4", CARD_NVIDIA_GEFORCE_GTX680}, /* 690 / 675MX / 760TI */ + /* Fermi */ + {"NVD9", CARD_NVIDIA_GEFORCE_GT520}, + {"NVD7", CARD_NVIDIA_GEFORCE_820M}, + {"NVCF", CARD_NVIDIA_GEFORCE_GTX550}, + {"NVCE", CARD_NVIDIA_GEFORCE_GTX560}, + {"NVC8", CARD_NVIDIA_GEFORCE_GTX570}, + {"NVC4", CARD_NVIDIA_GEFORCE_GTX460}, + {"NVC3", CARD_NVIDIA_GEFORCE_GT440}, + {"NVC1", CARD_NVIDIA_GEFORCE_GT420}, + {"NVC0", CARD_NVIDIA_GEFORCE_GTX480}, + /* Tesla */ + {"NVAF", CARD_NVIDIA_GEFORCE_GT320M}, + {"NVAC", CARD_NVIDIA_GEFORCE_8200}, + {"NVAA", CARD_NVIDIA_GEFORCE_8200}, /* 8100 */ + {"NVA8", CARD_NVIDIA_GEFORCE_210}, + {"NVA5", CARD_NVIDIA_GEFORCE_GT220}, + {"NVA3", CARD_NVIDIA_GEFORCE_GT240}, + {"NVA0", CARD_NVIDIA_GEFORCE_GTX280}, + {"NV98", CARD_NVIDIA_GEFORCE_9200}, + {"NV96", CARD_NVIDIA_GEFORCE_9400GT}, + {"NV94", CARD_NVIDIA_GEFORCE_9600GT}, + {"NV92", CARD_NVIDIA_GEFORCE_9800GT}, + {"NV86", CARD_NVIDIA_GEFORCE_8500GT}, + {"NV84", CARD_NVIDIA_GEFORCE_8600GT}, + {"NV50", CARD_NVIDIA_GEFORCE_8800GTX}, + /* Curie */ + {"NV68", CARD_NVIDIA_GEFORCE_6200}, /* 7050 */ + {"NV67", CARD_NVIDIA_GEFORCE_6200}, /* 7000M */ + {"NV63", CARD_NVIDIA_GEFORCE_6200}, /* 7100 */ + {"NV4E", CARD_NVIDIA_GEFORCE_6200}, /* 6100 Go / 6150 Go */ + {"NV4C", CARD_NVIDIA_GEFORCE_6200}, /* 6150SE */ + {"NV4B", CARD_NVIDIA_GEFORCE_7600}, + {"NV4A", CARD_NVIDIA_GEFORCE_6200}, + {"NV49", CARD_NVIDIA_GEFORCE_7800GT}, /* 7900 */ + {"NV47", CARD_NVIDIA_GEFORCE_7800GT}, + {"NV46", CARD_NVIDIA_GEFORCE_7400}, + {"NV45", CARD_NVIDIA_GEFORCE_6800}, + {"NV44", CARD_NVIDIA_GEFORCE_6200}, + {"NV43", CARD_NVIDIA_GEFORCE_6600GT}, + {"NV42", CARD_NVIDIA_GEFORCE_6800}, + {"NV41", CARD_NVIDIA_GEFORCE_6800}, + {"NV40", CARD_NVIDIA_GEFORCE_6800}, + /* Rankine */ + {"NV38", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5950 Ultra */ + {"NV36", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5700/5750 */ + {"NV35", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5900 */ + {"NV34", CARD_NVIDIA_GEFORCEFX_5200}, + {"NV31", CARD_NVIDIA_GEFORCEFX_5600}, + {"NV30", CARD_NVIDIA_GEFORCEFX_5800}, + /* Kelvin */ + {"nv28", CARD_NVIDIA_GEFORCE4_TI4200}, + {"nv25", CARD_NVIDIA_GEFORCE4_TI4200}, + {"nv20", CARD_NVIDIA_GEFORCE3}, + /* Celsius */ + {"nv1F", CARD_NVIDIA_GEFORCE4_MX}, /* GF4 MX IGP */ + {"nv1A", CARD_NVIDIA_GEFORCE2}, /* GF2 IGP */ + {"nv18", CARD_NVIDIA_GEFORCE4_MX}, + {"nv17", CARD_NVIDIA_GEFORCE4_MX}, + {"nv16", CARD_NVIDIA_GEFORCE2}, + {"nv15", CARD_NVIDIA_GEFORCE2}, + {"nv11", CARD_NVIDIA_GEFORCE2_MX}, + {"nv10", CARD_NVIDIA_GEFORCE}, + /* Fahrenheit */ + {"nv05", CARD_NVIDIA_RIVA_TNT2}, + {"nv04", CARD_NVIDIA_RIVA_TNT}, + {"nv03", CARD_NVIDIA_RIVA_128}, +}, +cards_redhat[] = +{ + {"virgl", CARD_REDHAT_VIRGL}, +}, +cards_vmware[] = +{ + {"SVGA3D", CARD_VMWARE_SVGA3D}, +}; + +static const struct gl_vendor_selection +{ + enum wined3d_gl_vendor gl_vendor; + const char *description; /* Description of the card selector i.e. Apple OS/X Intel */ + const struct wined3d_renderer_table *cards; /* To be used as cards[], pointer to the first member in an array */ + size_t cards_size; /* Number of entries in the array above */ +} +amd_gl_vendor_table[] = +{ + {GL_VENDOR_APPLE, "Apple OSX AMD/ATI binary driver", cards_amd_binary, ARRAY_SIZE(cards_amd_binary)}, + {GL_VENDOR_FGLRX, "AMD/ATI binary driver", cards_amd_binary, ARRAY_SIZE(cards_amd_binary)}, + {GL_VENDOR_MESA, "Mesa AMD/ATI driver", cards_amd_mesa, ARRAY_SIZE(cards_amd_mesa)}, +}, +nvidia_gl_vendor_table[] = +{ + {GL_VENDOR_APPLE, "Apple OSX NVidia binary driver", cards_nvidia_binary, ARRAY_SIZE(cards_nvidia_binary)}, + {GL_VENDOR_MESA, "Mesa Nouveau driver", cards_nvidia_mesa, ARRAY_SIZE(cards_nvidia_mesa)}, + {GL_VENDOR_NVIDIA, "NVIDIA binary driver", cards_nvidia_binary, ARRAY_SIZE(cards_nvidia_binary)}, +}, +redhat_gl_vendor_table[] = +{ + {GL_VENDOR_MESA, "Red Hat driver", cards_redhat, ARRAY_SIZE(cards_redhat)}, +}, +vmware_gl_vendor_table[] = +{ + {GL_VENDOR_MESA, "VMware driver", cards_vmware, ARRAY_SIZE(cards_vmware)}, +}, +intel_gl_vendor_table[] = +{ + {GL_VENDOR_APPLE, "Apple OSX Intel binary driver", cards_intel, ARRAY_SIZE(cards_intel)}, + {GL_VENDOR_MESA, "Mesa Intel driver", cards_intel, ARRAY_SIZE(cards_intel)}, +}; + +static enum wined3d_pci_device select_card_handler(const struct gl_vendor_selection *table, + unsigned int table_size, enum wined3d_gl_vendor gl_vendor, const char *gl_renderer) +{ + unsigned int i, j; + + for (i = 0; i < table_size; ++i) + { + if (table[i].gl_vendor != gl_vendor) + continue; + + TRACE("Applying card selector \"%s\".\n", table[i].description); + + for (j = 0; j < table[i].cards_size; ++j) + { + if (strstr(gl_renderer, table[i].cards[j].renderer)) + return table[i].cards[j].id; + } + return PCI_DEVICE_NONE; + } + FIXME("Couldn't find a suitable card selector for GL vendor %04x (using GL_RENDERER %s)\n", + gl_vendor, debugstr_a(gl_renderer)); + + return PCI_DEVICE_NONE; +} + +static const struct +{ + enum wined3d_pci_vendor card_vendor; + const char *description; /* Description of the card selector i.e. Apple OS/X Intel */ + const struct gl_vendor_selection *gl_vendor_selection; + unsigned int gl_vendor_count; +} +card_vendor_table[] = +{ + {HW_VENDOR_AMD, "AMD", amd_gl_vendor_table, ARRAY_SIZE(amd_gl_vendor_table)}, + {HW_VENDOR_NVIDIA, "NVIDIA", nvidia_gl_vendor_table, ARRAY_SIZE(nvidia_gl_vendor_table)}, + {HW_VENDOR_REDHAT, "Red Hat",redhat_gl_vendor_table, ARRAY_SIZE(redhat_gl_vendor_table)}, + {HW_VENDOR_VMWARE, "VMware", vmware_gl_vendor_table, ARRAY_SIZE(vmware_gl_vendor_table)}, + {HW_VENDOR_INTEL, "Intel", intel_gl_vendor_table, ARRAY_SIZE(intel_gl_vendor_table)}, +}; + +static enum wined3d_pci_device wined3d_guess_card(enum wined3d_feature_level feature_level, + const char *gl_renderer, enum wined3d_gl_vendor *gl_vendor, + enum wined3d_pci_vendor *card_vendor) +{ + /* A Direct3D device object contains the PCI id (vendor + device) of the + * videocard which is used for rendering. Various applications use this + * information to get a rough estimation of the features of the card and + * some might use it for enabling 3d effects only on certain types of + * videocards. In some cases games might even use it to work around bugs + * which happen on certain videocards/driver combinations. The problem is + * that OpenGL only exposes a rendering string containing the name of the + * videocard and not the PCI id. + * + * Various games depend on the PCI id, so somehow we need to provide one. + * A simple option is to parse the renderer string and translate this to + * the right PCI id. This is a lot of work because there are more than 200 + * GPUs just for NVIDIA. Various cards share the same renderer string, so + * the amount of code might be 'small' but there are quite a number of + * exceptions which would make this a pain to maintain. Another way would + * be to query the PCI id from the operating system (assuming this is the + * videocard which is used for rendering which is not always the case). + * This would work but it is not very portable. Second it would not work + * well in, let's say, a remote X situation in which the amount of 3d + * features which can be used is limited. + * + * As said most games only use the PCI id to get an indication of the + * capabilities of the card. It doesn't really matter if the given id is + * the correct one if we return the id of a card with similar 3d features. + * + * The code below checks the OpenGL capabilities of a videocard and matches + * that to a certain level of Direct3D functionality. Once a card passes + * the Direct3D9 check, we know that the card (in case of NVIDIA) is at + * least a GeforceFX. To give a better estimate we do a basic check on the + * renderer string but if that won't pass we return a default card. This + * way is better than maintaining a full card database as even without a + * full database we can return a card with similar features. Second the + * size of the database can be made quite small because when you know what + * type of 3d functionality a card has, you know to which GPU family the + * GPU must belong. Because of this you only have to check a small part of + * the renderer string to distinguish between different models from that + * family. + * + * The code also selects a default amount of video memory which we will + * use for an estimation of the amount of free texture memory. In case of + * real D3D the amount of texture memory includes video memory and system + * memory (to be specific AGP memory or in case of PCIE TurboCache / + * HyperMemory). We don't know how much system memory can be addressed by + * the system but we can make a reasonable estimation about the amount of + * video memory. If the value is slightly wrong it doesn't matter as we + * didn't include AGP-like memory which makes the amount of addressable + * memory higher and second OpenGL isn't that critical it moves to system + * memory behind our backs if really needed. Note that the amount of video + * memory can be overruled using a registry setting. */ + + enum wined3d_pci_device device; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(card_vendor_table); ++i) + { + if (card_vendor_table[i].card_vendor != *card_vendor) + continue; + + TRACE("Applying card selector \"%s\".\n", card_vendor_table[i].description); + device = select_card_handler(card_vendor_table[i].gl_vendor_selection, + card_vendor_table[i].gl_vendor_count, *gl_vendor, gl_renderer); + if (device != PCI_DEVICE_NONE) + return device; + + TRACE("Unrecognized renderer %s, falling back to default.\n", debugstr_a(gl_renderer)); + + return wined3d_gpu_from_feature_level(card_vendor, feature_level); + } + + FIXME("No card selector available for card vendor %04x (using GL_RENDERER %s).\n", + *card_vendor, debugstr_a(gl_renderer)); + + return wined3d_gpu_from_feature_level(card_vendor, feature_level); +} + +static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info, + const struct wined3d_shader_backend_ops *shader_backend_ops) +{ + if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_VERTEX_SHADER]) + return &glsl_vertex_pipe; + return &ffp_vertex_pipe; +} + +static const struct wined3d_fragment_pipe_ops *select_fragment_implementation(const struct wined3d_gl_info *gl_info, + const struct wined3d_shader_backend_ops *shader_backend_ops) +{ + if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_FRAGMENT_SHADER]) + return &glsl_fragment_pipe; + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) + return &arbfp_fragment_pipeline; + if (gl_info->supported[ATI_FRAGMENT_SHADER]) + return &atifs_fragment_pipeline; + if (gl_info->supported[NV_REGISTER_COMBINERS] && gl_info->supported[NV_TEXTURE_SHADER2]) + return &nvts_fragment_pipeline; + if (gl_info->supported[NV_REGISTER_COMBINERS]) + return &nvrc_fragment_pipeline; + return &ffp_fragment_pipeline; +} + +static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info) +{ + BOOL glsl = wined3d_settings.shader_backend == WINED3D_SHADER_BACKEND_AUTO + || wined3d_settings.shader_backend == WINED3D_SHADER_BACKEND_GLSL; + BOOL arb = wined3d_settings.shader_backend == WINED3D_SHADER_BACKEND_AUTO + || wined3d_settings.shader_backend == WINED3D_SHADER_BACKEND_ARB; + + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] && !glsl) + { + ERR_(winediag)("Ignoring the shader backend registry key. " + "GLSL is the only shader backend available on core profile contexts. " + "You need to explicitly set GL version to use legacy contexts.\n"); + glsl = TRUE; + } + + glsl = glsl && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20); + + if (glsl && gl_info->supported[ARB_VERTEX_SHADER] && gl_info->supported[ARB_FRAGMENT_SHADER]) + return &glsl_shader_backend; + if (arb && gl_info->supported[ARB_VERTEX_PROGRAM] && gl_info->supported[ARB_FRAGMENT_PROGRAM]) + return &arb_program_shader_backend; + if (glsl && (gl_info->supported[ARB_VERTEX_SHADER] || gl_info->supported[ARB_FRAGMENT_SHADER])) + return &glsl_shader_backend; + if (arb && (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM])) + return &arb_program_shader_backend; + return &none_shader_backend; +} + +static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *extensions, + const struct wined3d_extension_map *map, UINT entry_count) +{ + while (*extensions) + { + const char *start; + size_t len; + UINT i; + + while (isspace(*extensions)) + ++extensions; + start = extensions; + while (!isspace(*extensions) && *extensions) + ++extensions; + + len = extensions - start; + if (!len) + continue; + + TRACE("- %s.\n", debugstr_an(start, len)); + + for (i = 0; i < entry_count; ++i) + { + if (len == strlen(map[i].extension_string) + && !memcmp(start, map[i].extension_string, len)) + { + TRACE(" FOUND: %s support.\n", map[i].extension_string); + gl_info->supported[map[i].extension] = TRUE; + break; + } + } + } +} + +static void enumerate_gl_extensions(struct wined3d_gl_info *gl_info, + const struct wined3d_extension_map *map, unsigned int map_entries_count) +{ + const char *gl_extension_name; + unsigned int i, j; + GLint extensions_count; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count); + for (i = 0; i < extensions_count; ++i) + { + gl_extension_name = (const char *)GL_EXTCALL(glGetStringi(GL_EXTENSIONS, i)); + TRACE("- %s.\n", debugstr_a(gl_extension_name)); + for (j = 0; j < map_entries_count; ++j) + { + if (!strcmp(gl_extension_name, map[j].extension_string)) + { + TRACE("FOUND: %s support.\n", map[j].extension_string); + gl_info->supported[map[j].extension] = TRUE; + break; + } + } + } +} + +static void load_gl_funcs(struct wined3d_gl_info *gl_info) +{ +#define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn); + /* GL_APPLE_fence */ + USE_GL_FUNC(glDeleteFencesAPPLE) + USE_GL_FUNC(glFinishFenceAPPLE) + USE_GL_FUNC(glFinishObjectAPPLE) + USE_GL_FUNC(glGenFencesAPPLE) + USE_GL_FUNC(glIsFenceAPPLE) + USE_GL_FUNC(glSetFenceAPPLE) + USE_GL_FUNC(glTestFenceAPPLE) + USE_GL_FUNC(glTestObjectAPPLE) + /* GL_APPLE_flush_buffer_range */ + USE_GL_FUNC(glBufferParameteriAPPLE) + USE_GL_FUNC(glFlushMappedBufferRangeAPPLE) + /* GL_ARB_base_instance */ + USE_GL_FUNC(glDrawArraysInstancedBaseInstance) + USE_GL_FUNC(glDrawElementsInstancedBaseVertexBaseInstance) + /* GL_ARB_blend_func_extended */ + USE_GL_FUNC(glBindFragDataLocationIndexed) + USE_GL_FUNC(glGetFragDataIndex) + /* GL_ARB_buffer_storage */ + USE_GL_FUNC(glBufferStorage) + /* GL_ARB_clear_buffer_object */ + USE_GL_FUNC(glClearBufferData) + USE_GL_FUNC(glClearBufferSubData) + /* GL_ARB_clear_texture */ + USE_GL_FUNC(glClearTexImage) + USE_GL_FUNC(glClearTexSubImage) + /* GL_ARB_clip_control */ + USE_GL_FUNC(glClipControl) + /* GL_ARB_color_buffer_float */ + USE_GL_FUNC(glClampColorARB) + /* GL_ARB_compute_shader */ + USE_GL_FUNC(glDispatchCompute) + USE_GL_FUNC(glDispatchComputeIndirect) + /* GL_ARB_copy_buffer */ + USE_GL_FUNC(glCopyBufferSubData) + /* GL_ARB_copy_image */ + USE_GL_FUNC(glCopyImageSubData) + /* GL_ARB_debug_output */ + USE_GL_FUNC(glDebugMessageCallbackARB) + USE_GL_FUNC(glDebugMessageControlARB) + USE_GL_FUNC(glDebugMessageInsertARB) + USE_GL_FUNC(glGetDebugMessageLogARB) + /* GL_ARB_draw_buffers */ + USE_GL_FUNC(glDrawBuffersARB) + /* GL_ARB_draw_elements_base_vertex */ + USE_GL_FUNC(glDrawElementsBaseVertex) + USE_GL_FUNC(glDrawElementsInstancedBaseVertex) + USE_GL_FUNC(glDrawRangeElementsBaseVertex) + USE_GL_FUNC(glMultiDrawElementsBaseVertex) + /* GL_ARB_draw_indirect */ + USE_GL_FUNC(glDrawArraysIndirect) + USE_GL_FUNC(glDrawElementsIndirect) + /* GL_ARB_draw_instanced */ + USE_GL_FUNC(glDrawArraysInstancedARB) + USE_GL_FUNC(glDrawElementsInstancedARB) + /* GL_ARB_ES2_compatibility */ + USE_GL_FUNC(glReleaseShaderCompiler) + USE_GL_FUNC(glShaderBinary) + USE_GL_FUNC(glGetShaderPrecisionFormat) + USE_GL_FUNC(glDepthRangef) + USE_GL_FUNC(glClearDepthf) + /* GL_ARB_framebuffer_no_attachments */ + USE_GL_FUNC(glFramebufferParameteri) + /* GL_ARB_framebuffer_object */ + USE_GL_FUNC(glBindFramebuffer) + USE_GL_FUNC(glBindRenderbuffer) + USE_GL_FUNC(glBlitFramebuffer) + USE_GL_FUNC(glCheckFramebufferStatus) + USE_GL_FUNC(glDeleteFramebuffers) + USE_GL_FUNC(glDeleteRenderbuffers) + USE_GL_FUNC(glFramebufferRenderbuffer) + USE_GL_FUNC(glFramebufferTexture) + USE_GL_FUNC(glFramebufferTexture1D) + USE_GL_FUNC(glFramebufferTexture2D) + USE_GL_FUNC(glFramebufferTexture3D) + USE_GL_FUNC(glFramebufferTextureLayer) + USE_GL_FUNC(glGenFramebuffers) + USE_GL_FUNC(glGenRenderbuffers) + USE_GL_FUNC(glGenerateMipmap) + USE_GL_FUNC(glGetFramebufferAttachmentParameteriv) + USE_GL_FUNC(glGetRenderbufferParameteriv) + USE_GL_FUNC(glIsFramebuffer) + USE_GL_FUNC(glIsRenderbuffer) + USE_GL_FUNC(glRenderbufferStorage) + USE_GL_FUNC(glRenderbufferStorageMultisample) + /* GL_ARB_geometry_shader4 */ + USE_GL_FUNC(glFramebufferTextureARB) + USE_GL_FUNC(glFramebufferTextureFaceARB) + USE_GL_FUNC(glFramebufferTextureLayerARB) + USE_GL_FUNC(glProgramParameteriARB) + /* GL_ARB_instanced_arrays */ + USE_GL_FUNC(glVertexAttribDivisorARB) + /* GL_ARB_internalformat_query */ + USE_GL_FUNC(glGetInternalformativ) + /* GL_ARB_internalformat_query2 */ + USE_GL_FUNC(glGetInternalformati64v) + /* GL_ARB_map_buffer_range */ + USE_GL_FUNC(glFlushMappedBufferRange) + USE_GL_FUNC(glMapBufferRange) + /* GL_ARB_multisample */ + USE_GL_FUNC(glSampleCoverageARB) + /* GL_ARB_multitexture */ + USE_GL_FUNC(glActiveTextureARB) + USE_GL_FUNC(glClientActiveTextureARB) + USE_GL_FUNC(glMultiTexCoord1fARB) + USE_GL_FUNC(glMultiTexCoord1fvARB) + USE_GL_FUNC(glMultiTexCoord2fARB) + USE_GL_FUNC(glMultiTexCoord2fvARB) + USE_GL_FUNC(glMultiTexCoord2svARB) + USE_GL_FUNC(glMultiTexCoord3fARB) + USE_GL_FUNC(glMultiTexCoord3fvARB) + USE_GL_FUNC(glMultiTexCoord4fARB) + USE_GL_FUNC(glMultiTexCoord4fvARB) + USE_GL_FUNC(glMultiTexCoord4svARB) + /* GL_ARB_occlusion_query */ + USE_GL_FUNC(glBeginQueryARB) + USE_GL_FUNC(glDeleteQueriesARB) + USE_GL_FUNC(glEndQueryARB) + USE_GL_FUNC(glGenQueriesARB) + USE_GL_FUNC(glGetQueryivARB) + USE_GL_FUNC(glGetQueryObjectivARB) + USE_GL_FUNC(glGetQueryObjectuivARB) + USE_GL_FUNC(glIsQueryARB) + /* GL_ARB_point_parameters */ + USE_GL_FUNC(glPointParameterfARB) + USE_GL_FUNC(glPointParameterfvARB) + /* GL_ARB_polgyon_offset_clamp */ + USE_GL_FUNC(glPolygonOffsetClamp) + /* GL_ARB_provoking_vertex */ + USE_GL_FUNC(glProvokingVertex) + /* GL_ARB_sample_shading */ + USE_GL_FUNC(glMinSampleShadingARB) + /* GL_ARB_sampler_objects */ + USE_GL_FUNC(glGenSamplers) + USE_GL_FUNC(glDeleteSamplers) + USE_GL_FUNC(glIsSampler) + USE_GL_FUNC(glBindSampler) + USE_GL_FUNC(glSamplerParameteri) + USE_GL_FUNC(glSamplerParameterf) + USE_GL_FUNC(glSamplerParameteriv) + USE_GL_FUNC(glSamplerParameterfv) + USE_GL_FUNC(glSamplerParameterIiv) + USE_GL_FUNC(glSamplerParameterIuiv) + USE_GL_FUNC(glGetSamplerParameteriv) + USE_GL_FUNC(glGetSamplerParameterfv) + USE_GL_FUNC(glGetSamplerParameterIiv) + USE_GL_FUNC(glGetSamplerParameterIuiv) + /* GL_ARB_shader_atomic_counters */ + USE_GL_FUNC(glGetActiveAtomicCounterBufferiv) + /* GL_ARB_shader_image_load_store */ + USE_GL_FUNC(glBindImageTexture) + USE_GL_FUNC(glMemoryBarrier) + /* GL_ARB_shader_objects */ + USE_GL_FUNC(glAttachObjectARB) + USE_GL_FUNC(glBindAttribLocationARB) + USE_GL_FUNC(glCompileShaderARB) + USE_GL_FUNC(glCreateProgramObjectARB) + USE_GL_FUNC(glCreateShaderObjectARB) + USE_GL_FUNC(glDeleteObjectARB) + USE_GL_FUNC(glDetachObjectARB) + USE_GL_FUNC(glGetActiveUniformARB) + USE_GL_FUNC(glGetAttachedObjectsARB) + USE_GL_FUNC(glGetAttribLocationARB) + USE_GL_FUNC(glGetHandleARB) + USE_GL_FUNC(glGetInfoLogARB) + USE_GL_FUNC(glGetObjectParameterfvARB) + USE_GL_FUNC(glGetObjectParameterivARB) + USE_GL_FUNC(glGetShaderSourceARB) + USE_GL_FUNC(glGetUniformLocationARB) + USE_GL_FUNC(glGetUniformfvARB) + USE_GL_FUNC(glGetUniformivARB) + USE_GL_FUNC(glLinkProgramARB) + USE_GL_FUNC(glShaderSourceARB) + USE_GL_FUNC(glUniform1fARB) + USE_GL_FUNC(glUniform1fvARB) + USE_GL_FUNC(glUniform1iARB) + USE_GL_FUNC(glUniform1ivARB) + USE_GL_FUNC(glUniform2fARB) + USE_GL_FUNC(glUniform2fvARB) + USE_GL_FUNC(glUniform2iARB) + USE_GL_FUNC(glUniform2ivARB) + USE_GL_FUNC(glUniform3fARB) + USE_GL_FUNC(glUniform3fvARB) + USE_GL_FUNC(glUniform3iARB) + USE_GL_FUNC(glUniform3ivARB) + USE_GL_FUNC(glUniform4fARB) + USE_GL_FUNC(glUniform4fvARB) + USE_GL_FUNC(glUniform4iARB) + USE_GL_FUNC(glUniform4ivARB) + USE_GL_FUNC(glUniformMatrix2fvARB) + USE_GL_FUNC(glUniformMatrix3fvARB) + USE_GL_FUNC(glUniformMatrix4fvARB) + USE_GL_FUNC(glUseProgramObjectARB) + USE_GL_FUNC(glValidateProgramARB) + /* GL_ARB_shader_storage_buffer_object */ + USE_GL_FUNC(glShaderStorageBlockBinding) + /* GL_ARB_sync */ + USE_GL_FUNC(glClientWaitSync) + USE_GL_FUNC(glDeleteSync) + USE_GL_FUNC(glFenceSync) + USE_GL_FUNC(glGetInteger64v) + USE_GL_FUNC(glGetSynciv) + USE_GL_FUNC(glIsSync) + USE_GL_FUNC(glWaitSync) + /* GL_ARB_tessellation_shader */ + USE_GL_FUNC(glPatchParameteri) + USE_GL_FUNC(glPatchParameterfv) + /* GL_ARB_texture_buffer_object */ + USE_GL_FUNC(glTexBufferARB) + /* GL_ARB_texture_buffer_range */ + USE_GL_FUNC(glTexBufferRange) + /* GL_ARB_texture_compression */ + USE_GL_FUNC(glCompressedTexImage2DARB) + USE_GL_FUNC(glCompressedTexImage3DARB) + USE_GL_FUNC(glCompressedTexSubImage2DARB) + USE_GL_FUNC(glCompressedTexSubImage3DARB) + USE_GL_FUNC(glGetCompressedTexImageARB) + /* GL_ARB_texture_multisample */ + USE_GL_FUNC(glGetMultisamplefv); + USE_GL_FUNC(glSampleMaski); + USE_GL_FUNC(glTexImage2DMultisample); + USE_GL_FUNC(glTexImage3DMultisample); + /* GL_ARB_texture_storage */ + USE_GL_FUNC(glTexStorage1D) + USE_GL_FUNC(glTexStorage2D) + USE_GL_FUNC(glTexStorage3D) + /* GL_ARB_texture_storage_multisample */ + USE_GL_FUNC(glTexStorage2DMultisample); + USE_GL_FUNC(glTexStorage3DMultisample); + /* GL_ARB_texture_view */ + USE_GL_FUNC(glTextureView) + /* GL_ARB_timer_query */ + USE_GL_FUNC(glQueryCounter) + USE_GL_FUNC(glGetQueryObjectui64v) + /* GL_ARB_transform_feedback2 */ + USE_GL_FUNC(glBindTransformFeedback); + USE_GL_FUNC(glDeleteTransformFeedbacks); + USE_GL_FUNC(glDrawTransformFeedback); + USE_GL_FUNC(glGenTransformFeedbacks); + USE_GL_FUNC(glIsTransformFeedback); + USE_GL_FUNC(glPauseTransformFeedback); + USE_GL_FUNC(glResumeTransformFeedback); + /* GL_ARB_transform_feedback3 */ + USE_GL_FUNC(glBeginQueryIndexed); + USE_GL_FUNC(glDrawTransformFeedbackStream); + USE_GL_FUNC(glEndQueryIndexed); + USE_GL_FUNC(glGetQueryIndexediv); + /* GL_ARB_uniform_buffer_object */ + USE_GL_FUNC(glBindBufferBase) + USE_GL_FUNC(glBindBufferRange) + USE_GL_FUNC(glGetActiveUniformBlockName) + USE_GL_FUNC(glGetActiveUniformBlockiv) + USE_GL_FUNC(glGetActiveUniformName) + USE_GL_FUNC(glGetActiveUniformsiv) + USE_GL_FUNC(glGetIntegeri_v) + USE_GL_FUNC(glGetUniformBlockIndex) + USE_GL_FUNC(glGetUniformIndices) + USE_GL_FUNC(glUniformBlockBinding) + /* GL_ARB_vertex_buffer_object */ + USE_GL_FUNC(glBindBufferARB) + USE_GL_FUNC(glBufferDataARB) + USE_GL_FUNC(glBufferSubDataARB) + USE_GL_FUNC(glDeleteBuffersARB) + USE_GL_FUNC(glGenBuffersARB) + USE_GL_FUNC(glGetBufferParameterivARB) + USE_GL_FUNC(glGetBufferPointervARB) + USE_GL_FUNC(glGetBufferSubDataARB) + USE_GL_FUNC(glIsBufferARB) + USE_GL_FUNC(glMapBufferARB) + USE_GL_FUNC(glUnmapBufferARB) + /* GL_ARB_vertex_program */ + USE_GL_FUNC(glBindProgramARB) + USE_GL_FUNC(glDeleteProgramsARB) + USE_GL_FUNC(glDisableVertexAttribArrayARB) + USE_GL_FUNC(glEnableVertexAttribArrayARB) + USE_GL_FUNC(glGenProgramsARB) + USE_GL_FUNC(glGetProgramivARB) + USE_GL_FUNC(glProgramEnvParameter4fvARB) + USE_GL_FUNC(glProgramLocalParameter4fvARB) + USE_GL_FUNC(glProgramStringARB) + USE_GL_FUNC(glVertexAttrib1dARB) + USE_GL_FUNC(glVertexAttrib1dvARB) + USE_GL_FUNC(glVertexAttrib1fARB) + USE_GL_FUNC(glVertexAttrib1fvARB) + USE_GL_FUNC(glVertexAttrib1sARB) + USE_GL_FUNC(glVertexAttrib1svARB) + USE_GL_FUNC(glVertexAttrib2dARB) + USE_GL_FUNC(glVertexAttrib2dvARB) + USE_GL_FUNC(glVertexAttrib2fARB) + USE_GL_FUNC(glVertexAttrib2fvARB) + USE_GL_FUNC(glVertexAttrib2sARB) + USE_GL_FUNC(glVertexAttrib2svARB) + USE_GL_FUNC(glVertexAttrib3dARB) + USE_GL_FUNC(glVertexAttrib3dvARB) + USE_GL_FUNC(glVertexAttrib3fARB) + USE_GL_FUNC(glVertexAttrib3fvARB) + USE_GL_FUNC(glVertexAttrib3sARB) + USE_GL_FUNC(glVertexAttrib3svARB) + USE_GL_FUNC(glVertexAttrib4NbvARB) + USE_GL_FUNC(glVertexAttrib4NivARB) + USE_GL_FUNC(glVertexAttrib4NsvARB) + USE_GL_FUNC(glVertexAttrib4NubARB) + USE_GL_FUNC(glVertexAttrib4NubvARB) + USE_GL_FUNC(glVertexAttrib4NuivARB) + USE_GL_FUNC(glVertexAttrib4NusvARB) + USE_GL_FUNC(glVertexAttrib4bvARB) + USE_GL_FUNC(glVertexAttrib4dARB) + USE_GL_FUNC(glVertexAttrib4dvARB) + USE_GL_FUNC(glVertexAttrib4fARB) + USE_GL_FUNC(glVertexAttrib4fvARB) + USE_GL_FUNC(glVertexAttrib4ivARB) + USE_GL_FUNC(glVertexAttrib4sARB) + USE_GL_FUNC(glVertexAttrib4svARB) + USE_GL_FUNC(glVertexAttrib4ubvARB) + USE_GL_FUNC(glVertexAttrib4uivARB) + USE_GL_FUNC(glVertexAttrib4usvARB) + USE_GL_FUNC(glVertexAttribPointerARB) + /* GL_ARB_viewport_array */ + USE_GL_FUNC(glDepthRangeArrayv) + USE_GL_FUNC(glDepthRangeIndexed) + USE_GL_FUNC(glGetDoublei_v) + USE_GL_FUNC(glGetFloati_v) + USE_GL_FUNC(glScissorArrayv) + USE_GL_FUNC(glScissorIndexed) + USE_GL_FUNC(glScissorIndexedv) + USE_GL_FUNC(glViewportArrayv) + USE_GL_FUNC(glViewportIndexedf) + USE_GL_FUNC(glViewportIndexedfv) + /* GL_ATI_fragment_shader */ + USE_GL_FUNC(glAlphaFragmentOp1ATI) + USE_GL_FUNC(glAlphaFragmentOp2ATI) + USE_GL_FUNC(glAlphaFragmentOp3ATI) + USE_GL_FUNC(glBeginFragmentShaderATI) + USE_GL_FUNC(glBindFragmentShaderATI) + USE_GL_FUNC(glColorFragmentOp1ATI) + USE_GL_FUNC(glColorFragmentOp2ATI) + USE_GL_FUNC(glColorFragmentOp3ATI) + USE_GL_FUNC(glDeleteFragmentShaderATI) + USE_GL_FUNC(glEndFragmentShaderATI) + USE_GL_FUNC(glGenFragmentShadersATI) + USE_GL_FUNC(glPassTexCoordATI) + USE_GL_FUNC(glSampleMapATI) + USE_GL_FUNC(glSetFragmentShaderConstantATI) + /* GL_ATI_separate_stencil */ + USE_GL_FUNC(glStencilOpSeparateATI) + USE_GL_FUNC(glStencilFuncSeparateATI) + /* GL_EXT_blend_color */ + USE_GL_FUNC(glBlendColorEXT) + /* GL_EXT_blend_equation_separate */ + USE_GL_FUNC(glBlendFuncSeparateEXT) + /* GL_EXT_blend_func_separate */ + USE_GL_FUNC(glBlendEquationSeparateEXT) + /* GL_EXT_blend_minmax */ + USE_GL_FUNC(glBlendEquationEXT) + /* GL_EXT_depth_bounds_test */ + USE_GL_FUNC(glDepthBoundsEXT) + /* GL_EXT_draw_buffers2 */ + USE_GL_FUNC(glColorMaskIndexedEXT) + USE_GL_FUNC(glDisableIndexedEXT) + USE_GL_FUNC(glEnableIndexedEXT) + USE_GL_FUNC(glGetBooleanIndexedvEXT) + USE_GL_FUNC(glGetIntegerIndexedvEXT) + USE_GL_FUNC(glIsEnabledIndexedEXT) + /* GL_EXT_fog_coord */ + USE_GL_FUNC(glFogCoordPointerEXT) + USE_GL_FUNC(glFogCoorddEXT) + USE_GL_FUNC(glFogCoorddvEXT) + USE_GL_FUNC(glFogCoordfEXT) + USE_GL_FUNC(glFogCoordfvEXT) + /* GL_EXT_framebuffer_blit */ + USE_GL_FUNC(glBlitFramebufferEXT) + /* GL_EXT_framebuffer_multisample */ + USE_GL_FUNC(glRenderbufferStorageMultisampleEXT) + /* GL_EXT_framebuffer_object */ + USE_GL_FUNC(glBindFramebufferEXT) + USE_GL_FUNC(glBindRenderbufferEXT) + USE_GL_FUNC(glCheckFramebufferStatusEXT) + USE_GL_FUNC(glDeleteFramebuffersEXT) + USE_GL_FUNC(glDeleteRenderbuffersEXT) + USE_GL_FUNC(glFramebufferRenderbufferEXT) + USE_GL_FUNC(glFramebufferTexture1DEXT) + USE_GL_FUNC(glFramebufferTexture2DEXT) + USE_GL_FUNC(glFramebufferTexture3DEXT) + USE_GL_FUNC(glGenFramebuffersEXT) + USE_GL_FUNC(glGenRenderbuffersEXT) + USE_GL_FUNC(glGenerateMipmapEXT) + USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT) + USE_GL_FUNC(glGetRenderbufferParameterivEXT) + USE_GL_FUNC(glIsFramebufferEXT) + USE_GL_FUNC(glIsRenderbufferEXT) + USE_GL_FUNC(glRenderbufferStorageEXT) + /* GL_EXT_gpu_program_parameters */ + USE_GL_FUNC(glProgramEnvParameters4fvEXT) + USE_GL_FUNC(glProgramLocalParameters4fvEXT) + /* GL_EXT_gpu_shader4 */ + USE_GL_FUNC(glBindFragDataLocationEXT) + USE_GL_FUNC(glGetFragDataLocationEXT) + USE_GL_FUNC(glGetUniformuivEXT) + USE_GL_FUNC(glGetVertexAttribIivEXT) + USE_GL_FUNC(glGetVertexAttribIuivEXT) + USE_GL_FUNC(glUniform1uiEXT) + USE_GL_FUNC(glUniform1uivEXT) + USE_GL_FUNC(glUniform2uiEXT) + USE_GL_FUNC(glUniform2uivEXT) + USE_GL_FUNC(glUniform3uiEXT) + USE_GL_FUNC(glUniform3uivEXT) + USE_GL_FUNC(glUniform4uiEXT) + USE_GL_FUNC(glUniform4uivEXT) + USE_GL_FUNC(glVertexAttribI1iEXT) + USE_GL_FUNC(glVertexAttribI1ivEXT) + USE_GL_FUNC(glVertexAttribI1uiEXT) + USE_GL_FUNC(glVertexAttribI1uivEXT) + USE_GL_FUNC(glVertexAttribI2iEXT) + USE_GL_FUNC(glVertexAttribI2ivEXT) + USE_GL_FUNC(glVertexAttribI2uiEXT) + USE_GL_FUNC(glVertexAttribI2uivEXT) + USE_GL_FUNC(glVertexAttribI3iEXT) + USE_GL_FUNC(glVertexAttribI3ivEXT) + USE_GL_FUNC(glVertexAttribI3uiEXT) + USE_GL_FUNC(glVertexAttribI3uivEXT) + USE_GL_FUNC(glVertexAttribI4bvEXT) + USE_GL_FUNC(glVertexAttribI4iEXT) + USE_GL_FUNC(glVertexAttribI4ivEXT) + USE_GL_FUNC(glVertexAttribI4svEXT) + USE_GL_FUNC(glVertexAttribI4ubvEXT) + USE_GL_FUNC(glVertexAttribI4uiEXT) + USE_GL_FUNC(glVertexAttribI4uivEXT) + USE_GL_FUNC(glVertexAttribI4usvEXT) + USE_GL_FUNC(glVertexAttribIPointerEXT) + /* GL_EXT_memory_object */ + USE_GL_FUNC(glGetUnsignedBytei_vEXT) + USE_GL_FUNC(glGetUnsignedBytevEXT) + /* GL_EXT_point_parameters */ + USE_GL_FUNC(glPointParameterfEXT) + USE_GL_FUNC(glPointParameterfvEXT) + /* GL_EXT_polgyon_offset_clamp */ + USE_GL_FUNC(glPolygonOffsetClampEXT) + /* GL_EXT_provoking_vertex */ + USE_GL_FUNC(glProvokingVertexEXT) + /* GL_EXT_secondary_color */ + USE_GL_FUNC(glSecondaryColor3fEXT) + USE_GL_FUNC(glSecondaryColor3fvEXT) + USE_GL_FUNC(glSecondaryColor3ubEXT) + USE_GL_FUNC(glSecondaryColor3ubvEXT) + USE_GL_FUNC(glSecondaryColorPointerEXT) + /* GL_EXT_stencil_two_side */ + USE_GL_FUNC(glActiveStencilFaceEXT) + /* GL_EXT_texture3D */ + USE_GL_FUNC(glTexImage3D) + USE_GL_FUNC(glTexImage3DEXT) + USE_GL_FUNC(glTexSubImage3D) + USE_GL_FUNC(glTexSubImage3DEXT) + /* GL_NV_fence */ + USE_GL_FUNC(glDeleteFencesNV) + USE_GL_FUNC(glFinishFenceNV) + USE_GL_FUNC(glGenFencesNV) + USE_GL_FUNC(glGetFenceivNV) + USE_GL_FUNC(glIsFenceNV) + USE_GL_FUNC(glSetFenceNV) + USE_GL_FUNC(glTestFenceNV) + /* GL_NV_half_float */ + USE_GL_FUNC(glColor3hNV) + USE_GL_FUNC(glColor3hvNV) + USE_GL_FUNC(glColor4hNV) + USE_GL_FUNC(glColor4hvNV) + USE_GL_FUNC(glFogCoordhNV) + USE_GL_FUNC(glFogCoordhvNV) + USE_GL_FUNC(glMultiTexCoord1hNV) + USE_GL_FUNC(glMultiTexCoord1hvNV) + USE_GL_FUNC(glMultiTexCoord2hNV) + USE_GL_FUNC(glMultiTexCoord2hvNV) + USE_GL_FUNC(glMultiTexCoord3hNV) + USE_GL_FUNC(glMultiTexCoord3hvNV) + USE_GL_FUNC(glMultiTexCoord4hNV) + USE_GL_FUNC(glMultiTexCoord4hvNV) + USE_GL_FUNC(glNormal3hNV) + USE_GL_FUNC(glNormal3hvNV) + USE_GL_FUNC(glSecondaryColor3hNV) + USE_GL_FUNC(glSecondaryColor3hvNV) + USE_GL_FUNC(glTexCoord1hNV) + USE_GL_FUNC(glTexCoord1hvNV) + USE_GL_FUNC(glTexCoord2hNV) + USE_GL_FUNC(glTexCoord2hvNV) + USE_GL_FUNC(glTexCoord3hNV) + USE_GL_FUNC(glTexCoord3hvNV) + USE_GL_FUNC(glTexCoord4hNV) + USE_GL_FUNC(glTexCoord4hvNV) + USE_GL_FUNC(glVertex2hNV) + USE_GL_FUNC(glVertex2hvNV) + USE_GL_FUNC(glVertex3hNV) + USE_GL_FUNC(glVertex3hvNV) + USE_GL_FUNC(glVertex4hNV) + USE_GL_FUNC(glVertex4hvNV) + USE_GL_FUNC(glVertexAttrib1hNV) + USE_GL_FUNC(glVertexAttrib1hvNV) + USE_GL_FUNC(glVertexAttrib2hNV) + USE_GL_FUNC(glVertexAttrib2hvNV) + USE_GL_FUNC(glVertexAttrib3hNV) + USE_GL_FUNC(glVertexAttrib3hvNV) + USE_GL_FUNC(glVertexAttrib4hNV) + USE_GL_FUNC(glVertexAttrib4hvNV) + USE_GL_FUNC(glVertexAttribs1hvNV) + USE_GL_FUNC(glVertexAttribs2hvNV) + USE_GL_FUNC(glVertexAttribs3hvNV) + USE_GL_FUNC(glVertexAttribs4hvNV) + USE_GL_FUNC(glVertexWeighthNV) + USE_GL_FUNC(glVertexWeighthvNV) + /* GL_NV_point_sprite */ + USE_GL_FUNC(glPointParameteriNV) + USE_GL_FUNC(glPointParameterivNV) + /* GL_NV_register_combiners */ + USE_GL_FUNC(glCombinerInputNV) + USE_GL_FUNC(glCombinerOutputNV) + USE_GL_FUNC(glCombinerParameterfNV) + USE_GL_FUNC(glCombinerParameterfvNV) + USE_GL_FUNC(glCombinerParameteriNV) + USE_GL_FUNC(glCombinerParameterivNV) + USE_GL_FUNC(glFinalCombinerInputNV) + /* WGL extensions */ + USE_GL_FUNC(wglChoosePixelFormatARB) + USE_GL_FUNC(wglGetExtensionsStringARB) + USE_GL_FUNC(wglGetPixelFormatAttribfvARB) + USE_GL_FUNC(wglGetPixelFormatAttribivARB) + USE_GL_FUNC(wglQueryCurrentRendererIntegerWINE) + USE_GL_FUNC(wglQueryCurrentRendererStringWINE) + USE_GL_FUNC(wglQueryRendererIntegerWINE) + USE_GL_FUNC(wglQueryRendererStringWINE) + USE_GL_FUNC(wglSetPixelFormatWINE) + USE_GL_FUNC(wglSwapIntervalEXT) + + /* Newer core functions */ + USE_GL_FUNC(glActiveTexture) /* OpenGL 1.3 */ + USE_GL_FUNC(glAttachShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glBeginQuery) /* OpenGL 1.5 */ + USE_GL_FUNC(glBeginTransformFeedback) /* OpenGL 3.0 */ + USE_GL_FUNC(glBindAttribLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glBindBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glBindFragDataLocation) /* OpenGL 3.0 */ + USE_GL_FUNC(glBindVertexArray) /* OpenGL 3.0 */ + USE_GL_FUNC(glBlendColor) /* OpenGL 1.4 */ + USE_GL_FUNC(glBlendEquation) /* OpenGL 1.4 */ + USE_GL_FUNC(glBlendEquationSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glBlendFuncSeparate) /* OpenGL 1.4 */ + USE_GL_FUNC(glBufferData) /* OpenGL 1.5 */ + USE_GL_FUNC(glBufferSubData) /* OpenGL 1.5 */ + USE_GL_FUNC(glColorMaski) /* OpenGL 3.0 */ + USE_GL_FUNC(glCompileShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glCompressedTexImage2D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCompressedTexImage3D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCompressedTexSubImage2D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCompressedTexSubImage3D) /* OpenGL 1.3 */ + USE_GL_FUNC(glCreateProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glCreateShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDebugMessageCallback) /* OpenGL 4.3 */ + USE_GL_FUNC(glDebugMessageControl) /* OpenGL 4.3 */ + USE_GL_FUNC(glDebugMessageInsert) /* OpenGL 4.3 */ + USE_GL_FUNC(glDeleteBuffers) /* OpenGL 1.5 */ + USE_GL_FUNC(glDeleteProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glDeleteQueries) /* OpenGL 1.5 */ + USE_GL_FUNC(glDeleteShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDeleteVertexArrays) /* OpenGL 3.0 */ + USE_GL_FUNC(glDetachShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDisablei) /* OpenGL 3.0 */ + USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */ + USE_GL_FUNC(glDrawArraysInstanced) /* OpenGL 3.1 */ + USE_GL_FUNC(glDrawBuffers) /* OpenGL 2.0 */ + USE_GL_FUNC(glDrawElementsInstanced) /* OpenGL 3.1 */ + USE_GL_FUNC(glEnablei) /* OpenGL 3.0 */ + USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */ + USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */ + USE_GL_FUNC(glEndTransformFeedback) /* OpenGL 3.0 */ + USE_GL_FUNC(glFramebufferTexture) /* OpenGL 3.2 */ + USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */ + USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */ + USE_GL_FUNC(glGenVertexArrays) /* OpenGL 3.0 */ + USE_GL_FUNC(glGetActiveUniform) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetAttachedShaders) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetAttribLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetBooleani_v) /* OpenGL 3.0 */ + USE_GL_FUNC(glGetBufferSubData) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetCompressedTexImage) /* OpenGL 1.3 */ + USE_GL_FUNC(glGetDebugMessageLog) /* OpenGL 4.3 */ + USE_GL_FUNC(glGetIntegeri_v) /* OpenGL 3.0 */ + USE_GL_FUNC(glGetProgramInfoLog) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetProgramiv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetQueryiv) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetQueryObjectuiv) /* OpenGL 1.5 */ + USE_GL_FUNC(glGetShaderInfoLog) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetShaderiv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetShaderSource) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetStringi) /* OpenGL 3.0 */ + USE_GL_FUNC(glGetTextureLevelParameteriv) /* OpenGL 4.5 */ + USE_GL_FUNC(glGetTextureParameteriv) /* OpenGL 4.5 */ + USE_GL_FUNC(glGetUniformfv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetUniformiv) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetUniformLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glIsEnabledi) /* OpenGL 3.0 */ + USE_GL_FUNC(glLinkProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glMapBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glMinSampleShading) /* OpenGL 4.0 */ + USE_GL_FUNC(glPointParameteri) /* OpenGL 1.4 */ + USE_GL_FUNC(glPointParameteriv) /* OpenGL 1.4 */ + USE_GL_FUNC(glShaderSource) /* OpenGL 2.0 */ + USE_GL_FUNC(glStencilFuncSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glStencilOpSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glTexBuffer) /* OpenGL 3.1 */ + USE_GL_FUNC(glTexImage3D) /* OpenGL 1.2 */ + USE_GL_FUNC(glTexSubImage3D) /* OpenGL 1.2 */ + USE_GL_FUNC(glTransformFeedbackVaryings) /* OpenGL 3.0 */ + USE_GL_FUNC(glUniform1f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform1fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform1i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform1iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform2iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform3iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4f) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4i) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniform4iv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniformMatrix2fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniformMatrix3fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUniformMatrix4fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glUnmapBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glUseProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glValidateProgram) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib1f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib1fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib2f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib2fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib3f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib3fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4f) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4fv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nsv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nub) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nubv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nusv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4sv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4ubv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttribDivisor) /* OpenGL 3.3 */ + USE_GL_FUNC(glVertexAttribIPointer) /* OpenGL 3.0 */ + USE_GL_FUNC(glVertexAttribPointer) /* OpenGL 2.0 */ +#undef USE_GL_FUNC + +#ifndef USE_WIN32_OPENGL + /* hack: use the functions directly from the TEB table to bypass the thunks */ + /* note that we still need the above wglGetProcAddress calls to initialize the table */ + gl_info->gl_ops.ext = ((struct opengl_funcs *)NtCurrentTeb()->glTable)->ext; +#endif + +#define MAP_GL_FUNCTION(core_func, ext_func) \ + do \ + { \ + if (!gl_info->gl_ops.ext.p_##core_func) \ + gl_info->gl_ops.ext.p_##core_func = gl_info->gl_ops.ext.p_##ext_func; \ + } while (0) +#define MAP_GL_FUNCTION_CAST(core_func, ext_func) \ + do \ + { \ + if (!gl_info->gl_ops.ext.p_##core_func) \ + gl_info->gl_ops.ext.p_##core_func = (void *)gl_info->gl_ops.ext.p_##ext_func; \ + } while (0) + + MAP_GL_FUNCTION(glActiveTexture, glActiveTextureARB); + MAP_GL_FUNCTION(glAttachShader, glAttachObjectARB); + MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB); + MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB); + MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB); + MAP_GL_FUNCTION(glBindFragDataLocation, glBindFragDataLocationEXT); + MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT); + MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT); + MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT); + MAP_GL_FUNCTION(glBlendFuncSeparate, glBlendFuncSeparateEXT); + MAP_GL_FUNCTION(glBufferData, glBufferDataARB); + MAP_GL_FUNCTION(glBufferSubData, glBufferSubDataARB); + MAP_GL_FUNCTION(glColorMaski, glColorMaskIndexedEXT); + MAP_GL_FUNCTION(glCompileShader, glCompileShaderARB); + MAP_GL_FUNCTION(glCompressedTexImage2D, glCompressedTexImage2DARB); + MAP_GL_FUNCTION(glCompressedTexImage3D, glCompressedTexImage3DARB); + MAP_GL_FUNCTION(glCompressedTexSubImage2D, glCompressedTexSubImage2DARB); + MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB); + MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB); + MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB); + MAP_GL_FUNCTION(glDebugMessageCallback, glDebugMessageCallbackARB); + MAP_GL_FUNCTION(glDebugMessageControl, glDebugMessageControlARB); + MAP_GL_FUNCTION(glDebugMessageInsert, glDebugMessageInsertARB); + MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB); + MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB); + MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB); + MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB); + MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB); + MAP_GL_FUNCTION(glDisablei, glDisableIndexedEXT); + MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB); + MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB); + MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB); + MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB); + MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT); + MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB); + MAP_GL_FUNCTION(glEndQuery, glEndQueryARB); + MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB); + MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB); + MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB); + MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB); + MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB); + MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB); + MAP_GL_FUNCTION(glGetBooleani_v, glGetBooleanIndexedvEXT); + MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB); + MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB); + MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB); + MAP_GL_FUNCTION(glGetIntegeri_v, glGetIntegerIndexedvEXT); + MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB); + MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB); + MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB); + MAP_GL_FUNCTION(glGetQueryObjectuiv, glGetQueryObjectuivARB); + MAP_GL_FUNCTION(glGetShaderInfoLog, glGetInfoLogARB); + MAP_GL_FUNCTION(glGetShaderiv, glGetObjectParameterivARB); + MAP_GL_FUNCTION(glGetShaderSource, glGetShaderSourceARB); + MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB); + MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB); + MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB); + MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT); + MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB); + MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB); + MAP_GL_FUNCTION(glMinSampleShading, glMinSampleShadingARB); + MAP_GL_FUNCTION(glPolygonOffsetClamp, glPolygonOffsetClampEXT); + MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB); + MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB); + MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT); + MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT); + MAP_GL_FUNCTION(glUniform1f, glUniform1fARB); + MAP_GL_FUNCTION(glUniform1fv, glUniform1fvARB); + MAP_GL_FUNCTION(glUniform1i, glUniform1iARB); + MAP_GL_FUNCTION(glUniform1iv, glUniform1ivARB); + MAP_GL_FUNCTION(glUniform2f, glUniform2fARB); + MAP_GL_FUNCTION(glUniform2fv, glUniform2fvARB); + MAP_GL_FUNCTION(glUniform2i, glUniform2iARB); + MAP_GL_FUNCTION(glUniform2iv, glUniform2ivARB); + MAP_GL_FUNCTION(glUniform3f, glUniform3fARB); + MAP_GL_FUNCTION(glUniform3fv, glUniform3fvARB); + MAP_GL_FUNCTION(glUniform3i, glUniform3iARB); + MAP_GL_FUNCTION(glUniform3iv, glUniform3ivARB); + MAP_GL_FUNCTION(glUniform4f, glUniform4fARB); + MAP_GL_FUNCTION(glUniform4fv, glUniform4fvARB); + MAP_GL_FUNCTION(glUniform4i, glUniform4iARB); + MAP_GL_FUNCTION(glUniform4iv, glUniform4ivARB); + MAP_GL_FUNCTION(glUniformMatrix2fv, glUniformMatrix2fvARB); + MAP_GL_FUNCTION(glUniformMatrix3fv, glUniformMatrix3fvARB); + MAP_GL_FUNCTION(glUniformMatrix4fv, glUniformMatrix4fvARB); + MAP_GL_FUNCTION(glUnmapBuffer, glUnmapBufferARB); + MAP_GL_FUNCTION(glUseProgram, glUseProgramObjectARB); + MAP_GL_FUNCTION(glValidateProgram, glValidateProgramARB); + MAP_GL_FUNCTION(glVertexAttrib1f, glVertexAttrib1fARB); + MAP_GL_FUNCTION(glVertexAttrib1fv, glVertexAttrib1fvARB); + MAP_GL_FUNCTION(glVertexAttrib2f, glVertexAttrib2fARB); + MAP_GL_FUNCTION(glVertexAttrib2fv, glVertexAttrib2fvARB); + MAP_GL_FUNCTION(glVertexAttrib3f, glVertexAttrib3fARB); + MAP_GL_FUNCTION(glVertexAttrib3fv, glVertexAttrib3fvARB); + MAP_GL_FUNCTION(glVertexAttrib4f, glVertexAttrib4fARB); + MAP_GL_FUNCTION(glVertexAttrib4fv, glVertexAttrib4fvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nsv, glVertexAttrib4NsvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nub, glVertexAttrib4NubARB); + MAP_GL_FUNCTION(glVertexAttrib4Nubv, glVertexAttrib4NubvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nusv, glVertexAttrib4NusvARB); + MAP_GL_FUNCTION(glVertexAttrib4sv, glVertexAttrib4svARB); + MAP_GL_FUNCTION(glVertexAttrib4ubv, glVertexAttrib4ubvARB); + MAP_GL_FUNCTION(glVertexAttribDivisor, glVertexAttribDivisorARB); + MAP_GL_FUNCTION(glVertexAttribIPointer, glVertexAttribIPointerEXT); + MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB); +#undef MAP_GL_FUNCTION +#undef MAP_GL_FUNCTION_CAST +} + +static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) +{ + unsigned int i, sampler_count; + GLint gl_max; + + gl_info->limits.buffers = 1; + gl_info->limits.textures = 0; + gl_info->limits.texture_coords = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + gl_info->limits.uniform_blocks[i] = 0; + gl_info->limits.samplers[i] = 0; + } + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = 1; + gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]; + gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers; + gl_info->limits.vertex_attribs = 16; + gl_info->limits.texture_buffer_offset_alignment = 1; + gl_info->limits.glsl_vs_float_constants = 0; + gl_info->limits.glsl_ps_float_constants = 0; + gl_info->limits.arb_vs_float_constants = 0; + gl_info->limits.arb_vs_native_constants = 0; + gl_info->limits.arb_vs_instructions = 0; + gl_info->limits.arb_vs_temps = 0; + gl_info->limits.arb_ps_float_constants = 0; + gl_info->limits.arb_ps_local_constants = 0; + gl_info->limits.arb_ps_instructions = 0; + gl_info->limits.arb_ps_temps = 0; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max); + gl_info->limits.user_clip_distances = min(WINED3D_MAX_CLIP_DISTANCES, gl_max); + TRACE("Clip plane support - max planes %d.\n", gl_max); + + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max); + gl_info->limits.lights = gl_max; + TRACE("Light support - max lights %d.\n", gl_max); + } + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max); + gl_info->limits.texture_size = gl_max; + TRACE("Maximum texture size support - max texture size %d.\n", gl_max); + + if (gl_info->supported[ARB_MAP_BUFFER_ALIGNMENT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &gl_max); + TRACE("Minimum buffer map alignment: %d.\n", gl_max); + } + else + { + WARN_(d3d_perf)("Driver doesn't guarantee a minimum buffer map alignment.\n"); + } + if (gl_info->supported[NV_REGISTER_COMBINERS]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max); + gl_info->limits.general_combiners = gl_max; + TRACE("Max general combiners: %d.\n", gl_max); + } + if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max); + gl_info->limits.buffers = min(MAX_RENDER_TARGET_VIEWS, gl_max); + TRACE("Max draw buffers: %u.\n", gl_max); + } + if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &gl_max); + gl_info->limits.dual_buffers = gl_max; + TRACE("Max dual source draw buffers: %u.\n", gl_max); + } + if (gl_info->supported[ARB_MULTITEXTURE]) + { + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max); + gl_info->limits.textures = min(WINED3D_MAX_TEXTURES, gl_max); + TRACE("Max textures: %d.\n", gl_info->limits.textures); + + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max); + gl_info->limits.texture_coords = min(WINED3D_MAX_TEXTURES, gl_max); + } + else + { + gl_info->limits.texture_coords = gl_info->limits.textures; + } + TRACE("Max texture coords: %d.\n", gl_info->limits.texture_coords); + } + + if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_max; + } + else + { + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_info->limits.textures; + } + TRACE("Max fragment samplers: %d.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]); + + if (gl_info->supported[ARB_VERTEX_SHADER]) + { + unsigned int vertex_sampler_count; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &gl_max); + vertex_sampler_count = gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = gl_max; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &gl_max); + gl_info->limits.combined_samplers = gl_max; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &gl_max); + gl_info->limits.vertex_attribs = gl_max; + + /* Loading GLSL sampler uniforms is much simpler if we can assume + * that the sampler setup is known at shader link time. In a + * vertex shader + pixel shader combination this isn't an issue + * because then the sampler setup only depends on the two shaders. + * If a pixel shader is used with fixed-function vertex processing + * we're fine too because fixed-function vertex processing doesn't + * use any samplers. If fixed-function fragment processing is used + * we have to make sure that all vertex sampler setups are valid + * together with all possible fixed-function fragment processing + * setups. This is true if vsamplers + WINED3D_MAX_TEXTURES <= max_samplers. + * This is true on all Direct3D 9 cards that support vertex + * texture fetch (GeForce 6 and GeForce 7 cards). Direct3D 9 + * Radeon cards do not support vertex texture fetch. Direct3D 10 + * cards have 128 samplers, and Direct3D 9 is limited to 8 + * fixed-function texture stages and 4 vertex samplers. + * Direct3D 10 does not have a fixed-function pipeline anymore. + * + * So this is just a check to check that our assumption holds + * true. If not, write a warning and reduce the number of vertex + * samplers or probably disable vertex texture fetch. */ + if (vertex_sampler_count && gl_info->limits.combined_samplers < 12 + && WINED3D_MAX_TEXTURES + vertex_sampler_count > gl_info->limits.combined_samplers) + { + FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n", + vertex_sampler_count, gl_info->limits.combined_samplers); + FIXME("Expected vertex samplers + WINED3D_MAX_TEXTURES(=8) > combined_samplers.\n"); + if (gl_info->limits.combined_samplers > WINED3D_MAX_TEXTURES) + vertex_sampler_count = gl_info->limits.combined_samplers - WINED3D_MAX_TEXTURES; + else + vertex_sampler_count = 0; + gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = vertex_sampler_count; + } + } + else + { + gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]; + } + TRACE("Max vertex samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]); + TRACE("Max combined samplers: %u.\n", gl_info->limits.combined_samplers); + TRACE("Max vertex attributes: %u.\n", gl_info->limits.vertex_attribs); + } + else + { + gl_info->limits.textures = 1; + gl_info->limits.texture_coords = 1; + } + + if (gl_info->supported[EXT_TEXTURE3D]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max); + gl_info->limits.texture3d_size = gl_max; + TRACE("Max texture3D size: %d.\n", gl_info->limits.texture3d_size); + } + if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &gl_max); + gl_info->limits.anisotropy = gl_max; + TRACE("Max anisotropy: %d.\n", gl_info->limits.anisotropy); + } + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) + { + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); + gl_info->limits.arb_ps_float_constants = gl_max; + TRACE("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants); + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max)); + gl_info->limits.arb_ps_native_constants = gl_max; + TRACE("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n", + gl_info->limits.arb_ps_native_constants); + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max)); + gl_info->limits.arb_ps_temps = gl_max; + TRACE("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps); + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max)); + gl_info->limits.arb_ps_instructions = gl_max; + TRACE("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions); + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max)); + gl_info->limits.arb_ps_local_constants = gl_max; + TRACE("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions); + } + if (gl_info->supported[ARB_VERTEX_PROGRAM]) + { + GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); + gl_info->limits.arb_vs_float_constants = gl_max; + TRACE("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants); + GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max)); + gl_info->limits.arb_vs_native_constants = gl_max; + TRACE("Max ARB_VERTEX_PROGRAM native float constants: %d.\n", + gl_info->limits.arb_vs_native_constants); + GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max)); + gl_info->limits.arb_vs_temps = gl_max; + TRACE("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps); + GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max)); + gl_info->limits.arb_vs_instructions = gl_max; + TRACE("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions); + } + if (gl_info->supported[ARB_VERTEX_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max); + gl_info->limits.glsl_vs_float_constants = gl_max / 4; + TRACE("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants); + + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max vertex uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gl_max); + gl_info->limits.glsl_max_uniform_block_size = gl_max; + TRACE("Max uniform block size %u.\n", gl_max); + } + } + if (gl_info->supported[ARB_TESSELLATION_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max hull uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL] = gl_max; + TRACE("Max hull samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL]); + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max domain uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN] = gl_max; + TRACE("Max domain samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN]); + } + if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max geometry uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY] = gl_max; + TRACE("Max geometry samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY]); + } + if (gl_info->supported[ARB_FRAGMENT_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max); + gl_info->limits.glsl_ps_float_constants = gl_max / 4; + TRACE("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants); + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max); + gl_info->limits.glsl_varyings = gl_max; + } + else + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &gl_max); + gl_info->limits.glsl_varyings = gl_max - 4; + } + TRACE("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_info->limits.glsl_varyings, + gl_info->limits.glsl_varyings / 4); + + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max fragment uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL], gl_max); + } + } + if (gl_info->supported[ARB_COMPUTE_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max compute uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE] = gl_max; + TRACE("Max compute samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]); + } + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &gl_max); + TRACE("Max combined uniform blocks: %d.\n", gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_max); + TRACE("Max uniform buffer bindings: %d.\n", gl_max); + } + if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_max); + gl_info->limits.texture_buffer_offset_alignment = gl_max; + TRACE("Minimum required texture buffer offset alignment %d.\n", gl_max); + } + if (gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS]) + { + GLint max_fragment_buffers, max_combined_buffers, max_bindings; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_fragment_buffers); + TRACE("Max fragment atomic counter buffers: %d.\n", max_fragment_buffers); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, &max_combined_buffers); + TRACE("Max combined atomic counter buffers: %d.\n", max_combined_buffers); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings); + TRACE("Max atomic counter buffer bindings: %d.\n", max_bindings); + if (max_fragment_buffers < MAX_UNORDERED_ACCESS_VIEWS + || max_combined_buffers < MAX_UNORDERED_ACCESS_VIEWS + || max_bindings < MAX_UNORDERED_ACCESS_VIEWS) + { + WARN("Disabling ARB_shader_atomic_counters.\n"); + gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS] = FALSE; + } + } + if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_STREAMS, &gl_max); + TRACE("Max vertex streams: %d.\n", gl_max); + } + + if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) + gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess); + else + gl_info->limits.shininess = 128.0f; + + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_SAMPLES, &gl_max); + gl_info->limits.samples = gl_max; + } + + if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &gl_max); + gl_info->limits.framebuffer_width = gl_max; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &gl_max); + gl_info->limits.framebuffer_height = gl_max; + } + else + { + gl_info->limits.framebuffer_width = gl_info->limits.texture_size; + gl_info->limits.framebuffer_height = gl_info->limits.texture_size; + } + + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = + min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS); + sampler_count = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + sampler_count += gl_info->limits.samplers[i]; + if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->limits.combined_samplers < sampler_count) + { + /* The minimum value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS in OpenGL + * 3.2 is 48 (16 per stage). When tessellation shaders are supported + * the minimum value is increased to 80. */ + WARN("Graphics pipeline sampler count %u is greater than combined sampler count %u.\n", + sampler_count, gl_info->limits.combined_samplers); + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + gl_info->limits.samplers[i] = min(gl_info->limits.samplers[i], 16); + } + + /* A majority of OpenGL implementations allow us to statically partition + * the set of texture bindings into six separate sets. */ + gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers; + sampler_count = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + sampler_count += gl_info->limits.samplers[i]; + if (gl_info->limits.combined_samplers >= sampler_count) + gl_info->limits.graphics_samplers -= gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]; +} + +/* Context activation is done by the caller. */ +static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, + struct wined3d_caps_gl_ctx *caps_gl_ctx, unsigned int wined3d_creation_flags) +{ + static const struct + { + enum wined3d_gl_extension extension; + DWORD min_gl_version; + } + core_extensions[] = + { + {EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2)}, + {ARB_MULTISAMPLE, MAKEDWORD_VERSION(1, 3)}, + {ARB_MULTITEXTURE, MAKEDWORD_VERSION(1, 3)}, + {ARB_TEXTURE_BORDER_CLAMP, MAKEDWORD_VERSION(1, 3)}, + {ARB_TEXTURE_COMPRESSION, MAKEDWORD_VERSION(1, 3)}, + {ARB_TEXTURE_CUBE_MAP, MAKEDWORD_VERSION(1, 3)}, + {ARB_DEPTH_TEXTURE, MAKEDWORD_VERSION(1, 4)}, + {ARB_POINT_PARAMETERS, MAKEDWORD_VERSION(1, 4)}, + {ARB_SHADOW, MAKEDWORD_VERSION(1, 4)}, + {ARB_TEXTURE_MIRRORED_REPEAT, MAKEDWORD_VERSION(1, 4)}, + {EXT_BLEND_COLOR, MAKEDWORD_VERSION(1, 4)}, + {EXT_BLEND_FUNC_SEPARATE, MAKEDWORD_VERSION(1, 4)}, + {EXT_BLEND_MINMAX, MAKEDWORD_VERSION(1, 4)}, + {EXT_BLEND_SUBTRACT, MAKEDWORD_VERSION(1, 4)}, + {EXT_STENCIL_WRAP, MAKEDWORD_VERSION(1, 4)}, + {NV_POINT_SPRITE, MAKEDWORD_VERSION(1, 4)}, + {ARB_OCCLUSION_QUERY, MAKEDWORD_VERSION(1, 5)}, + {ARB_VERTEX_BUFFER_OBJECT, MAKEDWORD_VERSION(1, 5)}, + {ARB_DRAW_BUFFERS, MAKEDWORD_VERSION(2, 0)}, + {ARB_FRAGMENT_SHADER, MAKEDWORD_VERSION(2, 0)}, + {ARB_SHADING_LANGUAGE_100, MAKEDWORD_VERSION(2, 0)}, + {ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0)}, + {ARB_VERTEX_SHADER, MAKEDWORD_VERSION(2, 0)}, + {EXT_BLEND_EQUATION_SEPARATE, MAKEDWORD_VERSION(2, 0)}, + {ARB_PIXEL_BUFFER_OBJECT, MAKEDWORD_VERSION(2, 1)}, + {EXT_TEXTURE_SRGB, MAKEDWORD_VERSION(2, 1)}, + {ARB_COLOR_BUFFER_FLOAT, MAKEDWORD_VERSION(3, 0)}, + {ARB_DEPTH_BUFFER_FLOAT, MAKEDWORD_VERSION(3, 0)}, + {ARB_FRAMEBUFFER_OBJECT, MAKEDWORD_VERSION(3, 0)}, + {ARB_FRAMEBUFFER_SRGB, MAKEDWORD_VERSION(3, 0)}, + {ARB_HALF_FLOAT_PIXEL, MAKEDWORD_VERSION(3, 0)}, + {ARB_HALF_FLOAT_VERTEX, MAKEDWORD_VERSION(3, 0)}, + {ARB_MAP_BUFFER_RANGE, MAKEDWORD_VERSION(3, 0)}, + {ARB_TEXTURE_COMPRESSION_RGTC, MAKEDWORD_VERSION(3, 0)}, + {ARB_TEXTURE_FLOAT, MAKEDWORD_VERSION(3, 0)}, + {ARB_TEXTURE_RG, MAKEDWORD_VERSION(3, 0)}, + {EXT_DRAW_BUFFERS2, MAKEDWORD_VERSION(3, 0)}, + {EXT_PACKED_FLOAT, MAKEDWORD_VERSION(3, 0)}, + {EXT_TEXTURE_ARRAY, MAKEDWORD_VERSION(3, 0)}, + {EXT_TEXTURE_INTEGER, MAKEDWORD_VERSION(3, 0)}, + {EXT_TEXTURE_SHARED_EXPONENT, MAKEDWORD_VERSION(3, 0)}, + /* We don't want to enable EXT_GPU_SHADER4: even though similar + * functionality is available in core GL 3.0 / GLSL 1.30, it's different + * enough that reusing the same flag for the new features hurts more + * than it helps. */ + /* EXT_framebuffer_object, EXT_framebuffer_blit, + * EXT_framebuffer_multisample and EXT_packed_depth_stencil + * are integrated into ARB_framebuffer_object. */ + + {ARB_COPY_BUFFER, MAKEDWORD_VERSION(3, 1)}, + {ARB_DRAW_INSTANCED, MAKEDWORD_VERSION(3, 1)}, + {ARB_TEXTURE_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)}, + {ARB_UNIFORM_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)}, + {EXT_TEXTURE_SNORM, MAKEDWORD_VERSION(3, 1)}, + /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */ + + {ARB_DEPTH_CLAMP, MAKEDWORD_VERSION(3, 2)}, + {ARB_DRAW_ELEMENTS_BASE_VERTEX, MAKEDWORD_VERSION(3, 2)}, + /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2 + * core geometry shaders so it's not really correct to expose the + * extension for core-only support. */ + {ARB_FRAGMENT_COORD_CONVENTIONS, MAKEDWORD_VERSION(3, 2)}, + {ARB_PROVOKING_VERTEX, MAKEDWORD_VERSION(3, 2)}, + {ARB_SEAMLESS_CUBE_MAP, MAKEDWORD_VERSION(3, 2)}, + {ARB_SYNC, MAKEDWORD_VERSION(3, 2)}, + {ARB_TEXTURE_MULTISAMPLE, MAKEDWORD_VERSION(3, 2)}, + {ARB_VERTEX_ARRAY_BGRA, MAKEDWORD_VERSION(3, 2)}, + + {ARB_BLEND_FUNC_EXTENDED, MAKEDWORD_VERSION(3, 3)}, + {ARB_EXPLICIT_ATTRIB_LOCATION, MAKEDWORD_VERSION(3, 3)}, + {ARB_INSTANCED_ARRAYS, MAKEDWORD_VERSION(3, 3)}, + {ARB_SAMPLER_OBJECTS, MAKEDWORD_VERSION(3, 3)}, + {ARB_SHADER_BIT_ENCODING, MAKEDWORD_VERSION(3, 3)}, + {ARB_TEXTURE_RGB10_A2UI, MAKEDWORD_VERSION(3, 3)}, + {ARB_TEXTURE_SWIZZLE, MAKEDWORD_VERSION(3, 3)}, + {ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)}, + {ARB_VERTEX_TYPE_2_10_10_10_REV, MAKEDWORD_VERSION(3, 3)}, + + {ARB_DRAW_INDIRECT, MAKEDWORD_VERSION(4, 0)}, + {ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)}, + {ARB_SAMPLE_SHADING, MAKEDWORD_VERSION(4, 0)}, + {ARB_TESSELLATION_SHADER, MAKEDWORD_VERSION(4, 0)}, + {ARB_TEXTURE_CUBE_MAP_ARRAY, MAKEDWORD_VERSION(4, 0)}, + {ARB_TEXTURE_GATHER, MAKEDWORD_VERSION(4, 0)}, + {ARB_TRANSFORM_FEEDBACK2, MAKEDWORD_VERSION(4, 0)}, + {ARB_TRANSFORM_FEEDBACK3, MAKEDWORD_VERSION(4, 0)}, + + {ARB_ES2_COMPATIBILITY, MAKEDWORD_VERSION(4, 1)}, + {ARB_VIEWPORT_ARRAY, MAKEDWORD_VERSION(4, 1)}, + + {ARB_BASE_INSTANCE, MAKEDWORD_VERSION(4, 2)}, + {ARB_CONSERVATIVE_DEPTH, MAKEDWORD_VERSION(4, 2)}, + {ARB_INTERNALFORMAT_QUERY, MAKEDWORD_VERSION(4, 2)}, + {ARB_MAP_BUFFER_ALIGNMENT, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADER_ATOMIC_COUNTERS, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADER_IMAGE_LOAD_STORE, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADING_LANGUAGE_420PACK, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADING_LANGUAGE_PACKING, MAKEDWORD_VERSION(4, 2)}, + {ARB_TEXTURE_COMPRESSION_BPTC, MAKEDWORD_VERSION(4, 2)}, + {ARB_TEXTURE_STORAGE, MAKEDWORD_VERSION(4, 2)}, + + {ARB_CLEAR_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)}, + {ARB_COMPUTE_SHADER, MAKEDWORD_VERSION(4, 3)}, + {ARB_COPY_IMAGE, MAKEDWORD_VERSION(4, 3)}, + {ARB_DEBUG_OUTPUT, MAKEDWORD_VERSION(4, 3)}, + {ARB_ES3_COMPATIBILITY, MAKEDWORD_VERSION(4, 3)}, + {ARB_FRAGMENT_LAYER_VIEWPORT, MAKEDWORD_VERSION(4, 3)}, + {ARB_FRAMEBUFFER_NO_ATTACHMENTS, MAKEDWORD_VERSION(4, 3)}, + {ARB_INTERNALFORMAT_QUERY2, MAKEDWORD_VERSION(4, 3)}, + {ARB_SHADER_IMAGE_SIZE, MAKEDWORD_VERSION(4, 3)}, + {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)}, + {ARB_STENCIL_TEXTURING, MAKEDWORD_VERSION(4, 3)}, + {ARB_TEXTURE_BUFFER_RANGE, MAKEDWORD_VERSION(4, 3)}, + {ARB_TEXTURE_QUERY_LEVELS, MAKEDWORD_VERSION(4, 3)}, + {ARB_TEXTURE_STORAGE_MULTISAMPLE, MAKEDWORD_VERSION(4, 2)}, + {ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)}, + + {ARB_BUFFER_STORAGE, MAKEDWORD_VERSION(4, 4)}, + {ARB_CLEAR_TEXTURE, MAKEDWORD_VERSION(4, 4)}, + {ARB_QUERY_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 4)}, + {ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE, MAKEDWORD_VERSION(4, 4)}, + + {ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)}, + {ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)}, + {ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)}, + {ARB_SHADER_TEXTURE_IMAGE_SAMPLES, MAKEDWORD_VERSION(4, 5)}, + + {ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)}, + {ARB_POLYGON_OFFSET_CLAMP, MAKEDWORD_VERSION(4, 6)}, + {ARB_TEXTURE_FILTER_ANISOTROPIC, MAKEDWORD_VERSION(4, 6)}, + }; + struct wined3d_driver_info *driver_info = &adapter->driver_info; + const char *gl_vendor_str, *gl_renderer_str, *gl_version_str; + const struct wined3d_gpu_description *gpu_description; + struct wined3d_gl_info *gl_info = &adapter->gl_info; + const char *WGL_Extensions = NULL; + enum wined3d_gl_vendor gl_vendor; + DWORD gl_version, gl_ext_emul_mask; + GLint context_profile = 0; + UINT64 vram_bytes = 0; + unsigned int i, j; + HDC hdc; + + TRACE("adapter %p.\n", adapter); + + gl_renderer_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER); + TRACE("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str)); + if (!gl_renderer_str) + { + ERR("Received a NULL GL_RENDERER.\n"); + return FALSE; + } + + gl_vendor_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR); + TRACE("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str)); + if (!gl_vendor_str) + { + ERR("Received a NULL GL_VENDOR.\n"); + return FALSE; + } + + /* Parse the GL_VERSION field into major and minor information */ + gl_version_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VERSION); + TRACE("GL_VERSION: %s.\n", debugstr_a(gl_version_str)); + if (!gl_version_str) + { + ERR("Received a NULL GL_VERSION.\n"); + return FALSE; + } + gl_version = wined3d_parse_gl_version(gl_version_str); + + load_gl_funcs(gl_info); + + memset(gl_info->supported, 0, sizeof(gl_info->supported)); + gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE; + + if (gl_version >= MAKEDWORD_VERSION(3, 2)) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile); + checkGLcall("Querying context profile"); + } + if (context_profile & GL_CONTEXT_CORE_PROFILE_BIT) + TRACE("Got a core profile context.\n"); + else + gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] = TRUE; + + TRACE("GL extensions reported:\n"); + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS); + + if (!gl_extensions) + { + ERR("Received a NULL GL_EXTENSIONS.\n"); + return FALSE; + } + parse_extension_string(gl_info, gl_extensions, gl_extension_map, ARRAY_SIZE(gl_extension_map)); + } + else + { + enumerate_gl_extensions(gl_info, gl_extension_map, ARRAY_SIZE(gl_extension_map)); + } + + hdc = wglGetCurrentDC(); + /* Not all GL drivers might offer WGL extensions e.g. VirtualBox. */ + if (GL_EXTCALL(wglGetExtensionsStringARB)) + WGL_Extensions = (const char *)GL_EXTCALL(wglGetExtensionsStringARB(hdc)); + if (!WGL_Extensions) + WARN("WGL extensions not supported.\n"); + else + parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map, ARRAY_SIZE(wgl_extension_map)); + + for (i = 0; i < ARRAY_SIZE(core_extensions); ++i) + { + if (!gl_info->supported[core_extensions[i].extension] + && gl_version >= core_extensions[i].min_gl_version) + { + for (j = 0; j < ARRAY_SIZE(gl_extension_map); ++j) + if (gl_extension_map[j].extension == core_extensions[i].extension) + break; + + if (j < ARRAY_SIZE(gl_extension_map)) + { + TRACE("GL CORE: %s support.\n", gl_extension_map[j].extension_string); + gl_info->supported[core_extensions[i].extension] = TRUE; + } + else + { + FIXME("GL extension %u not in the GL extensions map.\n", core_extensions[i].extension); + } + } + } + + if (gl_info->supported[EXT_BLEND_MINMAX] || gl_info->supported[EXT_BLEND_SUBTRACT]) + gl_info->supported[WINED3D_GL_BLEND_EQUATION] = TRUE; + + if (gl_version >= MAKEDWORD_VERSION(2, 0)) + { + gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE; + /* We want to use the core APIs for two-sided stencil in GL 2.0. */ + gl_info->supported[EXT_STENCIL_TWO_SIDE] = FALSE; + } + if (gl_version >= MAKEDWORD_VERSION(3, 2)) + gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE; + + /* All the points are actually point sprites in core contexts, the APIs from + * ARB_point_sprite are not supported anymore. */ + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + gl_info->supported[ARB_POINT_SPRITE] = FALSE; + + if (gl_info->supported[APPLE_FENCE]) + { + /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically. + * The apple extension interacts with some other apple exts. Disable the NV + * extension if the apple one is support to prevent confusion in other parts + * of the code. */ + gl_info->supported[NV_FENCE] = FALSE; + } + if (gl_info->supported[APPLE_FLOAT_PIXELS]) + { + /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel + * + * The enums are the same: + * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881a + * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881b + * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814 + * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815 + * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140b + */ + if (!gl_info->supported[ARB_TEXTURE_FLOAT]) + { + TRACE(" IMPLIED: GL_ARB_texture_float support (by GL_APPLE_float_pixels).\n"); + gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE; + } + if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) + { + TRACE(" IMPLIED: GL_ARB_half_float_pixel support (by GL_APPLE_float_pixels).\n"); + gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE; + } + } + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same + * functionality. Prefer the ARB extension */ + gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE; + } + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + TRACE(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n"); + gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE; + } + if (!gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC]) + { + TRACE(" IMPLIED: EXT_texture_compression_rgtc support (by ARB_texture_compression_rgtc).\n"); + gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC] = TRUE; + } + if (!gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC]) + { + TRACE(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n"); + gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = TRUE; + } + if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && !gl_info->supported[ARB_TEXTURE_RG]) + { + TRACE("ARB_texture_rg not supported, disabling ARB_texture_compression_rgtc.\n"); + gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = FALSE; + } + if (gl_info->supported[NV_TEXTURE_SHADER2]) + { + if (gl_info->supported[NV_REGISTER_COMBINERS]) + { + /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2 + * are supported. The nv extensions provide the same functionality as the + * ATI one, and a bit more(signed pixelformats). */ + gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE; + } + } + if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + { + /* If we have full NP2 texture support, disable + * GL_ARB_texture_rectangle because we will never use it. + * This saves a few redundant glDisable calls. */ + gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE; + } + if (gl_info->supported[ATI_FRAGMENT_SHADER]) + { + /* Disable NV_register_combiners and fragment shader if this is supported. + * generally the NV extensions are preferred over the ATI ones, and this + * extension is disabled if register_combiners and texture_shader2 are both + * supported. So we reach this place only if we have incomplete NV dxlevel 8 + * fragment processing support. */ + gl_info->supported[NV_REGISTER_COMBINERS] = FALSE; + gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE; + gl_info->supported[NV_TEXTURE_SHADER] = FALSE; + gl_info->supported[NV_TEXTURE_SHADER2] = FALSE; + } + if (gl_info->supported[NV_HALF_FLOAT]) + { + /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */ + gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE; + } + if (gl_info->supported[ARB_FRAMEBUFFER_SRGB] && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + { + /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode + * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode + * we never render to sRGB surfaces). */ + TRACE("EXT_texture_sRGB_decode is not supported, disabling ARB_framebuffer_sRGB.\n"); + gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE; + } + if (gl_info->supported[ARB_OCCLUSION_QUERY]) + { + GLint counter_bits; + + GL_EXTCALL(glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &counter_bits)); + TRACE("Occlusion query counter has %d bits.\n", counter_bits); + if (!counter_bits) + gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE; + } + if (gl_info->supported[ARB_TIMER_QUERY]) + { + GLint counter_bits; + + GL_EXTCALL(glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &counter_bits)); + TRACE("Timestamp query counter has %d bits.\n", counter_bits); + if (!counter_bits) + gl_info->supported[ARB_TIMER_QUERY] = FALSE; + } + if (gl_version >= MAKEDWORD_VERSION(3, 0)) + { + GLint counter_bits; + + gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = TRUE; + + GL_EXTCALL(glGetQueryiv(GL_PRIMITIVES_GENERATED, GL_QUERY_COUNTER_BITS, &counter_bits)); + TRACE("Primitives query counter has %d bits.\n", counter_bits); + if (!counter_bits) + gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE; + + GL_EXTCALL(glGetQueryiv(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_QUERY_COUNTER_BITS, &counter_bits)); + TRACE("Transform feedback primitives query counter has %d bits.\n", counter_bits); + if (!counter_bits) + gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE; + } + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + GLint subpixel_bits; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &subpixel_bits); + TRACE("Viewport supports %d subpixel bits.\n", subpixel_bits); + if (subpixel_bits < 8 && gl_info->supported[ARB_CLIP_CONTROL]) + { + TRACE("Disabling ARB_clip_control because viewport subpixel bits < 8.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } + } + if (gl_info->supported[ARB_CLIP_CONTROL] && !gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + /* When using ARB_clip_control we need the float viewport parameters + * introduced by ARB_viewport_array to take care of the shifted pixel + * coordinates. */ + TRACE("Disabling ARB_clip_control because ARB_viewport_array is not supported.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } + if (gl_info->supported[ARB_STENCIL_TEXTURING] && !gl_info->supported[ARB_TEXTURE_SWIZZLE]) + { + /* The stencil value needs to be placed in the green channel. */ + TRACE("Disabling ARB_stencil_texturing because ARB_texture_swizzle is not supported.\n"); + gl_info->supported[ARB_STENCIL_TEXTURING] = FALSE; + } + if (!gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] && gl_info->supported[EXT_TEXTURE_MIRROR_CLAMP]) + { + TRACE(" IMPLIED: ATI_texture_mirror_once support (by EXT_texture_mirror_clamp).\n"); + gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE; + } + if (!gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] && gl_info->supported[ATI_TEXTURE_MIRROR_ONCE]) + { + TRACE(" IMPLIED: ARB_texture_mirror_clamp_to_edge support (by ATI_texture_mirror_once).\n"); + gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] = TRUE; + } + if (gl_info->supported[ARB_TEXTURE_STORAGE] && gl_info->supported[APPLE_YCBCR_422]) + { + /* AFAIK APPLE_ycbcr_422 is only available in legacy contexts so we shouldn't ever hit this. */ + ERR("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n"); + gl_info->supported[APPLE_YCBCR_422] = FALSE; + } + if (gl_info->supported[ARB_DRAW_INDIRECT] && !gl_info->supported[ARB_BASE_INSTANCE]) + { + /* If ARB_base_instance is not supported the baseInstance field + * in indirect draw parameters must be 0 or behavior is undefined. + */ + WARN("Disabling ARB_draw_indirect because ARB_base_instance is not supported.\n"); + gl_info->supported[ARB_DRAW_INDIRECT] = FALSE; + } + if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !wined3d_settings.multisample_textures) + gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE; + if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !gl_info->supported[ARB_TEXTURE_STORAGE_MULTISAMPLE]) + { + WARN("Disabling ARB_texture_multisample because immutable storage is not supported.\n"); + gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE; + } + + wined3d_adapter_init_limits(gl_info); + + if (gl_info->supported[ARB_VERTEX_PROGRAM] && test_arb_vs_offset_limit(gl_info)) + gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT; + + if (gl_info->supported[ARB_SHADING_LANGUAGE_100]) + { + const char *str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); + unsigned int major, minor; + + TRACE("GLSL version string: %s.\n", debugstr_a(str)); + + /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */ + sscanf(str, "%u.%u", &major, &minor); + gl_info->glsl_version = MAKEDWORD_VERSION(major, minor); + if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30)) + gl_info->supported[WINED3D_GLSL_130] = TRUE; + } + + checkGLcall("extension detection"); + + adapter->shader_backend = select_shader_backend(gl_info); + adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend); + adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend); + + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) + { + gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbuffer; + gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbuffer; + gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffers; + gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffers; + gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorage; + gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisample; + gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameteriv; + gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebuffer; + gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebuffer; + gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffers; + gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffers; + gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatus; + gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D; + gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D; + gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3D; + gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayer; + gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer; + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv + = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv; + gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer; + gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap; + gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture; + } + else + { + if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) + { + gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbufferEXT; + gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbufferEXT; + gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffersEXT; + gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffersEXT; + gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorageEXT; + gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameterivEXT; + gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebufferEXT; + gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebufferEXT; + gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffersEXT; + gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffersEXT; + gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatusEXT; + gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1DEXT; + gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2DEXT; + gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3DEXT; + gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbufferEXT; + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv + = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameterivEXT; + gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmapEXT; + } + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n"); + wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; + } + + if (gl_info->supported[ARB_GEOMETRY_SHADER4]) + { + gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB; + gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB; + } + if (gl_info->supported[EXT_FRAMEBUFFER_BLIT]) + { + gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT; + } + if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) + { + gl_info->fbo_ops.glRenderbufferStorageMultisample + = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisampleEXT; + } + } + + gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT; + gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] = + gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT; + gl_info->wrap_lookup[WINED3D_TADDRESS_CLAMP - WINED3D_TADDRESS_WRAP] = GL_CLAMP_TO_EDGE; + gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] = + gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT; + gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] = + gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] ? GL_MIRROR_CLAMP_TO_EDGE : GL_REPEAT; + + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + GLuint vao; + + GL_EXTCALL(glGenVertexArrays(1, &vao)); + GL_EXTCALL(glBindVertexArray(vao)); + checkGLcall("creating VAO"); + } + + gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str, gl_version_str); + TRACE("Guessed GL vendor %#x.\n", gl_vendor); + + if (!(gpu_description = query_gpu_description(gl_info, &vram_bytes))) + { + enum wined3d_feature_level feature_level; + struct fragment_caps fragment_caps; + enum wined3d_pci_vendor vendor; + enum wined3d_pci_device device; + struct shader_caps shader_caps; + + adapter->shader_backend->shader_get_caps(adapter, &shader_caps); + adapter->fragment_pipe->get_caps(adapter, &fragment_caps); + feature_level = feature_level_from_caps(gl_info, &shader_caps, &fragment_caps); + + vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str); + TRACE("Guessed vendor PCI ID 0x%04x.\n", vendor); + + device = wined3d_guess_card(feature_level, gl_renderer_str, &gl_vendor, &vendor); + TRACE("Guessed device PCI ID 0x%04x.\n", device); + + if (!(gpu_description = wined3d_get_gpu_description(vendor, device))) + { + ERR("Card %04x:%04x not found in driver DB.\n", vendor, device); + return FALSE; + } + } + fixup_extensions(gl_info, caps_gl_ctx, gl_renderer_str, gl_vendor, + gpu_description->vendor, gpu_description->device); + wined3d_driver_info_init(driver_info, gpu_description, vram_bytes, 0); + TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n", + driver_info->version_high, driver_info->version_low); + + adapter->vram_bytes_used = 0; + TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(driver_info->vram_bytes)); + + if (gl_info->supported[EXT_MEMORY_OBJECT]) + { + GLint device_count = 0; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_DEVICE_UUIDS_EXT, &device_count); + if (device_count > 0) + { + if (device_count > 1) + FIXME("A set of %d devices is not supported.\n", device_count); + + GL_EXTCALL(glGetUnsignedBytevEXT(GL_DRIVER_UUID_EXT, (GLubyte *)&adapter->driver_uuid)); + GL_EXTCALL(glGetUnsignedBytei_vEXT(GL_DEVICE_UUID_EXT, 0, (GLubyte *)&adapter->device_uuid)); + + TRACE("Driver UUID: %s, device UUID %s.\n", + debugstr_guid(&adapter->driver_uuid), debugstr_guid(&adapter->device_uuid)); + } + else + { + WARN("Unexpected device count %d.\n", device_count); + } + } + + gl_ext_emul_mask = adapter->vertex_pipe->vp_get_emul_mask(gl_info) + | adapter->fragment_pipe->get_emul_mask(gl_info); + if (gl_ext_emul_mask & GL_EXT_EMUL_ARB_MULTITEXTURE) + install_gl_compat_wrapper(gl_info, ARB_MULTITEXTURE); + if (gl_ext_emul_mask & GL_EXT_EMUL_EXT_FOG_COORD) + install_gl_compat_wrapper(gl_info, EXT_FOG_COORD); + + return TRUE; +} + +static void WINE_GLAPI invalid_func(const void *data) +{ + ERR("Invalid vertex attribute function called.\n"); + DebugBreak(); +} + +static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data) +{ + ERR("Invalid texcoord function called.\n"); + DebugBreak(); +} + +static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data) +{ + ERR("Invalid attribute function called.\n"); + DebugBreak(); +} + +/* Helper functions for providing vertex data to OpenGL. The arrays are + * initialised based on the extension detection and are used in + * draw_primitive_immediate_mode(). */ +static void WINE_GLAPI position_d3dcolor(const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + DWORD pos = *((const DWORD *)data); + + FIXME("Add a test for fixed function position from d3dcolor type.\n"); + gl_info->gl_ops.gl.p_glVertex4s(D3DCOLOR_B_R(pos), + D3DCOLOR_B_G(pos), + D3DCOLOR_B_B(pos), + D3DCOLOR_B_A(pos)); +} + +static void WINE_GLAPI position_float4(const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + const GLfloat *pos = data; + + if (pos[3] != 0.0f && pos[3] != 1.0f) + { + float w = 1.0f / pos[3]; + + gl_info->gl_ops.gl.p_glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w); + } + else + { + gl_info->gl_ops.gl.p_glVertex3fv(pos); + } +} + +static void WINE_GLAPI diffuse_d3dcolor(const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + DWORD diffuseColor = *((const DWORD *)data); + + gl_info->gl_ops.gl.p_glColor4ub(D3DCOLOR_B_R(diffuseColor), + D3DCOLOR_B_G(diffuseColor), + D3DCOLOR_B_B(diffuseColor), + D3DCOLOR_B_A(diffuseColor)); +} + +static void WINE_GLAPI specular_d3dcolor(const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + DWORD specularColor = *((const DWORD *)data); + GLubyte d[] = + { + D3DCOLOR_B_R(specularColor), + D3DCOLOR_B_G(specularColor), + D3DCOLOR_B_B(specularColor) + }; + + gl_info->gl_ops.ext.p_glSecondaryColor3ubvEXT(d); +} + +static void WINE_GLAPI warn_no_specular_func(const void *data) +{ + WARN("GL_EXT_secondary_color not supported.\n"); +} + +static void WINE_GLAPI generic_d3dcolor(GLuint idx, const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + DWORD color = *((const DWORD *)data); + + gl_info->gl_ops.ext.p_glVertexAttrib4Nub(idx, + D3DCOLOR_B_R(color), D3DCOLOR_B_G(color), + D3DCOLOR_B_B(color), D3DCOLOR_B_A(color)); +} + +static void WINE_GLAPI generic_short2n(GLuint idx, const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + const GLshort s[] = {((const GLshort *)data)[0], ((const GLshort *)data)[1], 0, 1}; + + gl_info->gl_ops.ext.p_glVertexAttrib4Nsv(idx, s); +} + +static void WINE_GLAPI generic_ushort2n(GLuint idx, const void *data) +{ + const GLushort s[] = {((const GLushort *)data)[0], ((const GLushort *)data)[1], 0, 1}; + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + + gl_info->gl_ops.ext.p_glVertexAttrib4Nusv(idx, s); +} + +static void WINE_GLAPI generic_float16_2(GLuint idx, const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + float x = float_16_to_32(((const unsigned short *)data) + 0); + float y = float_16_to_32(((const unsigned short *)data) + 1); + + gl_info->gl_ops.ext.p_glVertexAttrib2f(idx, x, y); +} + +static void WINE_GLAPI generic_float16_4(GLuint idx, const void *data) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl_get_current()->gl_info; + float x = float_16_to_32(((const unsigned short *)data) + 0); + float y = float_16_to_32(((const unsigned short *)data) + 1); + float z = float_16_to_32(((const unsigned short *)data) + 2); + float w = float_16_to_32(((const unsigned short *)data) + 3); + + gl_info->gl_ops.ext.p_glVertexAttrib4f(idx, x, y, z, w); +} + +static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter) +{ + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; + struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops; + unsigned int i; + + for (i = 0; i < WINED3D_FFP_EMIT_COUNT; ++i) + { + ops->position[i] = invalid_func; + ops->diffuse[i] = invalid_func; + ops->specular[i] = invalid_func; + ops->normal[i] = invalid_func; + ops->texcoord[i] = invalid_texcoord_func; + ops->generic[i] = invalid_generic_attrib_func; + } + + ops->position[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex3fv; + if (!d3d_info->xyzrhw) + ops->position[WINED3D_FFP_EMIT_FLOAT4] = position_float4; + else + ops->position[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex4fv; + ops->position[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor; + ops->position[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex2sv; + + ops->diffuse[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor3fv; + ops->diffuse[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4fv; + ops->diffuse[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor; + ops->diffuse[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4ubv; + ops->diffuse[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4sv; + ops->diffuse[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4usv; + + /* No 4 component entry points here. */ + if (gl_info->supported[EXT_SECONDARY_COLOR]) + ops->specular[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)GL_EXTCALL(glSecondaryColor3fvEXT); + else + ops->specular[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func; + if (gl_info->supported[EXT_SECONDARY_COLOR]) + ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor; + else + ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func; + + /* Only 3 component entry points here. Test how others behave. Float4 + * normals are used by one of our tests, trying to pass it to the pixel + * shader, which fails on Windows. */ + ops->normal[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv; + /* Just ignore the 4th value. */ + ops->normal[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv; + + ops->texcoord[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB; + ops->texcoord[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB; + ops->texcoord[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB; + ops->texcoord[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB; + ops->texcoord[WINED3D_FFP_EMIT_SHORT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2svARB; + ops->texcoord[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4svARB; + if (gl_info->supported[NV_HALF_FLOAT]) + { + /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT. */ + ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_2] = + (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2hvNV; + ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] = + (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4hvNV; + } + + ops->generic[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib1fv; + ops->generic[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2fv; + ops->generic[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib3fv; + ops->generic[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4fv; + if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = generic_d3dcolor; + else + ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = + (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv; + ops->generic[WINED3D_FFP_EMIT_UBYTE4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4ubv; + ops->generic[WINED3D_FFP_EMIT_SHORT2] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2sv; + ops->generic[WINED3D_FFP_EMIT_SHORT4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4sv; + ops->generic[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv; + ops->generic[WINED3D_FFP_EMIT_SHORT2N] = generic_short2n; + ops->generic[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nsv; + ops->generic[WINED3D_FFP_EMIT_USHORT2N] = generic_ushort2n; + ops->generic[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nusv; + if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) + { + ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = + (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2hvNV; + ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = + (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4hvNV; + } + else + { + ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = generic_float16_2; + ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = generic_float16_4; + } +} + +static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter_gl *adapter_gl, HDC dc) +{ + const struct wined3d_gl_info *gl_info = &adapter_gl->a.gl_info; + int i; + + if (gl_info->supported[WGL_ARB_PIXEL_FORMAT]) + { + UINT attrib_count = 0; + GLint cfg_count; + int attribs[11]; + int values[11]; + int attribute; + + attribute = WGL_NUMBER_PIXEL_FORMATS_ARB; + GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count)); + + adapter_gl->pixel_formats = heap_calloc(cfg_count, sizeof(*adapter_gl->pixel_formats)); + attribs[attrib_count++] = WGL_RED_BITS_ARB; + attribs[attrib_count++] = WGL_GREEN_BITS_ARB; + attribs[attrib_count++] = WGL_BLUE_BITS_ARB; + attribs[attrib_count++] = WGL_ALPHA_BITS_ARB; + attribs[attrib_count++] = WGL_COLOR_BITS_ARB; + attribs[attrib_count++] = WGL_DEPTH_BITS_ARB; + attribs[attrib_count++] = WGL_STENCIL_BITS_ARB; + attribs[attrib_count++] = WGL_DRAW_TO_WINDOW_ARB; + attribs[attrib_count++] = WGL_PIXEL_TYPE_ARB; + attribs[attrib_count++] = WGL_DOUBLE_BUFFER_ARB; + attribs[attrib_count++] = WGL_AUX_BUFFERS_ARB; + + for (i = 0, adapter_gl->pixel_format_count = 0; i < cfg_count; ++i) + { + struct wined3d_pixel_format *cfg = &adapter_gl->pixel_formats[adapter_gl->pixel_format_count]; + int format_id = i + 1; + + if (!GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, attrib_count, attribs, values))) + continue; + + cfg->iPixelFormat = format_id; + cfg->redSize = values[0]; + cfg->greenSize = values[1]; + cfg->blueSize = values[2]; + cfg->alphaSize = values[3]; + cfg->colorSize = values[4]; + cfg->depthSize = values[5]; + cfg->stencilSize = values[6]; + cfg->windowDrawable = values[7]; + cfg->iPixelType = values[8]; + cfg->doubleBuffer = values[9]; + cfg->auxBuffers = values[10]; + + cfg->numSamples = 0; + /* Check multisample support. */ + if (gl_info->supported[ARB_MULTISAMPLE]) + { + int attribs[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB}; + int values[2]; + + if (GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, 2, attribs, values))) + { + /* values[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether + * multisampling is supported. values[1] = number of + * multisample buffers. */ + if (values[0]) + cfg->numSamples = values[1]; + } + } + + TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " + "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n", + cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer, + cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize, + cfg->depthSize, cfg->stencilSize, cfg->numSamples, cfg->windowDrawable); + + ++adapter_gl->pixel_format_count; + } + } + else + { + int cfg_count; + + cfg_count = DescribePixelFormat(dc, 0, 0, 0); + adapter_gl->pixel_formats = heap_calloc(cfg_count, sizeof(*adapter_gl->pixel_formats)); + + for (i = 0, adapter_gl->pixel_format_count = 0; i < cfg_count; ++i) + { + struct wined3d_pixel_format *cfg = &adapter_gl->pixel_formats[adapter_gl->pixel_format_count]; + PIXELFORMATDESCRIPTOR pfd; + int format_id = i + 1; + + if (!DescribePixelFormat(dc, format_id, sizeof(pfd), &pfd)) + continue; + + /* We only want HW acceleration using an OpenGL ICD driver. + * PFD_GENERIC_FORMAT = slow OpenGL 1.1 GDI software rendering. + * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD + * driver (e.g. 3dfx minigl). */ + if (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) + { + TRACE("Skipping format %d because it isn't ICD accelerated.\n", format_id); + continue; + } + + cfg->iPixelFormat = format_id; + cfg->redSize = pfd.cRedBits; + cfg->greenSize = pfd.cGreenBits; + cfg->blueSize = pfd.cBlueBits; + cfg->alphaSize = pfd.cAlphaBits; + cfg->colorSize = pfd.cColorBits; + cfg->depthSize = pfd.cDepthBits; + cfg->stencilSize = pfd.cStencilBits; + cfg->windowDrawable = (pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0; + cfg->iPixelType = (pfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB; + cfg->doubleBuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0; + cfg->auxBuffers = pfd.cAuxBuffers; + cfg->numSamples = 0; + + TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " + "depth=%d, stencil=%d, windowDrawable=%d\n", + cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer, + cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize, + cfg->depthSize, cfg->stencilSize, cfg->windowDrawable); + + ++adapter_gl->pixel_format_count; + } + } +} + +static void adapter_gl_destroy(struct wined3d_adapter *adapter) +{ + struct wined3d_adapter_gl *adapter_gl = wined3d_adapter_gl(adapter); + + heap_free(adapter_gl->pixel_formats); + wined3d_adapter_cleanup(adapter); + heap_free(adapter_gl); +} + +static HRESULT adapter_gl_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter, + enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, + const enum wined3d_feature_level *levels, unsigned int level_count, + struct wined3d_device_parent *device_parent, struct wined3d_device **device) +{ + struct wined3d_device_gl *device_gl; + HRESULT hr; + + if (!(device_gl = heap_alloc_zero(sizeof(*device_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_device_init(&device_gl->d, wined3d, adapter->ordinal, device_type, + focus_window, flags, surface_alignment, levels, level_count, device_parent))) + { + WARN("Failed to initialize device, hr %#x.\n", hr); + heap_free(device_gl); + return hr; + } + + *device = &device_gl->d; + return WINED3D_OK; +} + +static void adapter_gl_destroy_device(struct wined3d_device *device) +{ + struct wined3d_device_gl *device_gl = wined3d_device_gl(device); + + wined3d_device_cleanup(&device_gl->d); + heap_free(device_gl); +} + +struct wined3d_context *adapter_gl_acquire_context(struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx) +{ + return wined3d_context_gl_acquire(device, texture, sub_resource_idx); +} + +void adapter_gl_release_context(struct wined3d_context *context) +{ +#if __REACTOS__ + wined3d_context_gl_release(wined3d_context_gl(context)); +#else + return wined3d_context_gl_release(wined3d_context_gl(context)); +#endif +} + +static void adapter_gl_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps) +{ + const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + + caps->ddraw_caps.dds_caps |= WINEDDSCAPS_BACKBUFFER + | WINEDDSCAPS_FLIP + | WINEDDSCAPS_COMPLEX + | WINEDDSCAPS_FRONTBUFFER + | WINEDDSCAPS_3DDEVICE + | WINEDDSCAPS_VIDEOMEMORY + | WINEDDSCAPS_OWNDC + | WINEDDSCAPS_LOCALVIDMEM + | WINEDDSCAPS_NONLOCALVIDMEM; + + caps->ddraw_caps.caps |= WINEDDCAPS_3D; + + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) + caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP; + + if (gl_info->supported[WINED3D_GL_BLEND_EQUATION]) + caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_BLENDOP; + if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) + caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND; + if (gl_info->supported[EXT_DRAW_BUFFERS2]) + caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS; + if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) + caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT; + if (~gl_info->quirks & WINED3D_QUIRK_NO_INDEPENDENT_BIT_DEPTHS) + caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS; + + if (gl_info->supported[ARB_SAMPLER_OBJECTS] || gl_info->supported[EXT_TEXTURE_LOD_BIAS]) + caps->RasterCaps |= WINED3DPRASTERCAPS_MIPMAPLODBIAS; + + if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) + { + caps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY; + + caps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC + | WINED3DPTFILTERCAPS_MINFANISOTROPIC; + } + + if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) + caps->DestBlendCaps |= WINED3DPBLENDCAPS_SRCALPHASAT; + + if (gl_info->supported[EXT_BLEND_COLOR]) + { + caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR; + caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR; + } + + if (gl_info->supported[EXT_TEXTURE3D]) + { + caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP + | WINED3DPTEXTURECAPS_MIPVOLUMEMAP; + if (!d3d_info->texture_npot) + caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP_POW2; + + caps->VolumeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFLINEAR + | WINED3DPTFILTERCAPS_MAGFPOINT + | WINED3DPTFILTERCAPS_MINFLINEAR + | WINED3DPTFILTERCAPS_MINFPOINT + | WINED3DPTFILTERCAPS_MIPFLINEAR + | WINED3DPTFILTERCAPS_MIPFPOINT + | WINED3DPTFILTERCAPS_LINEAR + | WINED3DPTFILTERCAPS_LINEARMIPLINEAR + | WINED3DPTFILTERCAPS_LINEARMIPNEAREST + | WINED3DPTFILTERCAPS_MIPLINEAR + | WINED3DPTFILTERCAPS_MIPNEAREST + | WINED3DPTFILTERCAPS_NEAREST; + + caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_INDEPENDENTUV + | WINED3DPTADDRESSCAPS_CLAMP + | WINED3DPTADDRESSCAPS_WRAP; + + if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP]) + { + caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER; + } + if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT]) + { + caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR; + } + if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]) + { + caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE; + } + + caps->MaxVolumeExtent = gl_info->limits.texture3d_size; + } + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP + | WINED3DPTEXTURECAPS_MIPCUBEMAP; + if (!d3d_info->texture_npot) + caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP_POW2; + + caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFLINEAR + | WINED3DPTFILTERCAPS_MAGFPOINT + | WINED3DPTFILTERCAPS_MINFLINEAR + | WINED3DPTFILTERCAPS_MINFPOINT + | WINED3DPTFILTERCAPS_MIPFLINEAR + | WINED3DPTFILTERCAPS_MIPFPOINT + | WINED3DPTFILTERCAPS_LINEAR + | WINED3DPTFILTERCAPS_LINEARMIPLINEAR + | WINED3DPTFILTERCAPS_LINEARMIPNEAREST + | WINED3DPTFILTERCAPS_MIPLINEAR + | WINED3DPTFILTERCAPS_MIPNEAREST + | WINED3DPTFILTERCAPS_NEAREST; + + if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) + { + caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC + | WINED3DPTFILTERCAPS_MINFANISOTROPIC; + } + } + + if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP]) + { + caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER; + } + if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT]) + { + caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR; + } + if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]) + { + caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE; + } + + if (gl_info->supported[EXT_STENCIL_WRAP]) + { + caps->StencilCaps |= WINED3DSTENCILCAPS_DECR + | WINED3DSTENCILCAPS_INCR; + } + + if (gl_info->supported[WINED3D_GL_VERSION_2_0] + || gl_info->supported[EXT_STENCIL_TWO_SIDE] + || gl_info->supported[ATI_SEPARATE_STENCIL]) + { + caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED; + } + + caps->MaxAnisotropy = gl_info->limits.anisotropy; + + if (caps->VertexShaderVersion >= 3) + { + caps->MaxVertexShader30InstructionSlots + = max(caps->MaxVertexShader30InstructionSlots, gl_info->limits.arb_vs_instructions); + } + if (caps->VertexShaderVersion >= 2) + { + caps->VS20Caps.temp_count = max(caps->VS20Caps.temp_count, gl_info->limits.arb_vs_temps); + + if (gl_info->supported[ARB_HALF_FLOAT_VERTEX]) + caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 | WINED3DDTCAPS_FLOAT16_4; + } + + if (caps->PixelShaderVersion >= 3) + { + caps->MaxPixelShader30InstructionSlots + = max(caps->MaxPixelShader30InstructionSlots, gl_info->limits.arb_ps_instructions); + } + if (caps->PixelShaderVersion >= 2) + { + caps->PS20Caps.temp_count = max(caps->PS20Caps.temp_count, gl_info->limits.arb_ps_temps); + } +} + +static BOOL wined3d_check_pixel_format_color(const struct wined3d_pixel_format *cfg, + const struct wined3d_format *format) +{ + /* Float formats need FBOs. If FBOs are used this function isn't called */ + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) + return FALSE; + + /* Probably a RGBA_float or color index mode. */ + if (cfg->iPixelType != WGL_TYPE_RGBA_ARB) + return FALSE; + + if (cfg->redSize < format->red_size + || cfg->greenSize < format->green_size + || cfg->blueSize < format->blue_size + || cfg->alphaSize < format->alpha_size) + return FALSE; + + return TRUE; +} + +static BOOL wined3d_check_pixel_format_depth(const struct wined3d_pixel_format *cfg, + const struct wined3d_format *format) +{ + BOOL lockable = FALSE; + + /* Float formats need FBOs. If FBOs are used this function isn't called */ + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) + return FALSE; + + if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT)) + lockable = TRUE; + + /* On some modern cards like the Geforce8/9, GLX doesn't offer some + * depth/stencil formats which D3D9 reports. We can safely report + * "compatible" formats (e.g. D24 can be used for D16) as long as we + * aren't dealing with a lockable format. This also helps D3D <= 7 as they + * expect D16 which isn't offered without this on Geforce8 cards. */ + if (!(cfg->depthSize == format->depth_size || (!lockable && cfg->depthSize > format->depth_size))) + return FALSE; + + /* Some cards like Intel i915 ones only offer D24S8 but lots of games also + * need a format without stencil. We can allow a mismatch if the format + * doesn't have any stencil bits. If it does have stencil bits the size + * must match, or stencil wrapping would break. */ + if (format->stencil_size && cfg->stencilSize != format->stencil_size) + return FALSE; + + return TRUE; +} + +static BOOL adapter_gl_check_format(const struct wined3d_adapter *adapter, + const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format, + const struct wined3d_format *ds_format) +{ + const struct wined3d_adapter_gl *adapter_gl = wined3d_adapter_gl_const(adapter); + unsigned int i; + + if (wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER) + return TRUE; + + if (adapter_format && rt_format) + { + /* In backbuffer mode the front and backbuffer share the same WGL + * pixelformat. The format must match in RGB, alpha is allowed to be + * different. (Only the backbuffer can have alpha.) */ + if (adapter_format->red_size != rt_format->red_size + || adapter_format->green_size != rt_format->green_size + || adapter_format->blue_size != rt_format->blue_size) + { + TRACE("Render target format %s doesn't match with adapter format %s.\n", + debug_d3dformat(rt_format->id), debug_d3dformat(adapter_format->id)); + return FALSE; + } + } + + for (i = 0; i < adapter_gl->pixel_format_count; ++i) + { + const struct wined3d_pixel_format *cfg = &adapter_gl->pixel_formats[i]; + + /* Check if there is a WGL pixel format matching the requirements, the format should also be window + * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */ + if (adapter_format && rt_format && !cfg->windowDrawable) + continue; + + if ((!adapter_format || wined3d_check_pixel_format_color(cfg, adapter_format)) + && (!rt_format || wined3d_check_pixel_format_color(cfg, rt_format)) + && (!ds_format || wined3d_check_pixel_format_depth(cfg, ds_format))) + { + TRACE("Pixel format %d is compatible.\n", cfg->iPixelFormat); + return TRUE; + } + } + + return FALSE; +} + +static HRESULT adapter_gl_init_3d(struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + wined3d_cs_init_object(device->cs, wined3d_device_create_primary_opengl_context_cs, device); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!wined3d_swapchain_gl(device->swapchains[0])->context_count) + return E_FAIL; + + device->d3d_initialized = TRUE; + + return WINED3D_OK; +} + +static void adapter_gl_uninit_3d(struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + wined3d_cs_destroy_object(device->cs, wined3d_device_delete_opengl_contexts_cs, device); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void *adapter_gl_map_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, size_t size, uint32_t bind_flags, uint32_t map_flags) +{ + struct wined3d_context_gl *context_gl; + GLenum binding; + + context_gl = wined3d_context_gl(context); + binding = wined3d_buffer_gl_binding_from_bind_flags(context_gl->gl_info, bind_flags); + + return wined3d_context_gl_map_bo_address(context_gl, data, size, binding, map_flags); +} + +static void adapter_gl_unmap_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, + uint32_t bind_flags, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + struct wined3d_context_gl *context_gl; + GLenum binding; + + context_gl = wined3d_context_gl(context); + binding = wined3d_buffer_gl_binding_from_bind_flags(context_gl->gl_info, bind_flags); + + wined3d_context_gl_unmap_bo_address(context_gl, data, binding, range_count, ranges); +} + +static void adapter_gl_copy_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *dst, uint32_t dst_bind_flags, + const struct wined3d_bo_address *src, uint32_t src_bind_flags, size_t size) +{ + struct wined3d_context_gl *context_gl; + GLenum dst_binding, src_binding; + + context_gl = wined3d_context_gl(context); + dst_binding = wined3d_buffer_gl_binding_from_bind_flags(context_gl->gl_info, dst_bind_flags); + src_binding = wined3d_buffer_gl_binding_from_bind_flags(context_gl->gl_info, src_bind_flags); + + wined3d_context_gl_copy_bo_address(context_gl, dst, dst_binding, src, src_binding, size); +} + +static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) +{ + struct wined3d_swapchain_gl *swapchain_gl; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", + device, desc, parent, parent_ops, swapchain); + + if (!(swapchain_gl = heap_alloc_zero(sizeof(*swapchain_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_gl_init(swapchain_gl, device, desc, parent, parent_ops))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(swapchain_gl); + return hr; + } + + TRACE("Created swapchain %p.\n", swapchain_gl); + *swapchain = &swapchain_gl->s; + + return hr; +} + +static void adapter_gl_destroy_swapchain(struct wined3d_swapchain *swapchain) +{ + struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(swapchain); + + wined3d_swapchain_gl_cleanup(swapchain_gl); + heap_free(swapchain_gl); +} + +static HRESULT adapter_gl_create_buffer(struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer) +{ + struct wined3d_buffer_gl *buffer_gl; + HRESULT hr; + + TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n", + device, desc, data, parent, parent_ops, buffer); + + if (!(buffer_gl = heap_alloc_zero(sizeof(*buffer_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_buffer_gl_init(buffer_gl, device, desc, data, parent, parent_ops))) + { + WARN("Failed to initialise buffer, hr %#x.\n", hr); + heap_free(buffer_gl); + return hr; + } + + TRACE("Created buffer %p.\n", buffer_gl); + *buffer = &buffer_gl->b; + + return hr; +} + +static void wined3d_buffer_gl_destroy_object(void *object) +{ + struct wined3d_buffer_gl *buffer_gl = object; + struct wined3d_context *context; + + if (buffer_gl->b.buffer_object) + { + context = context_acquire(buffer_gl->b.resource.device, NULL, 0); + wined3d_buffer_gl_destroy_buffer_object(buffer_gl, wined3d_context_gl(context)); + context_release(context); + } + + heap_free(buffer_gl); +} + +static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer) +{ + struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer); + struct wined3d_device *device = buffer_gl->b.resource.device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("buffer_gl %p.\n", buffer_gl); + + /* Take a reference to the device, in case releasing the buffer would + * cause the device to be destroyed. However, swapchain resources don't + * take a reference to the device, and we wouldn't want to increment the + * refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_buffer_cleanup(&buffer_gl->b); + wined3d_cs_destroy_object(device->cs, wined3d_buffer_gl_destroy_object, buffer_gl); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_gl_create_texture(struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) +{ + struct wined3d_texture_gl *texture_gl; + HRESULT hr; + + TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n", + device, desc, layer_count, level_count, flags, parent, parent_ops, texture); + + if (!(texture_gl = wined3d_texture_allocate_object_memory(sizeof(*texture_gl), level_count, layer_count))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_texture_gl_init(texture_gl, device, desc, + layer_count, level_count, flags, parent, parent_ops))) + { + WARN("Failed to initialise texture, hr %#x.\n", hr); + heap_free(texture_gl); + return hr; + } + + TRACE("Created texture %p.\n", texture_gl); + *texture = &texture_gl->t; + + return hr; +} + +static void wined3d_texture_gl_destroy_object(void *object) +{ + struct wined3d_renderbuffer_entry *entry, *entry2; + struct wined3d_texture_gl *texture_gl = object; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + struct wined3d_device *device; + + TRACE("texture_gl %p.\n", texture_gl); + + if (!list_empty(&texture_gl->renderbuffers)) + { + device = texture_gl->t.resource.device; + context = context_acquire(device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + TRACE("Deleting renderbuffer %u.\n", entry->id); + context_gl_resource_released(device, entry->id, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); + heap_free(entry); + } + + context_release(context); + } + + wined3d_texture_gl_unload_texture(texture_gl); + + heap_free(texture_gl); +} + +static void adapter_gl_destroy_texture(struct wined3d_texture *texture) +{ + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture); + struct wined3d_device *device = texture_gl->t.resource.device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("texture_gl %p.\n", texture_gl); + + /* Take a reference to the device, in case releasing the texture would + * cause the device to be destroyed. However, swapchain resources don't + * take a reference to the device, and we wouldn't want to increment the + * refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + + wined3d_texture_sub_resources_destroyed(texture); + texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); + + wined3d_texture_cleanup(&texture_gl->t); + wined3d_cs_destroy_object(device->cs, wined3d_texture_gl_destroy_object, texture_gl); + + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_gl_create_rendertarget_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_rendertarget_view **view) +{ + struct wined3d_rendertarget_view_gl *view_gl; + HRESULT hr; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + if (!(view_gl = heap_alloc_zero(sizeof(*view_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_rendertarget_view_gl_init(view_gl, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_gl); + return hr; + } + + TRACE("Created render target view %p.\n", view_gl); + *view = &view_gl->v; + + return hr; +} + +struct wined3d_view_gl_destroy_ctx +{ + struct wined3d_device *device; + const struct wined3d_gl_view *gl_view; + GLuint counter_bo; + void *object; + struct wined3d_view_gl_destroy_ctx *free; +}; + +static void wined3d_view_gl_destroy_object(void *object) +{ + struct wined3d_view_gl_destroy_ctx *ctx = object; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + struct wined3d_device *device; + + device = ctx->device; + + if (ctx->gl_view->name || ctx->counter_bo) + { + context = context_acquire(device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; + if (ctx->gl_view->name) + { + context_gl_resource_released(device, ctx->gl_view->name, FALSE); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &ctx->gl_view->name); + } + if (ctx->counter_bo) + GL_EXTCALL(glDeleteBuffers(1, &ctx->counter_bo)); + checkGLcall("delete resources"); + context_release(context); + } + + heap_free(ctx->object); + heap_free(ctx->free); +} + +static void wined3d_view_gl_destroy(struct wined3d_device *device, + const struct wined3d_gl_view *gl_view, GLuint counter_bo, void *object) +{ + struct wined3d_view_gl_destroy_ctx *ctx, c; + + if (!(ctx = heap_alloc(sizeof(*ctx)))) + ctx = &c; + ctx->device = device; + ctx->gl_view = gl_view; + ctx->counter_bo = counter_bo; + ctx->object = object; + ctx->free = ctx != &c ? ctx : NULL; + + wined3d_cs_destroy_object(device->cs, wined3d_view_gl_destroy_object, ctx); + if (!ctx->free) + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void adapter_gl_destroy_rendertarget_view(struct wined3d_rendertarget_view *view) +{ + struct wined3d_rendertarget_view_gl *view_gl = wined3d_rendertarget_view_gl(view); + struct wined3d_device *device = view_gl->v.resource->device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("view_gl %p.\n", view_gl); + + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_rendertarget_view_cleanup(&view_gl->v); + wined3d_view_gl_destroy(device, &view_gl->gl_view, 0, view_gl); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_gl_create_shader_resource_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view) +{ + struct wined3d_shader_resource_view_gl *view_gl; + HRESULT hr; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + if (!(view_gl = heap_alloc_zero(sizeof(*view_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_shader_resource_view_gl_init(view_gl, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_gl); + return hr; + } + + TRACE("Created shader resource view %p.\n", view_gl); + *view = &view_gl->v; + + return hr; +} + +static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resource_view *view) +{ + struct wined3d_shader_resource_view_gl *view_gl = wined3d_shader_resource_view_gl(view); + struct wined3d_device *device = view_gl->v.resource->device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("view_gl %p.\n", view_gl); + + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_shader_resource_view_cleanup(&view_gl->v); + wined3d_view_gl_destroy(device, &view_gl->gl_view, 0, view_gl); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_gl_create_unordered_access_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view) +{ + struct wined3d_unordered_access_view_gl *view_gl; + HRESULT hr; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + if (!(view_gl = heap_alloc_zero(sizeof(*view_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_unordered_access_view_gl_init(view_gl, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_gl); + return hr; + } + + TRACE("Created unordered access view %p.\n", view_gl); + *view = &view_gl->v; + + return hr; +} + +static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_access_view *view) +{ + struct wined3d_unordered_access_view_gl *view_gl = wined3d_unordered_access_view_gl(view); + struct wined3d_device *device = view_gl->v.resource->device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("view_gl %p.\n", view_gl); + + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_unordered_access_view_cleanup(&view_gl->v); + wined3d_view_gl_destroy(device, &view_gl->gl_view, view_gl->counter_bo, view_gl); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_gl_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler) +{ + struct wined3d_sampler_gl *sampler_gl; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n", + device, desc, parent, parent_ops, sampler); + + if (!(sampler_gl = heap_alloc_zero(sizeof(*sampler_gl)))) + return E_OUTOFMEMORY; + + wined3d_sampler_gl_init(sampler_gl, device, desc, parent, parent_ops); + + TRACE("Created sampler %p.\n", sampler_gl); + *sampler = &sampler_gl->s; + + return WINED3D_OK; +} + +static void wined3d_sampler_gl_destroy_object(void *object) +{ + struct wined3d_sampler_gl *sampler_gl = object; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + if (sampler_gl->name) + { + context = context_acquire(sampler_gl->s.device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; + GL_EXTCALL(glDeleteSamplers(1, &sampler_gl->name)); + context_release(context); + } + + heap_free(sampler_gl); +} + +static void adapter_gl_destroy_sampler(struct wined3d_sampler *sampler) +{ + struct wined3d_sampler_gl *sampler_gl = wined3d_sampler_gl(sampler); + + TRACE("sampler_gl %p.\n", sampler_gl); + + wined3d_cs_destroy_object(sampler->device->cs, wined3d_sampler_gl_destroy_object, sampler_gl); +} + +static HRESULT adapter_gl_create_query(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) +{ + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + return wined3d_query_gl_create(device, type, parent, parent_ops, query); +} + +static void wined3d_query_gl_destroy_object(void *object) +{ + struct wined3d_query *query = object; + + if (query->buffer_object) + { + struct wined3d_context *context; + + context = context_acquire(query->device, NULL, 0); + wined3d_query_gl_destroy_buffer_object(wined3d_context_gl(context), query); + context_release(context); + } + + /* Queries are specific to the GL context that created them. Not + * deleting the query will obviously leak it, but that's still better + * than potentially deleting a different query with the same id in this + * context, and (still) leaking the actual query. */ + query->query_ops->query_destroy(query); +} + +static void adapter_gl_destroy_query(struct wined3d_query *query) +{ + TRACE("query %p.\n", query); + + wined3d_cs_destroy_object(query->device->cs, wined3d_query_gl_destroy_object, query); +} + +static void adapter_gl_flush_context(struct wined3d_context *context) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + + TRACE("context_gl %p.\n", context_gl); + + if (context_gl->valid) + context_gl->gl_info->gl_ops.gl.p_glFlush(); +} + +void adapter_gl_clear_uav(struct wined3d_context *context, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) +{ + TRACE("context %p, view %p, clear_value %s.\n", context, view, debug_uvec4(clear_value)); + + wined3d_unordered_access_view_gl_clear_uint(wined3d_unordered_access_view_gl(view), + clear_value, wined3d_context_gl(context)); +} + +static const struct wined3d_adapter_ops wined3d_adapter_gl_ops = +{ + adapter_gl_destroy, + adapter_gl_create_device, + adapter_gl_destroy_device, + adapter_gl_acquire_context, + adapter_gl_release_context, + adapter_gl_get_wined3d_caps, + adapter_gl_check_format, + adapter_gl_init_3d, + adapter_gl_uninit_3d, + adapter_gl_map_bo_address, + adapter_gl_unmap_bo_address, + adapter_gl_copy_bo_address, + adapter_gl_create_swapchain, + adapter_gl_destroy_swapchain, + adapter_gl_create_buffer, + adapter_gl_destroy_buffer, + adapter_gl_create_texture, + adapter_gl_destroy_texture, + adapter_gl_create_rendertarget_view, + adapter_gl_destroy_rendertarget_view, + adapter_gl_create_shader_resource_view, + adapter_gl_destroy_shader_resource_view, + adapter_gl_create_unordered_access_view, + adapter_gl_destroy_unordered_access_view, + adapter_gl_create_sampler, + adapter_gl_destroy_sampler, + adapter_gl_create_query, + adapter_gl_destroy_query, + adapter_gl_flush_context, + adapter_gl_clear_uav, +}; + +static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_gl, uint32_t wined3d_creation_flags) +{ + const struct wined3d_gl_info *gl_info = &adapter_gl->a.gl_info; + struct wined3d_d3d_info *d3d_info = &adapter_gl->a.d3d_info; + struct wined3d_vertex_caps vertex_caps; + struct fragment_caps fragment_caps; + struct shader_caps shader_caps; + GLfloat f[2]; + int i; + + adapter_gl->a.shader_backend->shader_get_caps(&adapter_gl->a, &shader_caps); + adapter_gl->a.vertex_pipe->vp_get_caps(&adapter_gl->a, &vertex_caps); + adapter_gl->a.fragment_pipe->get_caps(&adapter_gl->a, &fragment_caps); + + d3d_info->limits.vs_version = shader_caps.vs_version; + d3d_info->limits.hs_version = shader_caps.hs_version; + d3d_info->limits.ds_version = shader_caps.ds_version; + d3d_info->limits.gs_version = shader_caps.gs_version; + d3d_info->limits.ps_version = shader_caps.ps_version; + d3d_info->limits.cs_version = shader_caps.cs_version; + d3d_info->limits.vs_uniform_count_swvp = shader_caps.vs_uniform_count; + d3d_info->limits.vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, shader_caps.vs_uniform_count); + d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count; + d3d_info->limits.varying_count = shader_caps.varying_count; + d3d_info->limits.ffp_textures = fragment_caps.MaxSimultaneousTextures; + d3d_info->limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages; + TRACE("Max texture stages: %u.\n", d3d_info->limits.ffp_blend_stages); + d3d_info->limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; + d3d_info->limits.active_light_count = vertex_caps.max_active_lights; + d3d_info->limits.ffp_max_vertex_blend_matrix_index = vertex_caps.max_vertex_blend_matrix_index; + + d3d_info->valid_dual_rt_mask = 0; + for (i = 0; i < gl_info->limits.dual_buffers; ++i) + d3d_info->valid_dual_rt_mask |= (1u << i); + + d3d_info->limits.max_rt_count = gl_info->limits.buffers; + d3d_info->limits.max_clip_distances = gl_info->limits.user_clip_distances; + d3d_info->limits.texture_size = gl_info->limits.texture_size; + + gl_info->gl_ops.gl.p_glGetFloatv(gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + ? GL_ALIASED_POINT_SIZE_RANGE : GL_POINT_SIZE_RANGE, f); + d3d_info->limits.pointsize_max = f[1]; + TRACE("Maximum point size support - max point size %.8e.\n", f[1]); + + d3d_info->wined3d_creation_flags = wined3d_creation_flags; + d3d_info->xyzrhw = vertex_caps.xyzrhw; + d3d_info->emulated_flatshading = vertex_caps.emulated_flatshading; + d3d_info->ffp_generic_attributes = vertex_caps.ffp_generic_attributes; + d3d_info->ffp_alpha_test = !!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; + d3d_info->vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING; + d3d_info->shader_color_key = !!(fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY); + d3d_info->shader_double_precision = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION); + d3d_info->shader_output_interpolation = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION); + d3d_info->viewport_array_index_any_shader = !!gl_info->supported[ARB_SHADER_VIEWPORT_LAYER_ARRAY]; + d3d_info->texture_npot = !!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]; + d3d_info->texture_npot_conditional = gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] + || gl_info->supported[ARB_TEXTURE_RECTANGLE]; + d3d_info->draw_base_vertex_offset = !!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]; + d3d_info->vertex_bgra = !!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]; + d3d_info->texture_swizzle = !!gl_info->supported[ARB_TEXTURE_SWIZZLE]; + d3d_info->srgb_read_control = !!gl_info->supported[EXT_TEXTURE_SRGB_DECODE]; + d3d_info->srgb_write_control = !!gl_info->supported[ARB_FRAMEBUFFER_SRGB]; + d3d_info->clip_control = !!gl_info->supported[ARB_CLIP_CONTROL]; + d3d_info->full_ffp_varyings = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_FULL_FFP_VARYINGS); + d3d_info->feature_level = feature_level_from_caps(gl_info, &shader_caps, &fragment_caps); + + if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) + d3d_info->multisample_draw_location = WINED3D_LOCATION_TEXTURE_RGB; + else + d3d_info->multisample_draw_location = WINED3D_LOCATION_RB_MULTISAMPLE; +} + +static BOOL wined3d_adapter_gl_init(struct wined3d_adapter_gl *adapter_gl, + unsigned int ordinal, unsigned int wined3d_creation_flags) +{ + static const DWORD supported_gl_versions[] = + { + MAKEDWORD_VERSION(4, 4), + MAKEDWORD_VERSION(3, 2), + MAKEDWORD_VERSION(1, 0), + }; + struct wined3d_gl_info *gl_info = &adapter_gl->a.gl_info; + struct wined3d_caps_gl_ctx caps_gl_ctx = {0}; + unsigned int i; + + TRACE("adapter_gl %p, ordinal %u, wined3d_creation_flags %#x.\n", + adapter_gl, ordinal, wined3d_creation_flags); + + if (!wined3d_adapter_init(&adapter_gl->a, ordinal, &wined3d_adapter_gl_ops)) + return FALSE; + + /* Dynamically load all GL core functions */ +#ifdef USE_WIN32_OPENGL + { + HMODULE mod_gl = GetModuleHandleA("opengl32.dll"); +#define USE_GL_FUNC(f) gl_info->gl_ops.gl.p_##f = (void *)GetProcAddress(mod_gl, #f); + ALL_WGL_FUNCS +#undef USE_GL_FUNC + gl_info->gl_ops.wgl.p_wglSwapBuffers = (void *)GetProcAddress(mod_gl, "wglSwapBuffers"); + gl_info->gl_ops.wgl.p_wglGetPixelFormat = (void *)GetProcAddress(mod_gl, "wglGetPixelFormat"); + } +#else + /* To bypass the opengl32 thunks retrieve functions from the WGL driver instead of opengl32 */ + { + HDC hdc = GetDC( 0 ); + const struct opengl_funcs *wgl_driver = __wine_get_wgl_driver( hdc, WINE_WGL_DRIVER_VERSION ); + ReleaseDC( 0, hdc ); + if (!wgl_driver || wgl_driver == (void *)-1) return FALSE; + gl_info->gl_ops.wgl = wgl_driver->wgl; + gl_info->gl_ops.gl = wgl_driver->gl; + } +#endif + + gl_info->p_glEnableWINE = gl_info->gl_ops.gl.p_glEnable; + gl_info->p_glDisableWINE = gl_info->gl_ops.gl.p_glDisable; + + if (!wined3d_caps_gl_ctx_create(&adapter_gl->a, &caps_gl_ctx)) + { + ERR("Failed to get a GL context for adapter %p.\n", adapter_gl); + return FALSE; + } + + for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i) + { + if (supported_gl_versions[i] <= wined3d_settings.max_gl_version) + break; + } + if (i == ARRAY_SIZE(supported_gl_versions)) + { + ERR_(winediag)("Requested invalid GL version %u.%u.\n", + wined3d_settings.max_gl_version >> 16, wined3d_settings.max_gl_version & 0xffff); + i = ARRAY_SIZE(supported_gl_versions) - 1; + } + + for (; i < ARRAY_SIZE(supported_gl_versions); ++i) + { + gl_info->selected_gl_version = supported_gl_versions[i]; + + if (wined3d_caps_gl_ctx_create_attribs(&caps_gl_ctx, gl_info)) + break; + + WARN("Couldn't create an OpenGL %u.%u context, trying fallback to a lower version.\n", + supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff); + } + + if (!wined3d_adapter_init_gl_caps(&adapter_gl->a, &caps_gl_ctx, wined3d_creation_flags)) + { + ERR("Failed to initialize GL caps for adapter %p.\n", adapter_gl); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); + return FALSE; + } + + wined3d_adapter_gl_init_d3d_info(adapter_gl, wined3d_creation_flags); + if (!adapter_gl->a.d3d_info.shader_color_key) + { + /* We do not want to deal with re-creating immutable texture storage + * for colour-keying emulation. */ + WARN("Disabling ARB_texture_storage because fragment pipe doesn't support colour-keying.\n"); + gl_info->supported[ARB_TEXTURE_STORAGE] = FALSE; + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) + ERR_(winediag)("You are using the backbuffer for offscreen rendering. " + "This is unsupported, and will be removed in a future version.\n"); + + wined3d_adapter_init_fb_cfgs(adapter_gl, caps_gl_ctx.dc); + /* We haven't found any suitable formats. This should only happen in + * case of GDI software rendering, which is pretty useless anyway. */ + if (!adapter_gl->pixel_format_count) + { + WARN("No suitable pixel formats found.\n"); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); + heap_free(adapter_gl->pixel_formats); + return FALSE; + } + + if (!wined3d_adapter_gl_init_format_info(&adapter_gl->a, &caps_gl_ctx)) + { + ERR("Failed to initialize GL format info.\n"); + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); + heap_free(adapter_gl->pixel_formats); + return FALSE; + } + + wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); + + wined3d_adapter_init_ffp_attrib_ops(&adapter_gl->a); + + return TRUE; +} + +struct wined3d_adapter *wined3d_adapter_gl_create(unsigned int ordinal, unsigned int wined3d_creation_flags) +{ + struct wined3d_adapter_gl *adapter; + + if (!(adapter = heap_alloc_zero(sizeof(*adapter)))) + return NULL; + + if (!wined3d_adapter_gl_init(adapter, ordinal, wined3d_creation_flags)) + { + heap_free(adapter); + return NULL; + } + + TRACE("Created adapter %p.\n", adapter); + + return &adapter->a; +} diff --git a/dll/directx/wine/wined3d/adapter_vk.c b/dll/directx/wine/wined3d/adapter_vk.c new file mode 100644 index 00000000000..2032ec170e7 --- /dev/null +++ b/dll/directx/wine/wined3d/adapter_vk.c @@ -0,0 +1,1230 @@ +/* + * Copyright 2018 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" +#include "wined3d_private.h" + +#include "wine/vulkan_driver.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); + +static inline const struct wined3d_adapter_vk *wined3d_adapter_vk_const(const struct wined3d_adapter *adapter) +{ + return CONTAINING_RECORD(adapter, struct wined3d_adapter_vk, a); +} + +static const char *debug_vk_version(uint32_t version) +{ + return wine_dbg_sprintf("%u.%u.%u", + VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version), VK_VERSION_PATCH(version)); +} + +static HRESULT hresult_from_vk_result(VkResult vr) +{ + switch (vr) + { + case VK_SUCCESS: + return S_OK; + case VK_ERROR_OUT_OF_HOST_MEMORY: + WARN("Out of host memory.\n"); + return E_OUTOFMEMORY; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: + WARN("Out of device memory.\n"); + return E_OUTOFMEMORY; + case VK_ERROR_DEVICE_LOST: + WARN("Device lost.\n"); + return E_FAIL; + case VK_ERROR_EXTENSION_NOT_PRESENT: + WARN("Extension not present.\n"); + return E_FAIL; + default: + FIXME("Unhandled VkResult %d.\n", vr); + return E_FAIL; + } +} + +#ifdef USE_WIN32_VULKAN +static BOOL wined3d_load_vulkan(struct wined3d_vk_info *vk_info) +{ + struct vulkan_ops *vk_ops = &vk_info->vk_ops; + + if (!(vk_info->vulkan_lib = LoadLibraryA("vulkan-1.dll"))) + { + WARN("Failed to load vulkan-1.dll.\n"); + return FALSE; + } + + vk_ops->vkGetInstanceProcAddr = (void *)GetProcAddress(vk_info->vulkan_lib, "vkGetInstanceProcAddr"); + if (!vk_ops->vkGetInstanceProcAddr) + { + FreeLibrary(vk_info->vulkan_lib); + return FALSE; + } + + return TRUE; +} + +static void wined3d_unload_vulkan(struct wined3d_vk_info *vk_info) +{ + if (vk_info->vulkan_lib) + { + FreeLibrary(vk_info->vulkan_lib); + vk_info->vulkan_lib = NULL; + } +} +#else +static BOOL wined3d_load_vulkan(struct wined3d_vk_info *vk_info) +{ + struct vulkan_ops *vk_ops = &vk_info->vk_ops; + const struct vulkan_funcs *vk_funcs; + HDC dc; + + dc = GetDC(0); + vk_funcs = __wine_get_vulkan_driver(dc, WINE_VULKAN_DRIVER_VERSION); + ReleaseDC(0, dc); + + if (!vk_funcs) + return FALSE; + + vk_ops->vkGetInstanceProcAddr = (void *)vk_funcs->p_vkGetInstanceProcAddr; + return TRUE; +} + +static void wined3d_unload_vulkan(struct wined3d_vk_info *vk_info) {} +#endif + +static void adapter_vk_destroy(struct wined3d_adapter *adapter) +{ + struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(adapter); + struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; + + VK_CALL(vkDestroyInstance(vk_info->instance, NULL)); + wined3d_unload_vulkan(vk_info); + wined3d_adapter_cleanup(&adapter_vk->a); + heap_free(adapter_vk); +} + +static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_vk *adapter_vk, + uint32_t *queue_family_index) +{ + VkPhysicalDevice physical_device = adapter_vk->physical_device; + const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; + VkQueueFamilyProperties *queue_properties; + uint32_t count, i; + + VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, NULL)); + + if (!(queue_properties = heap_calloc(count, sizeof(*queue_properties)))) + return E_OUTOFMEMORY; + + VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, queue_properties)); + + for (i = 0; i < count; ++i) + { + if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + *queue_family_index = i; + heap_free(queue_properties); + return WINED3D_OK; + } + } + heap_free(queue_properties); + + WARN("Failed to find graphics queue.\n"); + return E_FAIL; +} + +static void wined3d_disable_vulkan_features(VkPhysicalDeviceFeatures *features) +{ + features->depthBounds = VK_FALSE; + features->alphaToOne = VK_FALSE; + features->textureCompressionETC2 = VK_FALSE; + features->textureCompressionASTC_LDR = VK_FALSE; + features->shaderStorageImageMultisample = VK_FALSE; + features->shaderUniformBufferArrayDynamicIndexing = VK_FALSE; + features->shaderSampledImageArrayDynamicIndexing = VK_FALSE; + features->shaderStorageBufferArrayDynamicIndexing = VK_FALSE; + features->shaderStorageImageArrayDynamicIndexing = VK_FALSE; + features->shaderInt16 = VK_FALSE; + features->shaderResourceResidency = VK_FALSE; + features->shaderResourceMinLod = VK_FALSE; + features->sparseBinding = VK_FALSE; + features->sparseResidencyBuffer = VK_FALSE; + features->sparseResidencyImage2D = VK_FALSE; + features->sparseResidencyImage3D = VK_FALSE; + features->sparseResidency2Samples = VK_FALSE; + features->sparseResidency4Samples = VK_FALSE; + features->sparseResidency8Samples = VK_FALSE; + features->sparseResidency16Samples = VK_FALSE; + features->sparseResidencyAliased = VK_FALSE; + features->inheritedQueries = VK_FALSE; +} + +static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter, + enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, + const enum wined3d_feature_level *levels, unsigned int level_count, + struct wined3d_device_parent *device_parent, struct wined3d_device **device) +{ + const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter); + const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; + static const float priorities[] = {1.0f}; + struct wined3d_device_vk *device_vk; + VkDevice vk_device = VK_NULL_HANDLE; + VkDeviceQueueCreateInfo queue_info; + VkPhysicalDeviceFeatures features; + VkPhysicalDevice physical_device; + VkDeviceCreateInfo device_info; + uint32_t queue_family_index; + VkResult vr; + HRESULT hr; + + if (!(device_vk = heap_alloc_zero(sizeof(*device_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_select_vulkan_queue_family(adapter_vk, &queue_family_index))) + goto fail; + + physical_device = adapter_vk->physical_device; + + VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features)); + wined3d_disable_vulkan_features(&features); + + queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info.pNext = NULL; + queue_info.flags = 0; + queue_info.queueFamilyIndex = queue_family_index; + queue_info.queueCount = ARRAY_SIZE(priorities); + queue_info.pQueuePriorities = priorities; + + device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device_info.pNext = NULL; + device_info.flags = 0; + device_info.queueCreateInfoCount = 1; + device_info.pQueueCreateInfos = &queue_info; + device_info.enabledLayerCount = 0; + device_info.ppEnabledLayerNames = NULL; + device_info.enabledExtensionCount = 0; + device_info.ppEnabledExtensionNames = NULL; + device_info.pEnabledFeatures = &features; + + if ((vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device))) < 0) + { + WARN("Failed to create Vulkan device, vr %s.\n", wined3d_debug_vkresult(vr)); + vk_device = VK_NULL_HANDLE; + hr = hresult_from_vk_result(vr); + goto fail; + } + + device_vk->vk_device = vk_device; + VK_CALL(vkGetDeviceQueue(vk_device, queue_family_index, 0, &device_vk->vk_queue)); + + device_vk->vk_info = *vk_info; +#define LOAD_DEVICE_PFN(name) \ + if (!(device_vk->vk_info.vk_ops.name = (void *)VK_CALL(vkGetDeviceProcAddr(vk_device, #name)))) \ + { \ + WARN("Could not get device proc addr for '" #name "'.\n"); \ + hr = E_FAIL; \ + goto fail; \ + } +#define VK_DEVICE_PFN LOAD_DEVICE_PFN + VK_DEVICE_FUNCS() +#undef VK_DEVICE_PFN + + if (FAILED(hr = wined3d_device_init(&device_vk->d, wined3d, adapter->ordinal, device_type, + focus_window, flags, surface_alignment, levels, level_count, device_parent))) + { + WARN("Failed to initialize device, hr %#x.\n", hr); + goto fail; + } + + *device = &device_vk->d; + + return WINED3D_OK; + +fail: + VK_CALL(vkDestroyDevice(vk_device, NULL)); + heap_free(device_vk); + return hr; +} + +static void adapter_vk_destroy_device(struct wined3d_device *device) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(device); + const struct wined3d_vk_info *vk_info = &device_vk->vk_info; + + wined3d_device_cleanup(&device_vk->d); + VK_CALL(vkDestroyDevice(device_vk->vk_device, NULL)); + heap_free(device_vk); +} + +struct wined3d_context *adapter_vk_acquire_context(struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx) +{ + TRACE("device %p, texture %p, sub_resource_idx %u.\n", device, texture, sub_resource_idx); + + wined3d_from_cs(device->cs); + + if (!device->context_count) + return NULL; + + return &wined3d_device_vk(device)->context_vk.c; +} + +void adapter_vk_release_context(struct wined3d_context *context) +{ + TRACE("context %p.\n", context); +} + +static void adapter_vk_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps) +{ + const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter); + const VkPhysicalDeviceLimits *limits = &adapter_vk->device_limits; + BOOL sampler_anisotropy = limits->maxSamplerAnisotropy > 1.0f; + + caps->ddraw_caps.dds_caps |= WINEDDSCAPS_BACKBUFFER + | WINEDDSCAPS_FLIP + | WINEDDSCAPS_COMPLEX + | WINEDDSCAPS_FRONTBUFFER + | WINEDDSCAPS_3DDEVICE + | WINEDDSCAPS_VIDEOMEMORY + | WINEDDSCAPS_OWNDC + | WINEDDSCAPS_LOCALVIDMEM + | WINEDDSCAPS_NONLOCALVIDMEM; + caps->ddraw_caps.caps |= WINEDDCAPS_3D; + + caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP; + + caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_BLENDOP + | WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS + | WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS + | WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT + | WINED3DPMISCCAPS_SEPARATEALPHABLEND; + + caps->RasterCaps |= WINED3DPRASTERCAPS_MIPMAPLODBIAS; + + if (sampler_anisotropy) + { + caps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY; + + caps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC + | WINED3DPTFILTERCAPS_MINFANISOTROPIC; + + caps->MaxAnisotropy = limits->maxSamplerAnisotropy; + } + + caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR; + caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR + | WINED3DPBLENDCAPS_SRCALPHASAT; + + caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP + | WINED3DPTEXTURECAPS_MIPVOLUMEMAP + | WINED3DPTEXTURECAPS_VOLUMEMAP_POW2; + caps->VolumeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFLINEAR + | WINED3DPTFILTERCAPS_MAGFPOINT + | WINED3DPTFILTERCAPS_MINFLINEAR + | WINED3DPTFILTERCAPS_MINFPOINT + | WINED3DPTFILTERCAPS_MIPFLINEAR + | WINED3DPTFILTERCAPS_MIPFPOINT + | WINED3DPTFILTERCAPS_LINEAR + | WINED3DPTFILTERCAPS_LINEARMIPLINEAR + | WINED3DPTFILTERCAPS_LINEARMIPNEAREST + | WINED3DPTFILTERCAPS_MIPLINEAR + | WINED3DPTFILTERCAPS_MIPNEAREST + | WINED3DPTFILTERCAPS_NEAREST; + caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_INDEPENDENTUV + | WINED3DPTADDRESSCAPS_CLAMP + | WINED3DPTADDRESSCAPS_WRAP; + caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER + | WINED3DPTADDRESSCAPS_MIRROR + | WINED3DPTADDRESSCAPS_MIRRORONCE; + + caps->MaxVolumeExtent = limits->maxImageDimension3D; + + caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP + | WINED3DPTEXTURECAPS_MIPCUBEMAP + | WINED3DPTEXTURECAPS_CUBEMAP_POW2; + caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFLINEAR + | WINED3DPTFILTERCAPS_MAGFPOINT + | WINED3DPTFILTERCAPS_MINFLINEAR + | WINED3DPTFILTERCAPS_MINFPOINT + | WINED3DPTFILTERCAPS_MIPFLINEAR + | WINED3DPTFILTERCAPS_MIPFPOINT + | WINED3DPTFILTERCAPS_LINEAR + | WINED3DPTFILTERCAPS_LINEARMIPLINEAR + | WINED3DPTFILTERCAPS_LINEARMIPNEAREST + | WINED3DPTFILTERCAPS_MIPLINEAR + | WINED3DPTFILTERCAPS_MIPNEAREST + | WINED3DPTFILTERCAPS_NEAREST; + + if (sampler_anisotropy) + { + caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC + | WINED3DPTFILTERCAPS_MINFANISOTROPIC; + } + + caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER + | WINED3DPTADDRESSCAPS_MIRROR + | WINED3DPTADDRESSCAPS_MIRRORONCE; + + caps->StencilCaps |= WINED3DSTENCILCAPS_DECR + | WINED3DSTENCILCAPS_INCR + | WINED3DSTENCILCAPS_TWOSIDED; + + caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 | WINED3DDTCAPS_FLOAT16_4; + + caps->MaxPixelShader30InstructionSlots = WINED3DMAX30SHADERINSTRUCTIONS; + caps->MaxVertexShader30InstructionSlots = WINED3DMAX30SHADERINSTRUCTIONS; + caps->PS20Caps.temp_count = WINED3DPS20_MAX_NUMTEMPS; + caps->VS20Caps.temp_count = WINED3DVS20_MAX_NUMTEMPS; +} + +static BOOL adapter_vk_check_format(const struct wined3d_adapter *adapter, + const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format, + const struct wined3d_format *ds_format) +{ + return TRUE; +} + +static HRESULT adapter_vk_init_3d(struct wined3d_device *device) +{ + struct wined3d_context_vk *context_vk; + struct wined3d_device_vk *device_vk; + HRESULT hr; + + TRACE("device %p.\n", device); + + device_vk = wined3d_device_vk(device); + context_vk = &device_vk->context_vk; + if (FAILED(hr = wined3d_context_vk_init(context_vk, device->swapchains[0]))) + { + WARN("Failed to initialise context.\n"); + return hr; + } + + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, + device->adapter->vertex_pipe, device->adapter->fragment_pipe))) + { + ERR("Failed to allocate shader private data, hr %#x.\n", hr); + wined3d_context_vk_cleanup(context_vk); + return hr; + } + + if (!device_context_add(device, &context_vk->c)) + { + ERR("Failed to add the newly created context to the context list.\n"); + device->shader_backend->shader_free_private(device, NULL); + wined3d_context_vk_cleanup(context_vk); + return E_FAIL; + } + + TRACE("Initialised context %p.\n", context_vk); + + if (!(device_vk->d.blitter = wined3d_cpu_blitter_create())) + { + ERR("Failed to create CPU blitter.\n"); + device_context_remove(device, &context_vk->c); + device->shader_backend->shader_free_private(device, NULL); + wined3d_context_vk_cleanup(context_vk); + return E_FAIL; + } + + wined3d_device_create_default_samplers(device, &context_vk->c); + + return WINED3D_OK; +} + +static void adapter_vk_uninit_3d(struct wined3d_device *device) +{ + struct wined3d_context_vk *context_vk; + struct wined3d_shader *shader; + + TRACE("device %p.\n", device); + + context_vk = &wined3d_device_vk(device)->context_vk; + + LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) + { + device->shader_backend->shader_destroy(shader); + } + + wined3d_device_destroy_default_samplers(device, &context_vk->c); + + device->blitter->ops->blitter_destroy(device->blitter, NULL); + + device_context_remove(device, &context_vk->c); + device->shader_backend->shader_free_private(device, NULL); + wined3d_context_vk_cleanup(context_vk); +} + +static void *adapter_vk_map_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, size_t size, uint32_t bind_flags, uint32_t map_flags) +{ + if (data->buffer_object) + { + ERR("Unsupported buffer object %#lx.\n", data->buffer_object); + return NULL; + } + + return data->addr; +} + +static void adapter_vk_unmap_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, + uint32_t bind_flags, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + if (data->buffer_object) + ERR("Unsupported buffer object %#lx.\n", data->buffer_object); +} + +static void adapter_vk_copy_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *dst, uint32_t dst_bind_flags, + const struct wined3d_bo_address *src, uint32_t src_bind_flags, size_t size) +{ + struct wined3d_map_range range; + void *dst_ptr, *src_ptr; + + src_ptr = adapter_vk_map_bo_address(context, src, size, src_bind_flags, WINED3D_MAP_READ); + dst_ptr = adapter_vk_map_bo_address(context, dst, size, dst_bind_flags, WINED3D_MAP_WRITE); + + memcpy(dst_ptr, src_ptr, size); + + range.offset = 0; + range.size = size; + adapter_vk_unmap_bo_address(context, dst, dst_bind_flags, 1, &range); + adapter_vk_unmap_bo_address(context, src, src_bind_flags, 0, NULL); +} + +static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) +{ + struct wined3d_swapchain *swapchain_vk; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", + device, desc, parent, parent_ops, swapchain); + + if (!(swapchain_vk = heap_alloc_zero(sizeof(*swapchain_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_vk_init(swapchain_vk, device, desc, parent, parent_ops))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(swapchain_vk); + return hr; + } + + TRACE("Created swapchain %p.\n", swapchain_vk); + *swapchain = swapchain_vk; + + return hr; +} + +static void adapter_vk_destroy_swapchain(struct wined3d_swapchain *swapchain) +{ + wined3d_swapchain_cleanup(swapchain); + heap_free(swapchain); +} + +static HRESULT adapter_vk_create_buffer(struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer) +{ + struct wined3d_buffer_vk *buffer_vk; + HRESULT hr; + + TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n", + device, desc, data, parent, parent_ops, buffer); + + if (!(buffer_vk = heap_alloc_zero(sizeof(*buffer_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_buffer_vk_init(buffer_vk, device, desc, data, parent, parent_ops))) + { + WARN("Failed to initialise buffer, hr %#x.\n", hr); + heap_free(buffer_vk); + return hr; + } + + TRACE("Created buffer %p.\n", buffer_vk); + *buffer = &buffer_vk->b; + + return hr; +} + +static void adapter_vk_destroy_buffer(struct wined3d_buffer *buffer) +{ + struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer); + struct wined3d_device *device = buffer_vk->b.resource.device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("buffer_vk %p.\n", buffer_vk); + + /* Take a reference to the device, in case releasing the buffer would + * cause the device to be destroyed. However, swapchain resources don't + * take a reference to the device, and we wouldn't want to increment the + * refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_buffer_cleanup(&buffer_vk->b); + wined3d_cs_destroy_object(device->cs, heap_free, buffer_vk); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_vk_create_texture(struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) +{ + struct wined3d_texture_vk *texture_vk; + HRESULT hr; + + TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n", + device, desc, layer_count, level_count, flags, parent, parent_ops, texture); + + if (!(texture_vk = wined3d_texture_allocate_object_memory(sizeof(*texture_vk), level_count, layer_count))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_texture_vk_init(texture_vk, device, desc, + layer_count, level_count, flags, parent, parent_ops))) + { + WARN("Failed to initialise texture, hr %#x.\n", hr); + heap_free(texture_vk); + return hr; + } + + TRACE("Created texture %p.\n", texture_vk); + *texture = &texture_vk->t; + + return hr; +} + +static void adapter_vk_destroy_texture(struct wined3d_texture *texture) +{ + struct wined3d_texture_vk *texture_vk = wined3d_texture_vk(texture); + struct wined3d_device *device = texture_vk->t.resource.device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("texture_vk %p.\n", texture_vk); + + /* Take a reference to the device, in case releasing the texture would + * cause the device to be destroyed. However, swapchain resources don't + * take a reference to the device, and we wouldn't want to increment the + * refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + + wined3d_texture_sub_resources_destroyed(texture); + texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); + + wined3d_texture_cleanup(&texture_vk->t); + wined3d_cs_destroy_object(device->cs, heap_free, texture_vk); + + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_vk_create_rendertarget_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_rendertarget_view **view) +{ + struct wined3d_rendertarget_view_vk *view_vk; + HRESULT hr; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + if (!(view_vk = heap_alloc_zero(sizeof(*view_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_rendertarget_view_vk_init(view_vk, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_vk); + return hr; + } + + TRACE("Created render target view %p.\n", view_vk); + *view = &view_vk->v; + + return hr; +} + +static void adapter_vk_destroy_rendertarget_view(struct wined3d_rendertarget_view *view) +{ + struct wined3d_rendertarget_view_vk *view_vk = wined3d_rendertarget_view_vk(view); + struct wined3d_device *device = view_vk->v.resource->device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("view_vk %p.\n", view_vk); + + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_rendertarget_view_cleanup(&view_vk->v); + wined3d_cs_destroy_object(device->cs, heap_free, view_vk); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_vk_create_shader_resource_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view) +{ + struct wined3d_shader_resource_view_vk *view_vk; + HRESULT hr; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + if (!(view_vk = heap_alloc_zero(sizeof(*view_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_shader_resource_view_vk_init(view_vk, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_vk); + return hr; + } + + TRACE("Created shader resource view %p.\n", view_vk); + *view = &view_vk->v; + + return hr; +} + +static void adapter_vk_destroy_shader_resource_view(struct wined3d_shader_resource_view *view) +{ + struct wined3d_shader_resource_view_vk *view_vk = wined3d_shader_resource_view_vk(view); + struct wined3d_device *device = view_vk->v.resource->device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("view_vk %p.\n", view_vk); + + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_shader_resource_view_cleanup(&view_vk->v); + wined3d_cs_destroy_object(device->cs, heap_free, view_vk); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_vk_create_unordered_access_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view) +{ + struct wined3d_unordered_access_view_vk *view_vk; + HRESULT hr; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + if (!(view_vk = heap_alloc_zero(sizeof(*view_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_unordered_access_view_vk_init(view_vk, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_vk); + return hr; + } + + TRACE("Created unordered access view %p.\n", view_vk); + *view = &view_vk->v; + + return hr; +} + +static void adapter_vk_destroy_unordered_access_view(struct wined3d_unordered_access_view *view) +{ + struct wined3d_unordered_access_view_vk *view_vk = wined3d_unordered_access_view_vk(view); + struct wined3d_device *device = view_vk->v.resource->device; + unsigned int swapchain_count = device->swapchain_count; + + TRACE("view_vk %p.\n", view_vk); + + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_unordered_access_view_cleanup(&view_vk->v); + wined3d_cs_destroy_object(device->cs, heap_free, view_vk); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_vk_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler) +{ + struct wined3d_sampler *sampler_vk; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n", + device, desc, parent, parent_ops, sampler); + + if (!(sampler_vk = heap_alloc_zero(sizeof(*sampler_vk)))) + return E_OUTOFMEMORY; + + wined3d_sampler_vk_init(sampler_vk, device, desc, parent, parent_ops); + + TRACE("Created sampler %p.\n", sampler_vk); + *sampler = sampler_vk; + + return WINED3D_OK; +} + +static void adapter_vk_destroy_sampler(struct wined3d_sampler *sampler) +{ + TRACE("sampler %p.\n", sampler); + + wined3d_cs_destroy_object(sampler->device->cs, heap_free, sampler); +} + +static HRESULT adapter_vk_create_query(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) +{ + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + return WINED3DERR_NOTAVAILABLE; +} + +static void adapter_vk_destroy_query(struct wined3d_query *query) +{ + TRACE("query %p.\n", query); +} + +static void adapter_vk_flush_context(struct wined3d_context *context) +{ + TRACE("context %p.\n", context); +} + +void adapter_vk_clear_uav(struct wined3d_context *context, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) +{ + FIXME("context %p, view %p, clear_value %s.\n", context, view, debug_uvec4(clear_value)); +} + +static const struct wined3d_adapter_ops wined3d_adapter_vk_ops = +{ + adapter_vk_destroy, + adapter_vk_create_device, + adapter_vk_destroy_device, + adapter_vk_acquire_context, + adapter_vk_release_context, + adapter_vk_get_wined3d_caps, + adapter_vk_check_format, + adapter_vk_init_3d, + adapter_vk_uninit_3d, + adapter_vk_map_bo_address, + adapter_vk_unmap_bo_address, + adapter_vk_copy_bo_address, + adapter_vk_create_swapchain, + adapter_vk_destroy_swapchain, + adapter_vk_create_buffer, + adapter_vk_destroy_buffer, + adapter_vk_create_texture, + adapter_vk_destroy_texture, + adapter_vk_create_rendertarget_view, + adapter_vk_destroy_rendertarget_view, + adapter_vk_create_shader_resource_view, + adapter_vk_destroy_shader_resource_view, + adapter_vk_create_unordered_access_view, + adapter_vk_destroy_unordered_access_view, + adapter_vk_create_sampler, + adapter_vk_destroy_sampler, + adapter_vk_create_query, + adapter_vk_destroy_query, + adapter_vk_flush_context, + adapter_vk_clear_uav, +}; + +static unsigned int wined3d_get_wine_vk_version(void) +{ +#if __REACTOS__ + const char *ptr = "4.18"; +#else + const char *ptr = PACKAGE_VERSION; +#endif + int major, minor; + + major = atoi(ptr); + + while (isdigit(*ptr)) + ++ptr; + if (*ptr == '.') + ++ptr; + + minor = atoi(ptr); + + return VK_MAKE_VERSION(major, minor, 0); +} + +static const struct +{ + const char *name; + unsigned int core_since_version; + BOOL required; +} +vulkan_instance_extensions[] = +{ + {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1, FALSE}, +}; + +static BOOL enable_vulkan_instance_extensions(uint32_t *extension_count, + const char *enabled_extensions[], const struct wined3d_vk_info *vk_info) +{ + PFN_vkEnumerateInstanceExtensionProperties pfn_vkEnumerateInstanceExtensionProperties; + VkExtensionProperties *extensions = NULL; + BOOL success = FALSE, found; + unsigned int i, j, count; + VkResult vr; + + *extension_count = 0; + + if (!(pfn_vkEnumerateInstanceExtensionProperties + = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties")))) + { + WARN("Failed to get 'vkEnumerateInstanceExtensionProperties'.\n"); + goto done; + } + + if ((vr = pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, NULL)) < 0) + { + WARN("Failed to count instance extensions, vr %s.\n", wined3d_debug_vkresult(vr)); + goto done; + } + if (!(extensions = heap_calloc(count, sizeof(*extensions)))) + { + WARN("Out of memory.\n"); + goto done; + } + if ((vr = pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, extensions)) < 0) + { + WARN("Failed to enumerate extensions, vr %s.\n", wined3d_debug_vkresult(vr)); + goto done; + } + + for (i = 0; i < ARRAY_SIZE(vulkan_instance_extensions); ++i) + { + if (vulkan_instance_extensions[i].core_since_version <= vk_info->api_version) + continue; + + for (j = 0, found = FALSE; j < count; ++j) + { + if (!strcmp(extensions[j].extensionName, vulkan_instance_extensions[i].name)) + { + found = TRUE; + break; + } + } + if (found) + { + TRACE("Enabling instance extension '%s'.\n", vulkan_instance_extensions[i].name); + enabled_extensions[(*extension_count)++] = vulkan_instance_extensions[i].name; + } + else if (!found && vulkan_instance_extensions[i].required) + { + WARN("Required extension '%s' is not available.\n", vulkan_instance_extensions[i].name); + goto done; + } + } + success = TRUE; + +done: + heap_free(extensions); + return success; +} + +static BOOL wined3d_init_vulkan(struct wined3d_vk_info *vk_info) +{ + const char *enabled_instance_extensions[ARRAY_SIZE(vulkan_instance_extensions)]; + PFN_vkEnumerateInstanceVersion pfn_vkEnumerateInstanceVersion; + struct vulkan_ops *vk_ops = &vk_info->vk_ops; + VkInstance instance = VK_NULL_HANDLE; + VkInstanceCreateInfo instance_info; + VkApplicationInfo app_info; + uint32_t api_version = 0; + char app_name[MAX_PATH]; + VkResult vr; + + if (!wined3d_load_vulkan(vk_info)) + return FALSE; + + if (!(vk_ops->vkCreateInstance = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkCreateInstance")))) + { + ERR("Failed to get 'vkCreateInstance'.\n"); + goto fail; + } + + vk_info->api_version = VK_API_VERSION_1_0; + if ((pfn_vkEnumerateInstanceVersion = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion"))) + && pfn_vkEnumerateInstanceVersion(&api_version) == VK_SUCCESS) + { + TRACE("Vulkan instance API version %s.\n", debug_vk_version(api_version)); + + if (api_version >= VK_API_VERSION_1_1) + vk_info->api_version = VK_API_VERSION_1_1; + } + + memset(&app_info, 0, sizeof(app_info)); + app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + if (wined3d_get_app_name(app_name, ARRAY_SIZE(app_name))) + app_info.pApplicationName = app_name; + app_info.pEngineName = "Damavand"; + app_info.engineVersion = wined3d_get_wine_vk_version(); + app_info.apiVersion = vk_info->api_version; + + memset(&instance_info, 0, sizeof(instance_info)); + instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_info.pApplicationInfo = &app_info; + instance_info.ppEnabledExtensionNames = enabled_instance_extensions; + if (!enable_vulkan_instance_extensions(&instance_info.enabledExtensionCount, enabled_instance_extensions, vk_info)) + goto fail; + + if ((vr = VK_CALL(vkCreateInstance(&instance_info, NULL, &instance))) < 0) + { + WARN("Failed to create Vulkan instance, vr %s.\n", wined3d_debug_vkresult(vr)); + goto fail; + } + + TRACE("Created Vulkan instance %p.\n", instance); + +#define LOAD_INSTANCE_PFN(name) \ + if (!(vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name)))) \ + { \ + WARN("Could not get instance proc addr for '" #name "'.\n"); \ + goto fail; \ + } +#define LOAD_INSTANCE_OPT_PFN(name) \ + vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name)); +#define VK_INSTANCE_PFN LOAD_INSTANCE_PFN +#define VK_INSTANCE_EXT_PFN LOAD_INSTANCE_OPT_PFN +#define VK_DEVICE_PFN LOAD_INSTANCE_PFN + VK_INSTANCE_FUNCS() + VK_DEVICE_FUNCS() +#undef VK_INSTANCE_PFN +#undef VK_INSTANCE_EXT_PFN +#undef VK_DEVICE_PFN + +#define MAP_INSTANCE_FUNCTION(core_pfn, ext_pfn) \ + if (!vk_ops->core_pfn) \ + vk_ops->core_pfn = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #ext_pfn)); + MAP_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties2, vkGetPhysicalDeviceProperties2KHR) +#undef MAP_INSTANCE_FUNCTION + + vk_info->instance = instance; + + return TRUE; + +fail: + if (vk_ops->vkDestroyInstance) + VK_CALL(vkDestroyInstance(instance, NULL)); + wined3d_unload_vulkan(vk_info); + return FALSE; +} + +static VkPhysicalDevice get_vulkan_physical_device(struct wined3d_vk_info *vk_info) +{ + VkPhysicalDevice physical_devices[1]; + uint32_t count; + VkResult vr; + + if ((vr = VK_CALL(vkEnumeratePhysicalDevices(vk_info->instance, &count, NULL))) < 0) + { + WARN("Failed to enumerate physical devices, vr %s.\n", wined3d_debug_vkresult(vr)); + return VK_NULL_HANDLE; + } + if (!count) + { + WARN("No physical device.\n"); + return VK_NULL_HANDLE; + } + if (count > 1) + { + /* TODO: Create wined3d_adapter for each device. */ + FIXME("Multiple physical devices available.\n"); + count = 1; + } + + if ((vr = VK_CALL(vkEnumeratePhysicalDevices(vk_info->instance, &count, physical_devices))) < 0) + { + WARN("Failed to get physical devices, vr %s.\n", wined3d_debug_vkresult(vr)); + return VK_NULL_HANDLE; + } + + return physical_devices[0]; +} + +static enum wined3d_display_driver guess_display_driver(enum wined3d_pci_vendor vendor) +{ + switch (vendor) + { + case HW_VENDOR_AMD: return DRIVER_AMD_RX; + case HW_VENDOR_INTEL: return DRIVER_INTEL_HD4000; + case HW_VENDOR_NVIDIA: return DRIVER_NVIDIA_GEFORCE8; + default: return DRIVER_WINE; + } +} + +static void adapter_vk_init_driver_info(struct wined3d_adapter *adapter, + const VkPhysicalDeviceProperties *properties, const VkPhysicalDeviceMemoryProperties *memory_properties) +{ + const struct wined3d_gpu_description *gpu_description; + struct wined3d_gpu_description description; + UINT64 vram_bytes, sysmem_bytes; + const VkMemoryHeap *heap; + unsigned int i; + + TRACE("Device name: %s.\n", debugstr_a(properties->deviceName)); + TRACE("Vendor ID: 0x%04x, Device ID: 0x%04x.\n", properties->vendorID, properties->deviceID); + TRACE("Driver version: %#x.\n", properties->driverVersion); + TRACE("API version: %s.\n", debug_vk_version(properties->apiVersion)); + + for (i = 0, vram_bytes = 0, sysmem_bytes = 0; i < memory_properties->memoryHeapCount; ++i) + { + heap = &memory_properties->memoryHeaps[i]; + TRACE("Memory heap [%u]: flags %#x, size 0x%s.\n", + i, heap->flags, wine_dbgstr_longlong(heap->size)); + if (heap->flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + vram_bytes += heap->size; + else + sysmem_bytes += heap->size; + } + TRACE("Total device memory: 0x%s.\n", wine_dbgstr_longlong(vram_bytes)); + TRACE("Total shared system memory: 0x%s.\n", wine_dbgstr_longlong(sysmem_bytes)); + + if (!(gpu_description = wined3d_get_user_override_gpu_description(properties->vendorID, properties->deviceID))) + gpu_description = wined3d_get_gpu_description(properties->vendorID, properties->deviceID); + + if (!gpu_description) + { + FIXME("Failed to retrieve GPU description for device %s %04x:%04x.\n", + debugstr_a(properties->deviceName), properties->vendorID, properties->deviceID); + + description.vendor = properties->vendorID; + description.device = properties->deviceID; + description.description = properties->deviceName; + description.driver = guess_display_driver(properties->vendorID); + description.vidmem = vram_bytes; + + gpu_description = &description; + } + + wined3d_driver_info_init(&adapter->driver_info, gpu_description, vram_bytes, sysmem_bytes); +} + +static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter *adapter, uint32_t wined3d_creation_flags) +{ + struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; + + d3d_info->wined3d_creation_flags = wined3d_creation_flags; + + d3d_info->texture_swizzle = TRUE; + + d3d_info->multisample_draw_location = WINED3D_LOCATION_TEXTURE_RGB; +} + +static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk, + unsigned int ordinal, unsigned int wined3d_creation_flags) +{ + struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; + VkPhysicalDeviceMemoryProperties memory_properties; + struct wined3d_adapter *adapter = &adapter_vk->a; + VkPhysicalDeviceIDProperties id_properties; + VkPhysicalDeviceProperties2 properties2; + + TRACE("adapter_vk %p, ordinal %u, wined3d_creation_flags %#x.\n", + adapter_vk, ordinal, wined3d_creation_flags); + + if (!wined3d_adapter_init(adapter, ordinal, &wined3d_adapter_vk_ops)) + return FALSE; + + if (!wined3d_init_vulkan(vk_info)) + { + WARN("Failed to initialize Vulkan.\n"); + goto fail; + } + + if (!(adapter_vk->physical_device = get_vulkan_physical_device(vk_info))) + goto fail_vulkan; + + memset(&id_properties, 0, sizeof(id_properties)); + id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; + properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + properties2.pNext = &id_properties; + + if (vk_info->vk_ops.vkGetPhysicalDeviceProperties2) + VK_CALL(vkGetPhysicalDeviceProperties2(adapter_vk->physical_device, &properties2)); + else + VK_CALL(vkGetPhysicalDeviceProperties(adapter_vk->physical_device, &properties2.properties)); + adapter_vk->device_limits = properties2.properties.limits; + + VK_CALL(vkGetPhysicalDeviceMemoryProperties(adapter_vk->physical_device, &memory_properties)); + + adapter_vk_init_driver_info(adapter, &properties2.properties, &memory_properties); + adapter->vram_bytes_used = 0; + TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->driver_info.vram_bytes)); + + memcpy(&adapter->driver_uuid, id_properties.driverUUID, sizeof(adapter->driver_uuid)); + memcpy(&adapter->device_uuid, id_properties.deviceUUID, sizeof(adapter->device_uuid)); + + if (!wined3d_adapter_vk_init_format_info(adapter_vk, vk_info)) + goto fail_vulkan; + + adapter->vertex_pipe = &none_vertex_pipe; + adapter->fragment_pipe = &none_fragment_pipe; + adapter->shader_backend = &none_shader_backend; + + wined3d_adapter_vk_init_d3d_info(adapter, wined3d_creation_flags); + + return TRUE; + +fail_vulkan: + VK_CALL(vkDestroyInstance(vk_info->instance, NULL)); + wined3d_unload_vulkan(vk_info); +fail: + wined3d_adapter_cleanup(adapter); + return FALSE; +} + +struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal, + unsigned int wined3d_creation_flags) +{ + struct wined3d_adapter_vk *adapter_vk; + + if (!(adapter_vk = heap_alloc_zero(sizeof(*adapter_vk)))) + return NULL; + + if (!wined3d_adapter_vk_init(adapter_vk, ordinal, wined3d_creation_flags)) + { + heap_free(adapter_vk); + return NULL; + } + + TRACE("Created adapter %p.\n", adapter_vk); + + return &adapter_vk->a; +} diff --git a/dll/directx/wine/wined3d/arb_program_shader.c b/dll/directx/wine/wined3d/arb_program_shader.c index f86c167b606..34c3f061a94 100644 --- a/dll/directx/wine/wined3d/arb_program_shader.c +++ b/dll/directx/wine/wined3d/arb_program_shader.c @@ -177,8 +177,8 @@ struct arb_ps_compiled_shader { struct arb_ps_compile_args args; struct arb_ps_np2fixup_info np2fixup_info; - struct stb_const_desc bumpenvmatconst[MAX_TEXTURES]; - struct stb_const_desc luminanceconst[MAX_TEXTURES]; + struct stb_const_desc bumpenvmatconst[WINED3D_MAX_TEXTURES]; + struct stb_const_desc luminanceconst[WINED3D_MAX_TEXTURES]; UINT int_consts[WINED3D_MAX_CONSTS_I]; GLuint prgId; UINT ycorrection; @@ -226,7 +226,7 @@ struct recorded_instruction struct shader_arb_ctx_priv { - char addr_reg[20]; + char addr_reg[50]; enum { /* plain GL_ARB_vertex_program or GL_ARB_fragment_program */ @@ -304,7 +304,7 @@ struct shader_arb_priv const struct wined3d_context *last_context; const struct wined3d_vertex_pipe_ops *vertex_pipe; - const struct fragment_pipeline *fragment_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; BOOL ffp_proj_control; }; @@ -497,7 +497,7 @@ static unsigned int shader_arb_load_constants_f(const struct wined3d_shader *sha static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info *fixup, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) { - GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS]; + GLfloat np2fixup_constants[4 * WINED3D_MAX_FRAGMENT_SAMPLERS]; WORD active = fixup->super.active; UINT i; @@ -540,9 +540,9 @@ static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info /* Context activation is done by the caller. */ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *gl_shader, - const struct wined3d_context *context, const struct wined3d_state *state, UINT rt_height) + const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int rt_height) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned char i; for(i = 0; i < gl_shader->numbumpenvmatconsts; i++) @@ -576,8 +576,8 @@ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *g * ycorrection.w: 0.0 */ float val[4]; - val[0] = context->render_offscreen ? 0.0f : (float) rt_height; - val[1] = context->render_offscreen ? 1.0f : -1.0f; + val[0] = context_gl->c.render_offscreen ? 0.0f : (float)rt_height; + val[1] = context_gl->c.render_offscreen ? 1.0f : -1.0f; val[2] = 1.0f; val[3] = 0.0f; GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->ycorrection, val)); @@ -604,14 +604,14 @@ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *g /* Context activation is done by the caller. */ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *gl_shader, - const struct wined3d_context *context, const struct wined3d_state *state) + const struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; float position_fixup[4]; unsigned char i; /* Upload the position fixup */ - shader_get_position_fixup(context, state, position_fixup); + shader_get_position_fixup(&context_gl->c, state, 1, position_fixup); GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, position_fixup)); if (!gl_shader->num_int_consts) return; @@ -642,12 +642,11 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context * worry about the Integers or Booleans */ /* Context activation is done by the caller (state handler). */ -static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, - struct wined3d_context *context, const struct wined3d_state *state, - BOOL usePixelShader, BOOL useVertexShader, BOOL from_shader_select) +static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, struct wined3d_context_gl *context_gl, + const struct wined3d_state *state, BOOL use_ps, BOOL use_vs, BOOL from_shader_select) { - const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (!from_shader_select) { @@ -660,7 +659,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, && (vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts)))) { TRACE("bool/integer vertex shader constants potentially modified, forcing shader reselection.\n"); - shader_arb_select(priv, context, state); + shader_arb_select(priv, &context_gl->c, state); } else if (pshader && (pshader->reg_maps.boolean_constants @@ -668,11 +667,11 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, && (pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts)))) { TRACE("bool/integer pixel shader constants potentially modified, forcing shader reselection.\n"); - shader_arb_select(priv, context, state); + shader_arb_select(priv, &context_gl->c, state); } } - if (context != priv->last_context) + if (&context_gl->c != priv->last_context) { memset(priv->vshader_const_dirty, 1, sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count); @@ -682,10 +681,10 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count); priv->highest_dirty_ps_const = d3d_info->limits.ps_uniform_count; - priv->last_context = context; + priv->last_context = &context_gl->c; } - if (useVertexShader) + if (use_vs) { const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog; @@ -693,10 +692,10 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, /* Load DirectX 9 float constants for vertex shader */ priv->highest_dirty_vs_const = shader_arb_load_constants_f(vshader, gl_info, GL_VERTEX_PROGRAM_ARB, priv->highest_dirty_vs_const, state->vs_consts_f, priv->vshader_const_dirty); - shader_arb_vs_local_constants(gl_shader, context, state); + shader_arb_vs_local_constants(gl_shader, context_gl, state); } - if (usePixelShader) + if (use_ps) { const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; @@ -705,9 +704,9 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, /* Load DirectX 9 float constants for pixel shader */ priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty); - shader_arb_ps_local_constants(gl_shader, context, state, rt_height); + shader_arb_ps_local_constants(gl_shader, context_gl, state, rt_height); - if (context->constant_update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) + if (context_gl->c.constant_update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) shader_arb_load_np2fixup_constants(&gl_shader->np2fixup_info, gl_info, state); } } @@ -715,20 +714,18 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, static void shader_arb_load_constants(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { - BOOL vs = use_vs(state); - BOOL ps = use_ps(state); - - shader_arb_load_constants_internal(shader_priv, context, state, ps, vs, FALSE); + shader_arb_load_constants_internal(shader_priv, wined3d_context_gl(context), + state, use_ps(state), use_vs(state), FALSE); } static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) { - struct wined3d_context *context = context_get_current(); + struct wined3d_context_gl *context_gl = wined3d_context_gl_get_current(); struct shader_arb_priv *priv = device->shader_priv; /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || context->device != device) + if (!context_gl || context_gl->c.device != device) return; memset(priv->vshader_const_dirty + start, 1, sizeof(*priv->vshader_const_dirty) * count); @@ -737,12 +734,12 @@ static void shader_arb_update_float_vertex_constants(struct wined3d_device *devi static void shader_arb_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) { - struct wined3d_context *context = context_get_current(); + struct wined3d_context_gl *context_gl = wined3d_context_gl_get_current(); struct shader_arb_priv *priv = device->shader_priv; /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || context->device != device) + if (!context_gl || context_gl->c.device != device) return; memset(priv->pshader_const_dirty + start, 1, sizeof(*priv->pshader_const_dirty) * count); @@ -987,9 +984,10 @@ static void shader_arb_request_a0(const struct wined3d_shader_instruction *ins, struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; struct wined3d_string_buffer *buffer = ins->ctx->buffer; - if (!strcmp(priv->addr_reg, src)) return; + if (!strcmp(priv->addr_reg, src)) + return; - strcpy(priv->addr_reg, src); + snprintf(priv->addr_reg, sizeof(priv->addr_reg), "%s", src); shader_addline(buffer, "ARL A0.x, %s;\n", src); } @@ -1061,7 +1059,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction /* This is better than nothing for now */ sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset); } - else if(ctx->cur_ps_args->super.vp_mode != vertexshader) + else if(ctx->cur_ps_args->super.vp_mode != WINED3D_VP_MODE_SHADER) { /* This is problematic because we'd have to consult the ctx->ps_input strings * for where to find the varying. Some may be "0.0", others can be texcoords or @@ -1409,21 +1407,28 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx, const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy) { - enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type; + BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; struct wined3d_string_buffer *buffer = ins->ctx->buffer; - const char *tex_type; + enum wined3d_shader_resource_type resource_type; + struct color_fixup_masks masks; + const char *tex_dst = dst_str; BOOL np2_fixup = FALSE; - struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; + const char *tex_type; const char *mod; - BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); - const struct wined3d_shader *shader; - const struct wined3d_device *device; - const struct wined3d_gl_info *gl_info; - const char *tex_dst = dst_str; - struct color_fixup_masks masks; - /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */ - if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS; + if (pshader) + { + resource_type = pixelshader_get_resource_type(ins->ctx->reg_maps, sampler_idx, + priv->cur_ps_args->super.tex_types); + } + else + { + resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type; + + /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */ + sampler_idx += WINED3D_MAX_FRAGMENT_SAMPLERS; + } switch (resource_type) { @@ -1432,16 +1437,13 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD break; case WINED3D_SHADER_RESOURCE_TEXTURE_2D: - shader = ins->ctx->shader; - device = shader->device; - gl_info = &device->adapter->gl_info; - if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx) - && gl_info->supported[ARB_TEXTURE_RECTANGLE]) + && ins->ctx->gl_info->supported[ARB_TEXTURE_RECTANGLE]) tex_type = "RECT"; else tex_type = "2D"; - if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) + + if (pshader) { if (priv->cur_np2fixup_info->super.active & (1u << sampler_idx)) { @@ -1471,9 +1473,9 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD else mod = ""; /* Fragment samplers always have indentity mapping */ - if(sampler_idx >= MAX_FRAGMENT_SAMPLERS) + if(sampler_idx >= WINED3D_MAX_FRAGMENT_SAMPLERS) { - sampler_idx = priv->cur_vs_args->vertex.samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS]; + sampler_idx = priv->cur_vs_args->vertex.samplers[sampler_idx - WINED3D_MAX_FRAGMENT_SAMPLERS]; } if (pshader) @@ -2015,7 +2017,7 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) if (shader_version < WINED3D_SHADER_VERSION(1,4)) { DWORD flags = 0; - if (reg_sampler_code < MAX_TEXTURES) + if (reg_sampler_code < WINED3D_MAX_TEXTURES) flags = priv->cur_ps_args->super.tex_transform >> reg_sampler_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT; if (flags & WINED3D_PSARGS_PROJECTED) { @@ -2088,7 +2090,7 @@ static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins) /* Move .x first in case src_str is "TA" */ shader_addline(buffer, "MOV TA.y, %s.x;\n", src_str); shader_addline(buffer, "MOV TA.x, %s.w;\n", src_str); - if (reg1 < MAX_TEXTURES) + if (reg1 < WINED3D_MAX_TEXTURES) { struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; flags = priv->cur_ps_args->super.tex_transform >> reg1 * WINED3D_PSARGS_TEXTRANSFORM_SHIFT; @@ -2213,7 +2215,7 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins) shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name); - flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; + flags = reg < WINED3D_MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL); } @@ -2256,7 +2258,7 @@ static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins) /* Sample the texture using the calculated coordinates */ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); - flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; + flags = reg < WINED3D_MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; shader_hw_sample(ins, reg, dst_str, dst_name, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL); tex_mx->current_row = 0; } @@ -2297,7 +2299,7 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins /* Sample the texture using the calculated coordinates */ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); - flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; + flags = reg < WINED3D_MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL); tex_mx->current_row = 0; } @@ -2338,7 +2340,7 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins) /* Sample the texture using the calculated coordinates */ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); - flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; + flags = reg < WINED3D_MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0; shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL); tex_mx->current_row = 0; } @@ -3422,73 +3424,68 @@ static void init_ps_input(const struct wined3d_shader *shader, const char *semantic_name; DWORD semantic_idx; - switch(args->super.vp_mode) - { - case pretransformed: - case fixedfunction: - /* The pixelshader has to collect the varyings on its own. In any case properly load - * color0 and color1. In the case of pretransformed vertices also load texcoords. Set - * other attribs to 0.0. - * - * For fixedfunction this behavior is correct, according to the tests. For pretransformed - * we'd either need a replacement shader that can load other attribs like BINORMAL, or - * load the texcoord attrib pointers to match the pixel shader signature - */ - for (i = 0; i < shader->input_signature.element_count; ++i) - { - input = &shader->input_signature.elements[i]; - if (!(semantic_name = input->semantic_name)) - continue; - semantic_idx = input->semantic_idx; + if (args->super.vp_mode == WINED3D_VP_MODE_SHADER) + { + /* That one is easy. The vertex shaders provide v0-v7 in + * fragment.texcoord and v8 and v9 in fragment.color. */ + for (i = 0; i < 8; ++i) + { + priv->ps_input[i] = texcoords[i]; + } + priv->ps_input[8] = "fragment.color.primary"; + priv->ps_input[9] = "fragment.color.secondary"; + return; + } - if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR)) - { - if (!semantic_idx) - priv->ps_input[input->register_idx] = "fragment.color.primary"; - else if (semantic_idx == 1) - priv->ps_input[input->register_idx] = "fragment.color.secondary"; - else - priv->ps_input[input->register_idx] = "0.0"; - } - else if (args->super.vp_mode == fixedfunction) - { - priv->ps_input[input->register_idx] = "0.0"; - } - else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) - { - if (semantic_idx < 8) - priv->ps_input[input->register_idx] = texcoords[semantic_idx]; - else - priv->ps_input[input->register_idx] = "0.0"; - } - else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG)) - { - if (!semantic_idx) - priv->ps_input[input->register_idx] = "fragment.fogcoord"; - else - priv->ps_input[input->register_idx] = "0.0"; - } - else - { - priv->ps_input[input->register_idx] = "0.0"; - } + /* The fragment shader has to collect the varyings on its own. In any case + * properly load color0 and color1. In the case of pre-transformed + * vertices also load texture coordinates. Set other attributes to 0.0. + * + * For fixed-function this behavior is correct, according to the tests. + * For pre-transformed we'd either need a replacement shader that can load + * other attributes like BINORMAL, or load the texture coordinate + * attribute pointers to match the fragment shader signature. */ + for (i = 0; i < shader->input_signature.element_count; ++i) + { + input = &shader->input_signature.elements[i]; + if (!(semantic_name = input->semantic_name)) + continue; + semantic_idx = input->semantic_idx; - TRACE("v%u, semantic %s%u is %s\n", input->register_idx, - semantic_name, semantic_idx, priv->ps_input[input->register_idx]); - } - break; + if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR)) + { + if (!semantic_idx) + priv->ps_input[input->register_idx] = "fragment.color.primary"; + else if (semantic_idx == 1) + priv->ps_input[input->register_idx] = "fragment.color.secondary"; + else + priv->ps_input[input->register_idx] = "0.0"; + } + else if (args->super.vp_mode == WINED3D_VP_MODE_FF) + { + priv->ps_input[input->register_idx] = "0.0"; + } + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) + { + if (semantic_idx < 8) + priv->ps_input[input->register_idx] = texcoords[semantic_idx]; + else + priv->ps_input[input->register_idx] = "0.0"; + } + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG)) + { + if (!semantic_idx) + priv->ps_input[input->register_idx] = "fragment.fogcoord"; + else + priv->ps_input[input->register_idx] = "0.0"; + } + else + { + priv->ps_input[input->register_idx] = "0.0"; + } - case vertexshader: - /* That one is easy. The vertex shaders provide v0-v7 in fragment.texcoord and v8 and v9 in - * fragment.color - */ - for(i = 0; i < 8; i++) - { - priv->ps_input[i] = texcoords[i]; - } - priv->ps_input[8] = "fragment.color.primary"; - priv->ps_input[9] = "fragment.color.secondary"; - break; + TRACE("v%u, semantic %s%u is %s\n", input->register_idx, + semantic_name, semantic_idx, priv->ps_input[input->register_idx]); } } @@ -3671,10 +3668,10 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, if (args->super.srgb_correction) { shader_addline(buffer, "PARAM srgb_consts0 = "); - shader_arb_append_imm_vec4(buffer, wined3d_srgb_const0); + shader_arb_append_imm_vec4(buffer, &wined3d_srgb_const[0].x); shader_addline(buffer, ";\n"); shader_addline(buffer, "PARAM srgb_consts1 = "); - shader_arb_append_imm_vec4(buffer, wined3d_srgb_const1); + shader_arb_append_imm_vec4(buffer, &wined3d_srgb_const[1].x); shader_addline(buffer, ";\n"); } @@ -3760,7 +3757,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, /* Load constants to fixup NP2 texcoords if there are still free constants left: * Constants (texture dimensions) for the NP2 fixup are loaded as local program parameters. This will consume - * at most 8 (MAX_FRAGMENT_SAMPLERS / 2) parameters, which is highly unlikely, since the application had to + * at most 8 (WINED3D_MAX_FRAGMENT_SAMPLERS / 2) parameters, which is highly unlikely, since the application had to * use 16 NP2 textures at the same time. In case that we run out of constants the fixup is simply not * applied / activated. This will probably result in wrong rendering of the texture, but will save us from * shader compilation errors and the subsequent errors when drawing with this shader. */ @@ -3774,7 +3771,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, fixup->offset = next_local; fixup->super.active = 0; - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) { if (!(map & (1u << i))) continue; @@ -4241,12 +4238,12 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, } /* Context activation is done by the caller. */ -static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *shader, - const struct arb_ps_compile_args *args) +static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_context_gl *context_gl, + struct wined3d_shader *shader, const struct arb_ps_compile_args *args) { + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device *device = shader->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; UINT i; DWORD new_size; struct arb_ps_compiled_shader *new_array; @@ -4311,8 +4308,6 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args; - pixelshader_update_resource_types(shader, args->super.tex_types); - if (!string_buffer_init(&buffer)) { ERR("Failed to initialize shader buffer.\n"); @@ -4428,15 +4423,15 @@ static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *sh } static void find_arb_ps_compile_args(const struct wined3d_state *state, - const struct wined3d_context *context, const struct wined3d_shader *shader, + const struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader, struct arb_ps_compile_args *args) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; int i; WORD int_skip; - find_ps_compile_args(state, shader, context->stream_info.position_transformed, &args->super, context); + find_ps_compile_args(state, shader, context_gl->c.stream_info.position_transformed, &args->super, &context_gl->c); /* This forces all local boolean constants to 1 to make them stateblock independent */ args->bools = shader->reg_maps.local_bool_consts; @@ -4484,17 +4479,17 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state, } static void find_arb_vs_compile_args(const struct wined3d_state *state, - const struct wined3d_context *context, const struct wined3d_shader *shader, + const struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader, struct arb_vs_compile_args *args) { + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_device *device = shader->device; const struct wined3d_adapter *adapter = device->adapter; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; int i; WORD int_skip; - find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super, context); + find_vs_compile_args(state, shader, context_gl->c.stream_info.swizzle_map, &args->super, &context_gl->c); args->clip.boolclip_compare = 0; if (use_ps(state)) @@ -4509,7 +4504,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, { args->ps_signature = ~0; if (!d3d_info->vs_clipping && adapter->fragment_pipe == &arbfp_fragment_pipeline) - args->clip.boolclip.clip_texcoord = ffp_clip_emul(context) ? d3d_info->limits.ffp_blend_stages : 0; + args->clip.boolclip.clip_texcoord = ffp_clip_emul(&context_gl->c) ? d3d_info->limits.ffp_blend_stages : 0; /* Otherwise: Setting boolclip_compare set clip_texcoord to 0 */ } @@ -4529,9 +4524,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, args->clip.boolclip.bools |= (1u << i); } - args->vertex.samplers[0] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 0]; - args->vertex.samplers[1] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 1]; - args->vertex.samplers[2] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 2]; + args->vertex.samplers[0] = context_gl->tex_unit_map[WINED3D_MAX_FRAGMENT_SAMPLERS + 0]; + args->vertex.samplers[1] = context_gl->tex_unit_map[WINED3D_MAX_FRAGMENT_SAMPLERS + 1]; + args->vertex.samplers[2] = context_gl->tex_unit_map[WINED3D_MAX_FRAGMENT_SAMPLERS + 2]; args->vertex.samplers[3] = 0; /* Skip if unused or local */ @@ -4564,8 +4559,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, static void shader_arb_select(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct shader_arb_priv *priv = shader_priv; - const struct wined3d_gl_info *gl_info = context->gl_info; int i; /* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */ @@ -4576,8 +4572,8 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context struct arb_ps_compiled_shader *compiled; TRACE("Using pixel shader %p.\n", ps); - find_arb_ps_compile_args(state, context, ps, &compile_args); - compiled = find_arb_pshader(ps, &compile_args); + find_arb_ps_compile_args(state, context_gl, ps, &compile_args); + compiled = find_arb_pshader(context_gl, ps, &compile_args); priv->current_fprogram_id = compiled->prgId; priv->compiled_fprog = compiled; @@ -4586,7 +4582,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id);"); if (!priv->use_arbfp_fixed_func) - priv->fragment_pipe->enable_extension(gl_info, FALSE); + priv->fragment_pipe->fp_enable(context, FALSE); /* Enable OpenGL fragment programs. */ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); @@ -4606,12 +4602,12 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context priv->pshader_const_dirty[i] = 1; } /* Also takes care of loading local constants */ - shader_arb_load_constants_internal(shader_priv, context, state, TRUE, FALSE, TRUE); + shader_arb_load_constants_internal(shader_priv, context_gl, state, TRUE, FALSE, TRUE); } else { UINT rt_height = state->fb->render_targets[0]->height; - shader_arb_ps_local_constants(compiled, context, state, rt_height); + shader_arb_ps_local_constants(compiled, context_gl, state, rt_height); } /* Force constant reloading for the NP2 fixup (see comment in shader_glsl_select for more info) */ @@ -4633,7 +4629,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); priv->current_fprogram_id = 0; } - priv->fragment_pipe->enable_extension(gl_info, TRUE); + priv->fragment_pipe->fp_enable(context, TRUE); } if (use_vs(state)) @@ -4644,7 +4640,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context const struct wined3d_shader_signature *ps_input_sig; TRACE("Using vertex shader %p\n", vs); - find_arb_vs_compile_args(state, context, vs, &compile_args); + find_arb_vs_compile_args(state, context_gl, vs, &compile_args); /* Instead of searching for the signature in the signature list, read the one from the * current pixel shader. It's maybe not the shader where the signature came from, but it @@ -4654,7 +4650,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context else ps_input_sig = &state->shader[WINED3D_SHADER_TYPE_PIXEL]->input_signature; - compiled = find_arb_vshader(vs, context->gl_info, context->stream_info.use_map, + compiled = find_arb_vshader(vs, gl_info, context->stream_info.use_map, &compile_args, ps_input_sig); priv->current_vprogram_id = compiled->prgId; priv->compiled_vprog = compiled; @@ -4663,13 +4659,13 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id)); checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);"); - priv->vertex_pipe->vp_enable(gl_info, FALSE); + priv->vertex_pipe->vp_enable(context, FALSE); /* Enable OpenGL vertex programs */ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_ARB); checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);"); TRACE("Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", priv->current_vprogram_id); - shader_arb_vs_local_constants(compiled, context, state); + shader_arb_vs_local_constants(compiled, context_gl, state); if(priv->last_vs_color_unclamp != compiled->need_color_unclamp) { priv->last_vs_color_unclamp = compiled->need_color_unclamp; @@ -4694,7 +4690,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB); checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)"); } - priv->vertex_pipe->vp_enable(gl_info, TRUE); + priv->vertex_pipe->vp_enable(context, TRUE); } } @@ -4707,7 +4703,8 @@ static void shader_arb_select_compute(void *shader_priv, struct wined3d_context /* Context activation is done by the caller. */ static void shader_arb_disable(void *shader_priv, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct shader_arb_priv *priv = shader_priv; if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) @@ -4716,7 +4713,7 @@ static void shader_arb_disable(void *shader_priv, struct wined3d_context *contex checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); priv->current_fprogram_id = 0; } - priv->fragment_pipe->enable_extension(gl_info, FALSE); + priv->fragment_pipe->fp_enable(context, FALSE); if (gl_info->supported[ARB_VERTEX_PROGRAM]) { @@ -4724,7 +4721,7 @@ static void shader_arb_disable(void *shader_priv, struct wined3d_context *contex gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB); checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)"); } - priv->vertex_pipe->vp_enable(gl_info, FALSE); + priv->vertex_pipe->vp_enable(context, FALSE); if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT] && priv->last_vs_color_unclamp) { @@ -4744,56 +4741,42 @@ static void shader_arb_disable(void *shader_priv, struct wined3d_context *contex static void shader_arb_destroy(struct wined3d_shader *shader) { struct wined3d_device *device = shader->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + unsigned int i; + + /* This can happen if a shader was never compiled */ + if (!shader->backend_data) + return; + + context = context_acquire(device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; if (shader_is_pshader_version(shader->reg_maps.shader_version.type)) { struct arb_pshader_private *shader_data = shader->backend_data; - UINT i; - - if(!shader_data) return; /* This can happen if a shader was never compiled */ - - if (shader_data->num_gl_shaders) - { - struct wined3d_context *context = context_acquire(device, NULL, 0); - for (i = 0; i < shader_data->num_gl_shaders; ++i) - { - GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId)); - checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))"); - } - - context_release(context); - } + for (i = 0; i < shader_data->num_gl_shaders; ++i) + GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId)); heap_free(shader_data->gl_shaders); - heap_free(shader_data); - shader->backend_data = NULL; } else { struct arb_vshader_private *shader_data = shader->backend_data; - UINT i; - if(!shader_data) return; /* This can happen if a shader was never compiled */ + for (i = 0; i < shader_data->num_gl_shaders; ++i) + GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId)); - if (shader_data->num_gl_shaders) - { - struct wined3d_context *context = context_acquire(device, NULL, 0); + heap_free(shader_data->gl_shaders); + } - for (i = 0; i < shader_data->num_gl_shaders; ++i) - { - GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId)); - checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))"); - } + checkGLcall("delete programs"); - context_release(context); - } + context_release(context); - heap_free(shader_data->gl_shaders); - heap_free(shader_data); - shader->backend_data = NULL; - } + heap_free(shader->backend_data); + shader->backend_data = NULL; } static int sig_tree_compare(const void *key, const struct wine_rb_entry *entry) @@ -4803,7 +4786,7 @@ static int sig_tree_compare(const void *key, const struct wine_rb_entry *entry) } static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, - const struct fragment_pipeline *fragment_pipe) + const struct wined3d_fragment_pipe_ops *fragment_pipe) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct fragment_caps fragment_caps; @@ -4823,7 +4806,7 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wine if (!(fragment_priv = fragment_pipe->alloc_private(&arb_program_shader_backend, priv))) { ERR("Failed to initialize fragment pipe.\n"); - vertex_pipe->vp_free(device); + vertex_pipe->vp_free(device, NULL); heap_free(priv); return E_FAIL; } @@ -4837,7 +4820,7 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wine priv->vertex_pipe = vertex_pipe; priv->fragment_pipe = fragment_pipe; - fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps); + fragment_pipe->get_caps(device->adapter, &fragment_caps); priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; device->vertex_priv = vertex_priv; @@ -4861,13 +4844,13 @@ static void release_signature(struct wine_rb_entry *entry, void *context) } /* Context activation is done by the caller. */ -static void shader_arb_free(struct wined3d_device *device) +static void shader_arb_free(struct wined3d_device *device, struct wined3d_context *context) { struct shader_arb_priv *priv = device->shader_priv; wine_rb_destroy(&priv->signature_tree, release_signature, NULL); - priv->fragment_pipe->free_private(device); - priv->vertex_pipe->vp_free(device); + priv->fragment_pipe->free_private(device, context); + priv->vertex_pipe->vp_free(device, context); heap_free(device->shader_priv); } @@ -4887,8 +4870,10 @@ static void shader_arb_free_context_data(struct wined3d_context *context) static void shader_arb_init_context_state(struct wined3d_context *context) {} -static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) +static void shader_arb_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + if (gl_info->supported[ARB_VERTEX_PROGRAM]) { DWORD vs_consts; @@ -5096,7 +5081,6 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL /* WINED3DSIH_DSY */ shader_hw_dsy, /* WINED3DSIH_DSY_COARSE */ NULL, /* WINED3DSIH_DSY_FINE */ NULL, - /* WINED3DSIH_EVAL_SAMPLE_INDEX */ NULL, /* WINED3DSIH_ELSE */ shader_hw_else, /* WINED3DSIH_EMIT */ NULL, /* WINED3DSIH_EMIT_STREAM */ NULL, @@ -5105,6 +5089,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL /* WINED3DSIH_ENDREP */ shader_hw_endrep, /* WINED3DSIH_ENDSWITCH */ NULL, /* WINED3DSIH_EQ */ NULL, + /* WINED3DSIH_EVAL_SAMPLE_INDEX */ NULL, /* WINED3DSIH_EXP */ shader_hw_scalar_op, /* WINED3DSIH_EXPP */ shader_hw_scalar_op, /* WINED3DSIH_F16TOF32 */ NULL, @@ -5701,8 +5686,10 @@ struct arbfp_ffp_desc }; /* Context activation is done by the caller. */ -static void arbfp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) +static void arbfp_enable(const struct wined3d_context *context, BOOL enable) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + if (enable) { gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); @@ -5735,30 +5722,35 @@ static void *arbfp_alloc(const struct wined3d_shader_backend_ops *shader_backend } /* Context activation is done by the caller. */ -static void arbfp_free_ffpshader(struct wine_rb_entry *entry, void *context) +static void arbfp_free_ffpshader(struct wine_rb_entry *entry, void *param) { - const struct wined3d_gl_info *gl_info = context; struct arbfp_ffp_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_ffp_desc, parent.entry); + struct wined3d_context_gl *context_gl = param; + const struct wined3d_gl_info *gl_info; + gl_info = context_gl->gl_info; GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader)); - checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)"); + checkGLcall("delete ffp program"); heap_free(entry_arb); } /* Context activation is done by the caller. */ -static void arbfp_free(struct wined3d_device *device) +static void arbfp_free(struct wined3d_device *device, struct wined3d_context *context) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct shader_arb_priv *priv = device->fragment_priv; - wine_rb_destroy(&priv->fragment_shaders, arbfp_free_ffpshader, &device->adapter->gl_info); + wine_rb_destroy(&priv->fragment_shaders, arbfp_free_ffpshader, context_gl); priv->use_arbfp_fixed_func = FALSE; if (device->shader_backend != &arb_program_shader_backend) heap_free(device->fragment_priv); } -static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) +static void arbfp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL | WINED3D_FRAGMENT_CAP_SRGB_WRITE | WINED3D_FRAGMENT_CAP_COLOR_KEY; @@ -5791,8 +5783,8 @@ static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen /* TODO: Implement WINED3DTEXOPCAPS_PREMODULATE */ - caps->MaxTextureBlendStages = MAX_TEXTURES; - caps->MaxSimultaneousTextures = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_TEXTURES); + caps->MaxTextureBlendStages = WINED3D_MAX_TEXTURES; + caps->MaxSimultaneousTextures = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], WINED3D_MAX_TEXTURES); } static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info) @@ -5803,7 +5795,8 @@ static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info) static void state_texfactor_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device *device = context->device; struct wined3d_color color; @@ -5830,7 +5823,8 @@ static void state_tss_constant_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device *device = context->device; struct wined3d_color color; @@ -5857,7 +5851,8 @@ static void state_tss_constant_arbfp(struct wined3d_context *context, static void state_arb_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device *device = context->device; float col[4]; @@ -5892,7 +5887,8 @@ static void state_arb_specularenable(struct wined3d_context *context, static void set_bumpmat_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device *device = context->device; float mat[2][2]; @@ -5923,7 +5919,8 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device *device = context->device; float param[4]; @@ -5952,7 +5949,8 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, static void alpha_test_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; int glParm; float ref; @@ -5970,7 +5968,7 @@ static void alpha_test_arbfp(struct wined3d_context *context, const struct wined return; } - ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f; + ref = wined3d_alpha_ref(state); glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]); if (glParm) @@ -5982,8 +5980,9 @@ static void alpha_test_arbfp(struct wined3d_context *context, const struct wined static void color_key_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_texture *texture = state->textures[0]; - const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_device *device = context->device; struct wined3d_color float_key[2]; @@ -6084,17 +6083,19 @@ static const char *get_argreg(struct wined3d_string_buffer *buffer, DWORD argnum } static void gen_ffp_instr(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color, - BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) + BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) { const char *dstmask, *dstreg, *arg0, *arg1, *arg2; unsigned int mul = 1; - if(color && alpha) dstmask = ""; - else if(color) dstmask = ".xyz"; - else dstmask = ".w"; + if (color && alpha) + dstmask = ""; + else if (color) + dstmask = ".xyz"; + else + dstmask = ".w"; - if(dst == tempreg) dstreg = "tempreg"; - else dstreg = "ret"; + dstreg = tmp_dst ? "tempreg" : "ret"; arg0 = get_argreg(buffer, 0, stage, dw_arg0); arg1 = get_argreg(buffer, 1, stage, dw_arg1); @@ -6262,7 +6263,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con } /* Find out which textures are read */ - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (settings->op[stage].cop == WINED3D_TOP_DISABLE) break; @@ -6273,7 +6274,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE) tex_read |= 1u << stage; - if (settings->op[stage].dst == tempreg) + if (settings->op[stage].tmp_dst) tempreg_used = TRUE; if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; @@ -6345,7 +6346,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "TEMP arg0;\n"); shader_addline(&buffer, "TEMP arg1;\n"); shader_addline(&buffer, "TEMP arg2;\n"); - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (constant_used & (1u << stage)) shader_addline(&buffer, "PARAM const%u = program.env[%u];\n", stage, ARB_FFP_CONST_CONSTANT(stage)); @@ -6370,10 +6371,10 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con if (settings->sRGB_write) { shader_addline(&buffer, "PARAM srgb_consts0 = "); - shader_arb_append_imm_vec4(&buffer, wined3d_srgb_const0); + shader_arb_append_imm_vec4(&buffer, &wined3d_srgb_const[0].x); shader_addline(&buffer, ";\n"); shader_addline(&buffer, "PARAM srgb_consts1 = "); - shader_arb_append_imm_vec4(&buffer, wined3d_srgb_const1); + shader_arb_append_imm_vec4(&buffer, &wined3d_srgb_const[1].x); shader_addline(&buffer, ";\n"); } @@ -6384,19 +6385,24 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "MOV tempreg, 0.0;\n"); /* Generate texture sampling instructions */ - for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage) { if (!(tex_read & (1u << stage))) continue; textype = arbfp_texture_target(settings->op[stage].tex_type); - if(settings->op[stage].projected == proj_none) { + if (settings->op[stage].projected == WINED3D_PROJECTION_NONE) + { instr = "TEX"; - } else if(settings->op[stage].projected == proj_count4 || - settings->op[stage].projected == proj_count3) { + } + else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4 + || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) + { instr = "TXP"; - } else { + } + else + { FIXME("Unexpected projection mode %d\n", settings->op[stage].projected); instr = "TXP"; } @@ -6410,18 +6416,27 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1); shader_addline(&buffer, "DP3 ret.y, arg1, tex%u;\n", stage - 1); - /* with projective textures, texbem only divides the static texture coord, not the displacement, - * so multiply the displacement with the dividing parameter before passing it to TXP - */ - if (settings->op[stage].projected != proj_none) { - if(settings->op[stage].projected == proj_count4) { + /* With projective textures, texbem only divides the static + * texture coordinate, not the displacement, so multiply the + * displacement with the dividing parameter before passing it to + * TXP. */ + if (settings->op[stage].projected != WINED3D_PROJECTION_NONE) + { + if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4) + { shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].w;\n", stage); - shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", stage, stage); - } else { + shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", + stage, stage); + } + else + { shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].z;\n", stage); - shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", stage, stage); + shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", + stage, stage); } - } else { + } + else + { shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage); } @@ -6433,12 +6448,16 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con stage - 1, stage - 1, stage - 1); shader_addline(&buffer, "MUL tex%u, tex%u, ret.x;\n", stage, stage); } - } else if(settings->op[stage].projected == proj_count3) { + } + else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) + { shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage); shader_addline(&buffer, "MOV ret.w, ret.z;\n"); shader_addline(&buffer, "%s tex%u, ret, texture[%u], %s;\n", instr, stage, stage, textype); - } else { + } + else + { shader_addline(&buffer, "%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n", instr, stage, stage, stage, textype); } @@ -6462,7 +6481,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "MOV ret, fragment.color.primary;\n"); /* Generate the main shader */ - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (settings->op[stage].cop == WINED3D_TOP_DISABLE) break; @@ -6487,23 +6506,23 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con if (settings->op[stage].aop == WINED3D_TOP_DISABLE) { - gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst, + gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (op_equal) { - gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst, + gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE) { - gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst, + gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); - gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].dst, + gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst, settings->op[stage].aop, settings->op[stage].aarg0, settings->op[stage].aarg1, settings->op[stage].aarg2); } @@ -6537,7 +6556,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con static void fragment_prog_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_device *device = context->device; struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(state); @@ -6553,7 +6573,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi { /* Reload fixed function constants since they collide with the * pixel shader constants. */ - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); @@ -6604,7 +6624,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi { /* Reload fixed function constants since they collide with the * pixel shader constants. */ - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); @@ -6678,7 +6698,7 @@ static void textransform(struct wined3d_context *context, const struct wined3d_s fragment_prog_arbfp(context, state, state_id); } -static const struct StateEntryTemplate arbfp_fragmentstate_template[] = +static const struct wined3d_state_entry_template arbfp_fragmentstate_template[] = { {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, @@ -6846,7 +6866,8 @@ static void arbfp_free_context_data(struct wined3d_context *context) { } -const struct fragment_pipeline arbfp_fragment_pipeline = { +const struct wined3d_fragment_pipe_ops arbfp_fragment_pipeline = +{ arbfp_enable, arbfp_get_caps, arbfp_get_emul_mask, @@ -6897,10 +6918,10 @@ static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *ctx) { struct arbfp_blit_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry); const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; - context = ctx; - gl_info = context->gl_info; + context_gl = ctx; + gl_info = context_gl->gl_info; GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader)); checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)"); @@ -6910,16 +6931,17 @@ static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *ctx) /* Context activation is done by the caller. */ static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_arbfp_blitter *arbfp_blitter; struct wined3d_blitter *next; if ((next = blitter->next)) - next->ops->blitter_destroy(next, context); + next->ops->blitter_destroy(next, &context_gl->c); arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter); - wine_rb_destroy(&arbfp_blitter->shaders, arbfp_free_blit_shader, context); + wine_rb_destroy(&arbfp_blitter->shaders, arbfp_free_blit_shader, context_gl); checkGLcall("Delete blit programs"); if (arbfp_blitter->palette_texture) @@ -6928,8 +6950,8 @@ static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3 heap_free(arbfp_blitter); } -static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, - char *luminance) +static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer, + const struct arbfp_blit_type *type, char *luminance) { char chroma; const char *tex, *texinstr = "TXP"; @@ -6977,13 +6999,12 @@ static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const stru shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n"); shader_addline(buffer, "ADD texcrd.x, texcrd.x, coef.y;\n"); - /* Divide the x coordinate by 0.5 and get the fraction. This gives 0.25 and 0.75 for the - * even and odd pixels respectively - */ + /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25 + * and 0.75 for the even and odd pixels respectively. */ shader_addline(buffer, "MUL texcrd2, texcrd, coef.y;\n"); shader_addline(buffer, "FRC texcrd2, texcrd2;\n"); - /* Sample Pixel 1 */ + /* Sample Pixel 1. */ shader_addline(buffer, "%s luminance, texcrd, texture[0], %s;\n", texinstr, tex); /* Put the value into either of the chroma values */ @@ -7012,12 +7033,10 @@ static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const stru /* This gives the correctly filtered luminance value */ shader_addline(buffer, "TEX luminance, fragment.texcoord[0], texture[0], %s;\n", tex); - - return TRUE; } -static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, - char *luminance) +static void gen_yv12_read(struct wined3d_string_buffer *buffer, + const struct arbfp_blit_type *type, char *luminance) { const char *tex; static const float yv12_coef[] @@ -7079,7 +7098,6 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arb */ if (type->res_type == WINED3D_GL_RES_TYPE_TEX_2D) { - shader_addline(buffer, "RCP chroma.w, size.y;\n"); shader_addline(buffer, "MUL texcrd2.y, texcrd.y, size.y;\n"); @@ -7087,7 +7105,7 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arb shader_addline(buffer, "FLR texcrd2.y, texcrd2.y;\n"); shader_addline(buffer, "MAD texcrd.y, texcrd.y, yv12_coef.y, yv12_coef.x;\n"); - /* Read odd lines from the right side(add size * 0.5 to the x coordinate */ + /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */ shader_addline(buffer, "ADD texcrd2.x, texcrd2.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */ shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n"); shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n"); @@ -7101,11 +7119,11 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arb } else { - /* Read from [size - size+size/4] */ + /* The y coordinate for V is in the range [size, size + size / 4). */ shader_addline(buffer, "FLR texcrd.y, texcrd.y;\n"); shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.w, size.y;\n"); - /* Read odd lines from the right side(add size * 0.5 to the x coordinate */ + /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */ shader_addline(buffer, "ADD texcrd2.x, texcrd.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */ shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n"); shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n"); @@ -7161,12 +7179,10 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arb shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex); } *luminance = 'a'; - - return TRUE; } -static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, - char *luminance) +static void gen_nv12_read(struct wined3d_string_buffer *buffer, + const struct arbfp_blit_type *type, char *luminance) { const char *tex; static const float nv12_coef[] @@ -7242,7 +7258,7 @@ static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arb } else { - /* Read from [size - size+size/2] */ + /* The y coordinate for chroma is in the range [size, size + size / 2). */ shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.y, size.y;\n"); shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n"); @@ -7297,8 +7313,6 @@ static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arb shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex); } *luminance = 'a'; - - return TRUE; } /* Context activation is done by the caller. */ @@ -7352,11 +7366,11 @@ static GLuint gen_p8_shader(const struct wined3d_gl_info *gl_info, const struct } /* Context activation is done by the caller. */ -static void upload_palette(struct wined3d_arbfp_blitter *blitter, - const struct wined3d_texture *texture, struct wined3d_context *context) +static void arbfp_blitter_upload_palette(struct wined3d_arbfp_blitter *blitter, + const struct wined3d_texture_gl *texture_gl, struct wined3d_context_gl *context_gl) { - const struct wined3d_palette *palette = texture->swapchain ? texture->swapchain->palette : NULL; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_palette *palette = texture_gl->t.swapchain ? texture_gl->t.swapchain->palette : NULL; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (!blitter->palette_texture) gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture); @@ -7385,7 +7399,7 @@ static void upload_palette(struct wined3d_arbfp_blitter *blitter, } /* Switch back to unit 0 in which the 2D texture will be stored. */ - context_active_texture(context, gl_info, 0); + wined3d_context_gl_active_texture(context_gl, gl_info, 0); } /* Context activation is done by the caller. */ @@ -7464,27 +7478,15 @@ static GLuint gen_yuv_shader(const struct wined3d_gl_info *gl_info, const struct { case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YUY2: - if (!gen_planar_yuv_read(&buffer, type, &luminance_component)) - { - string_buffer_free(&buffer); - return 0; - } + gen_packed_yuv_read(&buffer, type, &luminance_component); break; case COMPLEX_FIXUP_YV12: - if (!gen_yv12_read(&buffer, type, &luminance_component)) - { - string_buffer_free(&buffer); - return 0; - } + gen_yv12_read(&buffer, type, &luminance_component); break; case COMPLEX_FIXUP_NV12: - if (!gen_nv12_read(&buffer, type, &luminance_component)) - { - string_buffer_free(&buffer); - return 0; - } + gen_nv12_read(&buffer, type, &luminance_component); break; default: @@ -7566,12 +7568,12 @@ static GLuint arbfp_gen_plain_shader(const struct wined3d_gl_info *gl_info, cons } /* Context activation is done by the caller. */ -static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wined3d_context *context, - const struct wined3d_texture *texture, unsigned int sub_resource_idx, +static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wined3d_context_gl *context_gl, + const struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, const struct wined3d_color_key *color_key) { + const struct wined3d_gl_info *gl_info = context_gl->gl_info; enum complex_fixup fixup; - const struct wined3d_gl_info *gl_info = context->gl_info; struct wine_rb_entry *entry; struct arbfp_blit_type type; struct arbfp_blit_desc *desc; @@ -7580,18 +7582,18 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine unsigned int level; GLuint shader; - level = sub_resource_idx % texture->level_count; - size.x = wined3d_texture_get_level_pow2_width(texture, level); - size.y = wined3d_texture_get_level_pow2_height(texture, level); + level = sub_resource_idx % texture_gl->t.level_count; + size.x = wined3d_texture_get_level_pow2_width(&texture_gl->t, level); + size.y = wined3d_texture_get_level_pow2_height(&texture_gl->t, level); size.z = 1.0f; size.w = 1.0f; - if (is_complex_fixup(texture->resource.format->color_fixup)) - fixup = get_complex_fixup(texture->resource.format->color_fixup); + if (is_complex_fixup(texture_gl->t.resource.format->color_fixup)) + fixup = get_complex_fixup(texture_gl->t.resource.format->color_fixup); else fixup = COMPLEX_FIXUP_NONE; - switch (texture->target) + switch (texture_gl->target) { case GL_TEXTURE_1D: type.res_type = WINED3D_GL_RES_TYPE_TEX_1D; @@ -7614,7 +7616,7 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine break; default: - ERR("Unexpected GL texture type %#x.\n", texture->target); + ERR("Unexpected GL texture type %#x.\n", texture_gl->target); type.res_type = WINED3D_GL_RES_TYPE_TEX_2D; } type.fixup = fixup; @@ -7631,7 +7633,7 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine switch (fixup) { case COMPLEX_FIXUP_NONE: - if (!is_identity_fixup(texture->resource.format->color_fixup)) + if (!is_identity_fixup(texture_gl->t.resource.format->color_fixup)) FIXME("Implement support for sign or swizzle fixups.\n"); shader = arbfp_gen_plain_shader(gl_info, &type); break; @@ -7673,7 +7675,7 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine } if (fixup == COMPLEX_FIXUP_P8) - upload_palette(blitter, texture, context); + arbfp_blitter_upload_palette(blitter, texture_gl, context_gl); gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)"); @@ -7683,7 +7685,7 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine checkGLcall("glProgramLocalParameter4fvARB"); if (type.use_color_key) { - wined3d_format_get_float_color_key(texture->resource.format, color_key, float_color_key); + wined3d_format_get_float_color_key(texture_gl->t.resource.format, color_key, float_color_key); GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARBFP_BLIT_PARAM_COLOR_KEY_LOW, &float_color_key[0].r)); GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, @@ -7710,7 +7712,7 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine enum complex_fixup src_fixup; BOOL decompress; - if (!context->gl_info->supported[ARB_FRAGMENT_PROGRAM]) + if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) return FALSE; if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id) @@ -7739,7 +7741,7 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine return FALSE; } - decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + decompress = (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) return FALSE; @@ -7795,59 +7797,109 @@ static BOOL arbfp_blit_supported(enum wined3d_blit_op blit_op, const struct wine } static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, - const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, + unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - struct wined3d_texture *src_texture = src_surface->container; - struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct wined3d_device *device = dst_texture->resource.device; + struct wined3d_texture *staging_texture = NULL; struct wined3d_arbfp_blitter *arbfp_blitter; struct wined3d_color_key alpha_test_key; struct wined3d_blitter *next; + unsigned int src_level; RECT s, d; + TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), + wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), + wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter)); + if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location, &dst_texture->resource, dst_location)) { - if ((next = blitter->next)) - return next->ops->blitter_blit(next, op, context, src_surface, src_location, - src_rect, dst_surface, dst_location, dst_rect, color_key, filter); + if (!(next = blitter->next)) + { + ERR("No blitter to handle blit op %#x.\n", op); + return dst_location; + } + + TRACE("Forwarding to blitter %p.\n", next); + return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter); } arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter); - /* Now load the surface */ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && (surface_get_sub_resource(src_surface)->locations - & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) - == WINED3D_LOCATION_DRAWABLE + if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + struct wined3d_resource_desc desc; + struct wined3d_box upload_box; + HRESULT hr; + + TRACE("Source texture is not GPU accessible, creating a staging texture.\n"); + + src_level = src_sub_resource_idx % src_texture->level_count; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + desc.format = src_texture->resource.format->id; + desc.multisample_type = src_texture->resource.multisample_type; + desc.multisample_quality = src_texture->resource.multisample_quality; + desc.usage = WINED3DUSAGE_PRIVATE; + desc.bind_flags = 0; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + desc.width = wined3d_texture_get_level_width(src_texture, src_level); + desc.height = wined3d_texture_get_level_height(src_texture, src_level); + desc.depth = 1; + desc.size = 0; + + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0, + NULL, NULL, &wined3d_null_parent_ops, &staging_texture))) + { + ERR("Failed to create staging texture, hr %#x.\n", hr); + return dst_location; + } + + wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth); + wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0, + src_texture, src_sub_resource_idx, &upload_box); + + src_texture = staging_texture; + src_texture_gl = wined3d_texture_gl(src_texture); + src_sub_resource_idx = 0; + } + else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && (src_texture->sub_resources[src_sub_resource_idx].locations + & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE && !wined3d_resource_is_offscreen(&src_texture->resource)) { - unsigned int src_level = src_sub_resource_idx % src_texture->level_count; /* Without FBO blits transferring from the drawable to the texture is * expensive, because we have to flip the data in sysmem. Since we can * flip in the blitter, we don't actually need that flip anyway. So we * use the surface's texture as scratch texture, and flip the source * rectangle instead. */ - surface_load_fb_texture(src_surface, FALSE, context); + texture2d_load_fb_texture(src_texture_gl, src_sub_resource_idx, FALSE, context); s = *src_rect; + src_level = src_sub_resource_idx % src_texture->level_count; s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top; s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom; src_rect = &s; } else + { wined3d_texture_load(src_texture, context, FALSE); + } - context_apply_blit_state(context, device); + wined3d_context_gl_apply_ffp_blit_state(context_gl, device); if (dst_location == WINED3D_LOCATION_DRAWABLE) { d = *dst_rect; - surface_translate_drawable_coords(dst_surface, context->win_handle, &d); + wined3d_texture_translate_drawable_coords(dst_texture, context_gl->window, &d); dst_rect = &d; } @@ -7857,17 +7909,18 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl if (dst_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Destination surface %p is onscreen.\n", dst_surface); + TRACE("Destination texture %p is onscreen.\n", dst_texture); buffer = wined3d_texture_get_gl_buffer(dst_texture); } else { - TRACE("Destination surface %p is offscreen.\n", dst_surface); + TRACE("Destination texture %p is offscreen.\n", dst_texture); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); - context_set_draw_buffer(context, buffer); - context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, + &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location); + wined3d_context_gl_set_draw_buffer(context_gl, buffer); + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); } @@ -7879,17 +7932,20 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl color_key = &alpha_test_key; } - arbfp_blit_set(arbfp_blitter, context, src_texture, src_sub_resource_idx, color_key); + arbfp_blit_set(arbfp_blitter, context_gl, src_texture_gl, src_sub_resource_idx, color_key); /* Draw a textured quad */ - draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter); + wined3d_context_gl_draw_textured_quad(context_gl, src_texture_gl, + src_sub_resource_idx, src_rect, dst_rect, filter); /* Leave the opengl state valid for blitting */ - arbfp_blit_unset(context->gl_info); + arbfp_blit_unset(context_gl->gl_info); + + if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture)) + context_gl->gl_info->gl_ops.gl.p_glFlush(); - if (wined3d_settings.strict_draw_ordering - || (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))) - context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + if (staging_texture) + wined3d_texture_decref(staging_texture); return dst_location; } diff --git a/dll/directx/wine/wined3d/ati_fragment_shader.c b/dll/directx/wine/wined3d/ati_fragment_shader.c index 9d6837a2f22..ae2843db403 100644 --- a/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -52,7 +52,7 @@ struct atifs_ffp_desc struct ffp_frag_desc parent; GLuint shader; unsigned int num_textures_used; - enum atifs_constant_value constants[MAX_TEXTURES]; + enum atifs_constant_value constants[WINED3D_MAX_TEXTURES]; }; struct atifs_private_data @@ -322,15 +322,15 @@ static GLuint register_for_arg(DWORD arg, const struct wined3d_gl_info *gl_info, return ret; } -static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES]) +static GLuint find_tmpreg(const struct texture_stage_op op[WINED3D_MAX_TEXTURES]) { int lowest_read = -1; int lowest_write = -1; int i; - BOOL tex_used[MAX_TEXTURES]; + BOOL tex_used[WINED3D_MAX_TEXTURES]; memset(tex_used, 0, sizeof(tex_used)); - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (op[i].cop == WINED3D_TOP_DISABLE) break; @@ -341,9 +341,8 @@ static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES]) lowest_read = i; } - if(lowest_write == -1 && op[i].dst == tempreg) { + if (lowest_write == -1 && op[i].tmp_dst) lowest_write = i; - } if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE || op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) { @@ -468,7 +467,7 @@ static BOOL op_reads_constant(const struct texture_stage_op *op) || (op->aarg2 & WINED3DTA_SELECTMASK) == WINED3DTA_CONSTANT; } -static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], +static GLuint gen_ati_shader(const struct texture_stage_op op[WINED3D_MAX_TEXTURES], const struct wined3d_gl_info *gl_info, enum atifs_constant_value *constants) { GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1)); @@ -505,16 +504,13 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, GL_SWIZZLE_STR_ATI)\n", stage, stage); - GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, - GL_TEXTURE0_ARB + stage, - GL_SWIZZLE_STR_ATI)); - if(op[stage + 1].projected == proj_none) { + GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, GL_TEXTURE0_ARB + stage, GL_SWIZZLE_STR_ATI)); + if (op[stage + 1].projected == WINED3D_PROJECTION_NONE) swizzle = GL_SWIZZLE_STR_ATI; - } else if(op[stage + 1].projected == proj_count4) { + else if (op[stage + 1].projected == WINED3D_PROJECTION_COUNT4) swizzle = GL_SWIZZLE_STQ_DQ_ATI; - } else { + else swizzle = GL_SWIZZLE_STR_DR_ATI; - } TRACE("glPassTexCoordATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, %s)\n", stage + 1, stage + 1, debug_swizzle(swizzle)); GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1, @@ -579,13 +575,12 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], if (op[stage].cop == WINED3D_TOP_DISABLE) break; - if(op[stage].projected == proj_none) { + if (op[stage].projected == WINED3D_PROJECTION_NONE) swizzle = GL_SWIZZLE_STR_ATI; - } else if(op[stage].projected == proj_count3) { + else if (op[stage].projected == WINED3D_PROJECTION_COUNT3) swizzle = GL_SWIZZLE_STR_DR_ATI; - } else { + else swizzle = GL_SWIZZLE_STQ_DQ_ATI; - } if (op_reads_texture(&op[stage])) { @@ -609,7 +604,7 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], } /* Pass 4: Generate the arithmetic instructions */ - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (op[stage].cop == WINED3D_TOP_DISABLE) { @@ -624,14 +619,18 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], break; } - if(op[stage].dst == tempreg) { - /* If we're writing to D3DTA_TEMP, but never reading from it we don't have to write there in the first place. - * skip the entire stage, this saves some GPU time - */ - if(tmparg == GL_NONE) continue; + if (op[stage].tmp_dst) + { + /* If we're writing to D3DTA_TEMP, but never reading from it we + * don't have to write there in the first place. Skip the entire + * stage, this saves some GPU time. */ + if (tmparg == GL_NONE) + continue; dstreg = tmparg; - } else { + } + else + { dstreg = GL_REG_0_ATI; } @@ -937,7 +936,7 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], constants[ATIFS_CONST_TFACTOR - GL_CON_0_ATI] = ATIFS_CONSTANT_TFACTOR; /* Assign unused constants to avoid reloading due to unused <-> bump matrix switches. */ - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (constants[stage] == ATIFS_CONSTANT_UNUSED) constants[stage] = ATIFS_CONSTANT_BUMP; @@ -951,8 +950,9 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], static void atifs_tfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_color color; if (!ctx_priv->last_shader @@ -967,7 +967,8 @@ static void atifs_tfactor(struct wined3d_context *context, const struct wined3d_ static void set_bumpmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; float mat[2][2]; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; @@ -996,8 +997,9 @@ static void set_bumpmat(struct wined3d_context *context, const struct wined3d_st static void atifs_stage_constant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - const struct wined3d_gl_info *gl_info = context->gl_info; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_color color; if (!ctx_priv->last_shader @@ -1011,13 +1013,14 @@ static void atifs_stage_constant(struct wined3d_context *context, const struct w static void set_tex_op_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->device; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; const struct atifs_ffp_desc *desc, *last_shader = ctx_priv->last_shader; - struct ffp_frag_settings settings; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_device *device = context->device; struct atifs_private_data *priv = device->fragment_priv; + struct ffp_frag_settings settings; DWORD mapped_stage; unsigned int i; @@ -1052,10 +1055,10 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined */ for (i = 0; i < desc->num_textures_used; ++i) { - mapped_stage = context->tex_unit_map[i]; + mapped_stage = context_gl->tex_unit_map[i]; if (mapped_stage != WINED3D_UNMAPPED_STAGE) { - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); texture_activate_dimensions(state->textures[i], gl_info); } } @@ -1063,7 +1066,7 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined GL_EXTCALL(glBindFragmentShaderATI(desc->shader)); ctx_priv->last_shader = desc; - for (i = 0; i < MAX_TEXTURES; i++) + for (i = 0; i < WINED3D_MAX_TEXTURES; i++) { if (last_shader && last_shader->constants[i] == desc->constants[i]) continue; @@ -1100,7 +1103,8 @@ static void atifs_srgbwriteenable(struct wined3d_context *context, const struct WARN("sRGB writes are not supported by this fragment pipe.\n"); } -static const struct StateEntryTemplate atifs_fragmentstate_template[] = { +static const struct wined3d_state_entry_template atifs_fragmentstate_template[] = +{ {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), atifs_tfactor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -1249,8 +1253,10 @@ static const struct StateEntryTemplate atifs_fragmentstate_template[] = { }; /* Context activation is done by the caller. */ -static void atifs_enable(const struct wined3d_gl_info *gl_info, BOOL enable) +static void atifs_enable(const struct wined3d_context *context, BOOL enable) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + if (enable) { gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_SHADER_ATI); @@ -1263,7 +1269,7 @@ static void atifs_enable(const struct wined3d_gl_info *gl_info, BOOL enable) } } -static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) +static void atifs_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL; caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP | @@ -1308,7 +1314,7 @@ static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen * The proper fix for this is not to use GL_ATI_fragment_shader on cards newer than the * r200 series and use an ARB or GLSL shader instead */ - caps->MaxTextureBlendStages = MAX_TEXTURES; + caps->MaxTextureBlendStages = WINED3D_MAX_TEXTURES; caps->MaxSimultaneousTextures = 6; } @@ -1329,22 +1335,25 @@ static void *atifs_alloc(const struct wined3d_shader_backend_ops *shader_backend } /* Context activation is done by the caller. */ -static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *cb_ctx) +static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *param) { - const struct wined3d_gl_info *gl_info = cb_ctx; struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry); + struct wined3d_context_gl *context_gl = param; + const struct wined3d_gl_info *gl_info; + gl_info = context_gl->gl_info; GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader)); checkGLcall("glDeleteFragmentShaderATI(entry->shader)"); heap_free(entry_ati); } /* Context activation is done by the caller. */ -static void atifs_free(struct wined3d_device *device) +static void atifs_free(struct wined3d_device *device, struct wined3d_context *context) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct atifs_private_data *priv = device->fragment_priv; - wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, &device->adapter->gl_info); + wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, context_gl); heap_free(priv); device->fragment_priv = NULL; @@ -1372,7 +1381,8 @@ static void atifs_free_context_data(struct wined3d_context *context) heap_free(context->fragment_pipe_data); } -const struct fragment_pipeline atifs_fragment_pipeline = { +const struct wined3d_fragment_pipe_ops atifs_fragment_pipeline = +{ atifs_enable, atifs_get_caps, atifs_get_emul_mask, diff --git a/dll/directx/wine/wined3d/buffer.c b/dll/directx/wine/wined3d/buffer.c index cae7ef87885..c52b62788c9 100644 --- a/dll/directx/wine/wined3d/buffer.c +++ b/dll/directx/wine/wined3d/buffer.c @@ -133,18 +133,20 @@ void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD loc } /* Context activation is done by the caller. */ -static void buffer_bind(struct wined3d_buffer *buffer, struct wined3d_context *context) +static void wined3d_buffer_gl_bind(struct wined3d_buffer_gl *buffer_gl, struct wined3d_context_gl *context_gl) { - context_bind_bo(context, buffer->buffer_type_hint, buffer->buffer_object); + wined3d_context_gl_bind_bo(context_gl, buffer_gl->buffer_type_hint, buffer_gl->b.buffer_object); } /* Context activation is done by the caller. */ -static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context) +void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl, + struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_resource *resource = &buffer->resource; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_resource *resource = &buffer_gl->b.resource; + GLuint bo; - if (!buffer->buffer_object) + if (!buffer_gl->b.buffer_object) return; /* The stream source state handler might have read the memory of the @@ -154,11 +156,11 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct w * rarely. */ if (resource->bind_count) { - if (buffer->bind_flags & WINED3D_BIND_VERTEX_BUFFER) + if (resource->bind_flags & WINED3D_BIND_VERTEX_BUFFER) device_invalidate_state(resource->device, STATE_STREAMSRC); - if (buffer->bind_flags & WINED3D_BIND_INDEX_BUFFER) + if (resource->bind_flags & WINED3D_BIND_INDEX_BUFFER) device_invalidate_state(resource->device, STATE_INDEXBUFFER); - if (buffer->bind_flags & WINED3D_BIND_CONSTANT_BUFFER) + if (resource->bind_flags & WINED3D_BIND_CONSTANT_BUFFER) { device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX)); device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL)); @@ -167,41 +169,44 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct w device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL)); device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE)); } - if (buffer->bind_flags & WINED3D_BIND_STREAM_OUTPUT) + if (resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT) { device_invalidate_state(resource->device, STATE_STREAM_OUTPUT); - if (context->transform_feedback_active) + if (context_gl->c.transform_feedback_active) { /* We have to make sure that transform feedback is not active * when deleting a potentially bound transform feedback buffer. * This may happen when the device is being destroyed. */ - WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer); - context_end_transform_feedback(context); + WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer_gl); + wined3d_context_gl_end_transform_feedback(context_gl); } } } - GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object)); + bo = buffer_gl->b.buffer_object; + GL_EXTCALL(glDeleteBuffers(1, &bo)); checkGLcall("glDeleteBuffers"); - buffer->buffer_object = 0; + buffer_gl->b.buffer_object = 0; - if (buffer->fence) + if (buffer_gl->b.fence) { - wined3d_fence_destroy(buffer->fence); - buffer->fence = NULL; + wined3d_fence_destroy(buffer_gl->b.fence); + buffer_gl->b.fence = NULL; } - buffer->flags &= ~WINED3D_BUFFER_APPLESYNC; + buffer_gl->b.flags &= ~WINED3D_BUFFER_APPLESYNC; } /* Context activation is done by the caller. */ -static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context) +static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buffer_gl, + struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; GLenum gl_usage = GL_STATIC_DRAW; GLenum error; + GLuint bo; - TRACE("Creating an OpenGL buffer object for wined3d_buffer %p with usage %s.\n", - buffer, debug_d3dusage(buffer->resource.usage)); + TRACE("Creating an OpenGL buffer object for wined3d buffer %p with usage %s.\n", + buffer_gl, debug_d3dusage(buffer_gl->b.resource.usage)); /* Make sure that the gl error is cleared. Do not use checkGLcall * here because checkGLcall just prints a fixme and continues. However, @@ -216,15 +221,16 @@ static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wi * to be verified to check if the rhw and color values are in the correct * format. */ - GL_EXTCALL(glGenBuffers(1, &buffer->buffer_object)); + GL_EXTCALL(glGenBuffers(1, &bo)); + buffer_gl->b.buffer_object = bo; error = gl_info->gl_ops.gl.p_glGetError(); - if (!buffer->buffer_object || error != GL_NO_ERROR) + if (!buffer_gl->b.buffer_object || error != GL_NO_ERROR) { ERR("Failed to create a BO with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - buffer_bind(buffer, context); + wined3d_buffer_gl_bind(buffer_gl, context_gl); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { @@ -232,22 +238,24 @@ static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wi goto fail; } - if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC) + if (buffer_gl->b.resource.usage & WINED3DUSAGE_DYNAMIC) { TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n"); gl_usage = GL_STREAM_DRAW_ARB; if (gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) { - GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); - GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + GL_EXTCALL(glBufferParameteriAPPLE(buffer_gl->buffer_type_hint, + GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); + GL_EXTCALL(glBufferParameteriAPPLE(buffer_gl->buffer_type_hint, + GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); checkGLcall("glBufferParameteriAPPLE"); - buffer->flags |= WINED3D_BUFFER_APPLESYNC; + buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC; } /* No setup is needed here for GL_ARB_map_buffer_range. */ } - GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, NULL, gl_usage)); + GL_EXTCALL(glBufferData(buffer_gl->buffer_type_hint, buffer_gl->b.resource.size, NULL, gl_usage)); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { @@ -255,17 +263,17 @@ static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wi goto fail; } - buffer->buffer_object_usage = gl_usage; - buffer_invalidate_bo_range(buffer, 0, 0); + buffer_gl->buffer_object_usage = gl_usage; + buffer_invalidate_bo_range(&buffer_gl->b, 0, 0); return TRUE; fail: /* Clean up all BO init, but continue because we can work without a BO :-) */ ERR("Failed to create a buffer object. Continuing, but performance issues may occur.\n"); - buffer->flags &= ~WINED3D_BUFFER_USE_BO; - buffer_destroy_buffer_object(buffer, context); - buffer_clear_dirty_areas(buffer); + buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO; + wined3d_buffer_gl_destroy_buffer_object(buffer_gl, context_gl); + buffer_clear_dirty_areas(&buffer_gl->b); return FALSE; } @@ -309,7 +317,7 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer, } data = ((DWORD_PTR)attrib->data.addr) % buffer->stride; - for (i = 0; i < format->attribute_size; ++i) + for (i = 0; i < format->byte_count; ++i) { DWORD_PTR idx = (data + i) % buffer->stride; if (buffer->conversion_map[idx] != conversion_type) @@ -531,24 +539,6 @@ ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) return refcount; } -/* Context activation is done by the caller. */ -static void wined3d_buffer_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, - const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_map_range *range; - - buffer_bind(buffer, context); - - while (range_count--) - { - range = &ranges[range_count]; - GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, - range->offset, range->size, (BYTE *)data + range->offset - data_offset)); - } - checkGLcall("glBufferSubData"); -} - static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined3d_context *context) { unsigned int i, j, range_idx, start, end, vertex_count; @@ -600,48 +590,22 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined } } - wined3d_buffer_upload_ranges(buffer, context, data, 0, buffer->modified_areas, buffer->maps); + buffer->buffer_ops->buffer_upload_ranges(buffer, context, + data, 0, buffer->modified_areas, buffer->maps); heap_free(data); } static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, - struct wined3d_context *context, DWORD location) + struct wined3d_context *context, unsigned int location) { - switch (location) - { - case WINED3D_LOCATION_SYSMEM: - if (buffer->resource.heap_memory) - return TRUE; - - if (!wined3d_resource_allocate_sysmem(&buffer->resource)) - { - ERR("Failed to allocate system memory.\n"); - return FALSE; - } - return TRUE; - - case WINED3D_LOCATION_BUFFER: - if (buffer->buffer_object) - return TRUE; - - if (!(buffer->flags & WINED3D_BUFFER_USE_BO)) - { - WARN("Trying to create BO for buffer %p with no WINED3D_BUFFER_USE_BO.\n", buffer); - return FALSE; - } - return buffer_create_buffer_object(buffer, context); - - default: - ERR("Invalid location %s.\n", wined3d_debug_location(location)); - return FALSE; - } + return buffer->buffer_ops->buffer_prepare_location(buffer, context, location); } BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, struct wined3d_context *context, DWORD location) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_map_range range; TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location)); @@ -675,16 +639,16 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, switch (location) { case WINED3D_LOCATION_SYSMEM: - buffer_bind(buffer, context); - GL_EXTCALL(glGetBufferSubData(buffer->buffer_type_hint, 0, buffer->resource.size, - buffer->resource.heap_memory)); - checkGLcall("buffer download"); + range.offset = 0; + range.size = buffer->resource.size; + buffer->buffer_ops->buffer_download_ranges(buffer, context, + buffer->resource.heap_memory, 0, 1, &range); break; case WINED3D_LOCATION_BUFFER: if (!buffer->conversion_map) - wined3d_buffer_upload_ranges(buffer, context, buffer->resource.heap_memory, - 0, buffer->modified_areas, buffer->maps); + buffer->buffer_ops->buffer_upload_ranges(buffer, context, + buffer->resource.heap_memory, 0, buffer->modified_areas, buffer->maps); else buffer_conversion_upload(buffer, context); break; @@ -749,7 +713,7 @@ static void buffer_unload(struct wined3d_resource *resource) wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER); - buffer_destroy_buffer_object(buffer, context); + wined3d_buffer_gl_destroy_buffer_object(wined3d_buffer_gl(buffer), wined3d_context_gl(context)); buffer_clear_dirty_areas(buffer); context_release(context); @@ -773,19 +737,15 @@ static void wined3d_buffer_drop_bo(struct wined3d_buffer *buffer) static void wined3d_buffer_destroy_object(void *object) { struct wined3d_buffer *buffer = object; - struct wined3d_context *context; - - if (buffer->buffer_object) - { - context = context_acquire(buffer->resource.device, NULL, 0); - buffer_destroy_buffer_object(buffer, context); - context_release(context); - - heap_free(buffer->conversion_map); - } + heap_free(buffer->conversion_map); heap_free(buffer->maps); - heap_free(buffer); +} + +void wined3d_buffer_cleanup(struct wined3d_buffer *buffer) +{ + resource_cleanup(&buffer->resource); + wined3d_cs_destroy_object(buffer->resource.device->cs, wined3d_buffer_destroy_object, buffer); } ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) @@ -797,8 +757,7 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) if (!refcount) { buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); - resource_cleanup(&buffer->resource); - wined3d_cs_destroy_object(buffer->resource.device->cs, wined3d_buffer_destroy_object, buffer); + buffer->resource.device->adapter->adapter_ops->adapter_destroy_buffer(buffer); } return refcount; @@ -812,8 +771,10 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer) } /* The caller provides a context and binds the buffer */ -static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const struct wined3d_gl_info *gl_info) +static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl, + uint32_t flags, struct wined3d_context_gl *context_gl) { + const struct wined3d_gl_info *gl_info = context_gl->gl_info; enum wined3d_fence_result ret; HRESULT hr; @@ -824,16 +785,19 @@ static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const if (flags & WINED3D_MAP_DISCARD) { - GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, NULL, buffer->buffer_object_usage)); + wined3d_buffer_gl_bind(buffer_gl, context_gl); + + GL_EXTCALL(glBufferData(buffer_gl->buffer_type_hint, buffer_gl->b.resource.size, + NULL, buffer_gl->buffer_object_usage)); checkGLcall("glBufferData"); return; } - if (!buffer->fence) + if (!buffer_gl->b.fence) { - TRACE("Creating fence for buffer %p.\n", buffer); + TRACE("Creating fence for buffer %p.\n", buffer_gl); - if (FAILED(hr = wined3d_fence_create(buffer->resource.device, &buffer->fence))) + if (FAILED(hr = wined3d_fence_create(buffer_gl->b.resource.device, &buffer_gl->b.fence))) { if (hr == WINED3DERR_NOTAVAILABLE) FIXME("Fences not supported, dropping async buffer locks.\n"); @@ -847,8 +811,8 @@ static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const return; } - TRACE("Synchronizing buffer %p.\n", buffer); - ret = wined3d_fence_wait(buffer->fence, buffer->resource.device); + TRACE("Synchronizing buffer %p.\n", buffer_gl); + ret = wined3d_fence_wait(buffer_gl->b.fence, buffer_gl->b.resource.device); switch (ret) { case WINED3D_FENCE_NOT_STARTED: @@ -866,16 +830,17 @@ static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const } drop_fence: - if (buffer->fence) + if (buffer_gl->b.fence) { - wined3d_fence_destroy(buffer->fence); - buffer->fence = NULL; + wined3d_fence_destroy(buffer_gl->b.fence); + buffer_gl->b.fence = NULL; } gl_info->gl_ops.gl.p_glFinish(); - GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); - checkGLcall("glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); - buffer->flags &= ~WINED3D_BUFFER_APPLESYNC; + wined3d_buffer_gl_bind(buffer_gl, context_gl); + GL_EXTCALL(glBufferParameteriAPPLE(buffer_gl->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); + checkGLcall("glBufferParameteriAPPLE(buffer_gl->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); + buffer_gl->b.flags &= ~WINED3D_BUFFER_APPLESYNC; } static void buffer_mark_used(struct wined3d_buffer *buffer) @@ -887,16 +852,20 @@ static void buffer_mark_used(struct wined3d_buffer *buffer) void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; BOOL decl_changed = FALSE; TRACE("buffer %p.\n", buffer); - if (buffer->resource.map_count) + if (buffer->resource.map_count && buffer->map_ptr) { - WARN("Buffer is mapped, skipping preload.\n"); + FIXME("Buffer is mapped through buffer object, not loading.\n"); return; } + else if (buffer->resource.map_count) + { + WARN("Loading mapped buffer.\n"); + } buffer_mark_used(buffer); @@ -921,9 +890,9 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * if (!use_vs(state)) { - if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && !context->d3d_info->ffp_generic_attributes) + if (!d3d_info->vertex_bgra && !d3d_info->ffp_generic_attributes) fixup_flags |= WINED3D_BUFFER_FIXUP_D3DCOLOR; - if (!context->d3d_info->xyzrhw) + if (!d3d_info->xyzrhw) fixup_flags |= WINED3D_BUFFER_FIXUP_XYZRHW; } @@ -999,20 +968,43 @@ struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffe return &buffer->resource; } -static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags) +static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, uint32_t flags) { - struct wined3d_device *device = buffer->resource.device; + struct wined3d_buffer *buffer = buffer_from_resource(resource); + struct wined3d_device *device = resource->device; struct wined3d_context *context; + unsigned int offset, size; + uint8_t *base; LONG count; - BYTE *base; - TRACE("buffer %p, offset %u, size %u, data %p, flags %#x.\n", buffer, offset, size, data, flags); + TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", + resource, sub_resource_idx, map_desc, debug_box(box), flags); - count = ++buffer->resource.map_count; + if (sub_resource_idx) + { + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return E_INVALIDARG; + } + + if (box) + { + offset = box->left; + size = box->right - box->left; + } + else + { + offset = size = 0; + } + + map_desc->row_pitch = map_desc->slice_pitch = resource->size; + + count = ++resource->map_count; if (buffer->buffer_object) { unsigned int dirty_offset = offset, dirty_size = size; + struct wined3d_bo_address addr; /* DISCARD invalidates the entire buffer, regardless of the specified * offset and size. Some applications also depend on the entire buffer @@ -1040,10 +1032,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI } else { - const struct wined3d_gl_info *gl_info; - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; if (flags & WINED3D_MAP_DISCARD) wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); @@ -1051,15 +1040,16 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); if (flags & WINED3D_MAP_WRITE) + { + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_SYSMEM); buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size); + } - if ((flags & WINED3D_MAP_DISCARD) && buffer->resource.heap_memory) + if ((flags & WINED3D_MAP_DISCARD) && resource->heap_memory) wined3d_buffer_evict_sysmem(buffer); if (count == 1) { - buffer_bind(buffer, context); - /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 * multitexture fill rate test seems to depend on this. When * we map a buffer with GL_MAP_INVALIDATE_BUFFER_BIT, the @@ -1070,36 +1060,26 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI if (buffer->flags & WINED3D_BUFFER_DISCARD) flags &= ~WINED3D_MAP_DISCARD; - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); - buffer->map_ptr = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint, - 0, buffer->resource.size, mapflags)); - checkGLcall("glMapBufferRange"); - } - else - { - if (buffer->flags & WINED3D_BUFFER_APPLESYNC) - buffer_sync_apple(buffer, flags, gl_info); - buffer->map_ptr = GL_EXTCALL(glMapBuffer(buffer->buffer_type_hint, - GL_READ_WRITE)); - checkGLcall("glMapBuffer"); - } + if (buffer->flags & WINED3D_BUFFER_APPLESYNC) + wined3d_buffer_gl_sync_apple(wined3d_buffer_gl(buffer), flags, wined3d_context_gl(context)); + + addr.buffer_object = buffer->buffer_object; + addr.addr = 0; + buffer->map_ptr = wined3d_context_map_bo_address(context, + &addr, resource->size, resource->bind_flags, flags); if (((DWORD_PTR)buffer->map_ptr) & (RESOURCE_ALIGNMENT - 1)) { WARN("Pointer %p is not %u byte aligned.\n", buffer->map_ptr, RESOURCE_ALIGNMENT); - GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); - checkGLcall("glUnmapBuffer"); + wined3d_context_unmap_bo_address(context, &addr, resource->bind_flags, 0, NULL); buffer->map_ptr = NULL; - if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC) + if (resource->usage & WINED3DUSAGE_DYNAMIC) { - /* The extra copy is more expensive than not using VBOs at - * all on the Nvidia Linux driver, which is the only driver - * that returns unaligned pointers. - */ + /* The extra copy is more expensive than not using VBOs + * at all on the NVIDIA Linux driver, which is the + * only driver that returns unaligned pointers. */ TRACE("Dynamic buffer, dropping VBO.\n"); wined3d_buffer_drop_bo(buffer); } @@ -1109,7 +1089,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); buffer->flags |= WINED3D_BUFFER_PIN_SYSMEM; } - TRACE("New pointer is %p.\n", buffer->resource.heap_memory); + TRACE("New pointer is %p.\n", resource->heap_memory); } } @@ -1120,76 +1100,97 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI buffer->flags |= WINED3D_BUFFER_DISCARD; } - base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; - *data = base + offset; + base = buffer->map_ptr ? buffer->map_ptr : resource->heap_memory; + map_desc->data = base + offset; - TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); - /* TODO: check Flags compatibility with buffer->currentDesc.Usage (see MSDN) */ + TRACE("Returning memory at %p (base %p, offset %u).\n", map_desc->data, base, offset); return WINED3D_OK; } -static void wined3d_buffer_unmap(struct wined3d_buffer *buffer) +static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_info *info, DWORD flags) { - ULONG i; + struct wined3d_buffer *buffer = buffer_from_resource(resource); - TRACE("buffer %p.\n", buffer); + if (sub_resource_idx) + { + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return E_INVALIDARG; + } + + info->row_pitch = resource->size; + info->slice_pitch = resource->size; + info->size = buffer->resource.size; - /* In the case that the number of Unmap calls > the - * number of Map calls, d3d returns always D3D_OK. - * This is also needed to prevent Map from returning garbage on - * the next call (this will happen if the lock_count is < 0). */ - if (!buffer->resource.map_count) + return WINED3D_OK; +} + +static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) +{ + struct wined3d_buffer *buffer = buffer_from_resource(resource); + unsigned int range_count = buffer->modified_areas; + struct wined3d_device *device = resource->device; + struct wined3d_context *context; + struct wined3d_bo_address addr; + + TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); + + if (sub_resource_idx) + { + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return E_INVALIDARG; + } + + if (!resource->map_count) { WARN("Unmap called without a previous map call.\n"); - return; + return WINED3D_OK; } - if (--buffer->resource.map_count) + if (--resource->map_count) { - /* Delay loading the buffer until everything is unlocked */ + /* Delay loading the buffer until everything is unmapped. */ TRACE("Ignoring unmap.\n"); - return; + return WINED3D_OK; } - if (buffer->map_ptr) + if (!buffer->map_ptr) + return WINED3D_OK; + + context = context_acquire(device, NULL, 0); + + if (buffer->flags & WINED3D_BUFFER_APPLESYNC) { - struct wined3d_device *device = buffer->resource.device; + struct wined3d_context_gl *context_gl; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + struct wined3d_buffer_gl *buffer_gl; + unsigned int i; - buffer_bind(buffer, context); + buffer_gl = wined3d_buffer_gl(buffer); + context_gl = wined3d_context_gl(context); + gl_info = context_gl->gl_info; - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + wined3d_buffer_gl_bind(buffer_gl, context_gl); + for (i = 0; i < range_count; ++i) { - for (i = 0; i < buffer->modified_areas; ++i) - { - GL_EXTCALL(glFlushMappedBufferRange(buffer->buffer_type_hint, - buffer->maps[i].offset, buffer->maps[i].size)); - checkGLcall("glFlushMappedBufferRange"); - } - } - else if (buffer->flags & WINED3D_BUFFER_APPLESYNC) - { - for (i = 0; i < buffer->modified_areas; ++i) - { - GL_EXTCALL(glFlushMappedBufferRangeAPPLE(buffer->buffer_type_hint, - buffer->maps[i].offset, buffer->maps[i].size)); - checkGLcall("glFlushMappedBufferRangeAPPLE"); - } + GL_EXTCALL(glFlushMappedBufferRangeAPPLE(buffer_gl->buffer_type_hint, + buffer->maps[i].offset, buffer->maps[i].size)); + checkGLcall("glFlushMappedBufferRangeAPPLE"); } + range_count = 0; + } - GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); - if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - context_release(context); + addr.buffer_object = buffer->buffer_object; + addr.addr = 0; + wined3d_context_unmap_bo_address(context, &addr, resource->bind_flags, range_count, buffer->maps); - buffer_clear_dirty_areas(buffer); - buffer->map_ptr = NULL; - } + context_release(context); + + buffer_clear_dirty_areas(buffer); + buffer->map_ptr = NULL; + + return WINED3D_OK; } void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, @@ -1209,8 +1210,8 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off src.addr += src_offset; context = context_acquire(dst_buffer->resource.device, NULL, 0); - context_copy_bo_address(context, &dst, dst_buffer->buffer_type_hint, - &src, src_buffer->buffer_type_hint, size); + wined3d_context_copy_bo_address(context, &dst, dst_buffer->resource.bind_flags, + &src, src_buffer->resource.bind_flags, size); context_release(context); wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size); @@ -1232,7 +1233,29 @@ void wined3d_buffer_upload_data(struct wined3d_buffer *buffer, struct wined3d_co range.size = buffer->resource.size; } - wined3d_buffer_upload_ranges(buffer, context, data, range.offset, 1, &range); + buffer->buffer_ops->buffer_upload_ranges(buffer, context, data, range.offset, 1, &range); +} + +static void wined3d_buffer_init_data(struct wined3d_buffer *buffer, + struct wined3d_device *device, const struct wined3d_sub_resource_data *data) +{ + struct wined3d_resource *resource = &buffer->resource; + struct wined3d_bo_address bo; + struct wined3d_box box; + + if (buffer->flags & WINED3D_BUFFER_USE_BO) + { + wined3d_box_set(&box, 0, 0, resource->size, 1, 0, 1); + wined3d_cs_emit_update_sub_resource(device->cs, resource, + 0, &box, data->data, data->row_pitch, data->slice_pitch); + } + else + { + wined3d_buffer_get_memory(buffer, &bo, WINED3D_LOCATION_SYSMEM); + memcpy(bo.addr, data->data, resource->size); + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_SYSMEM); + wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_SYSMEM); + } } static ULONG buffer_resource_incref(struct wined3d_resource *resource) @@ -1254,62 +1277,6 @@ static void buffer_resource_preload(struct wined3d_resource *resource) context_release(context); } -static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - struct wined3d_buffer *buffer = buffer_from_resource(resource); - UINT offset, size; - - if (sub_resource_idx) - { - WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); - return E_INVALIDARG; - } - - if (box) - { - offset = box->left; - size = box->right - box->left; - } - else - { - offset = size = 0; - } - - map_desc->row_pitch = map_desc->slice_pitch = buffer->desc.byte_width; - return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data, flags); -} - -static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_info *info, DWORD flags) -{ - struct wined3d_buffer *buffer = buffer_from_resource(resource); - - if (sub_resource_idx) - { - WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); - return E_INVALIDARG; - } - - info->row_pitch = buffer->desc.byte_width; - info->slice_pitch = buffer->desc.byte_width; - info->size = buffer->resource.size; - - return WINED3D_OK; -} - -static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) -{ - if (sub_resource_idx) - { - WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); - return E_INVALIDARG; - } - - wined3d_buffer_unmap(buffer_from_resource(resource)); - return WINED3D_OK; -} - static const struct wined3d_resource_ops buffer_resource_ops = { buffer_resource_incref, @@ -1321,9 +1288,11 @@ static const struct wined3d_resource_ops buffer_resource_ops = buffer_resource_sub_resource_unmap, }; -static GLenum buffer_type_hint_from_bind_flags(const struct wined3d_gl_info *gl_info, - unsigned int bind_flags) +GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info, uint32_t bind_flags) { + if (!bind_flags) + return GL_PIXEL_UNPACK_BUFFER; + if (bind_flags == WINED3D_BIND_INDEX_BUFFER) return GL_ELEMENT_ARRAY_BUFFER; @@ -1343,24 +1312,30 @@ static GLenum buffer_type_hint_from_bind_flags(const struct wined3d_gl_info *gl_ return GL_ARRAY_BUFFER; } -static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, - UINT size, DWORD usage, enum wined3d_format_id format_id, unsigned int access, unsigned int bind_flags, - const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops) +static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_buffer_ops *buffer_ops) { + const struct wined3d_format *format = wined3d_get_format(device->adapter, WINED3DFMT_UNKNOWN, desc->bind_flags); const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, usage); + struct wined3d_resource *resource = &buffer->resource; BOOL dynamic_buffer_ok; HRESULT hr; - if (!size) + TRACE("buffer %p, device %p, desc byte_width %u, usage %s, bind_flags %s, " + "access %s, data %p, parent %p, parent_ops %p.\n", + buffer, device, desc->byte_width, debug_d3dusage(desc->usage), wined3d_debug_bind_flags(desc->bind_flags), + wined3d_debug_resource_access(desc->access), data, parent, parent_ops); + + if (!desc->byte_width) { WARN("Size 0 requested, returning E_INVALIDARG.\n"); return E_INVALIDARG; } - if (bind_flags & WINED3D_BIND_CONSTANT_BUFFER && size & (WINED3D_CONSTANT_BUFFER_ALIGNMENT - 1)) + if (desc->bind_flags & WINED3D_BIND_CONSTANT_BUFFER && desc->byte_width & (WINED3D_CONSTANT_BUFFER_ALIGNMENT - 1)) { - WARN("Size %#x is not suitably aligned for constant buffers.\n", size); + WARN("Size %#x is not suitably aligned for constant buffers.\n", desc->byte_width); return E_INVALIDARG; } @@ -1370,28 +1345,29 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device return E_INVALIDARG; } - if (FAILED(hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format, WINED3D_MULTISAMPLE_NONE, - 0, usage, access, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops))) + if (FAILED(hr = resource_init(resource, device, WINED3D_RTYPE_BUFFER, format, + WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->bind_flags, desc->access, + desc->byte_width, 1, 1, desc->byte_width, parent, parent_ops, &buffer_resource_ops))) { WARN("Failed to initialize resource, hr %#x.\n", hr); return hr; } - buffer->buffer_type_hint = buffer_type_hint_from_bind_flags(gl_info, bind_flags); - buffer->bind_flags = bind_flags; - buffer->locations = WINED3D_LOCATION_SYSMEM; + buffer->buffer_ops = buffer_ops; + buffer->structure_byte_stride = desc->structure_byte_stride; + buffer->locations = data ? WINED3D_LOCATION_DISCARDED : WINED3D_LOCATION_SYSMEM; - TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n", - buffer, buffer->resource.size, buffer->resource.usage, - debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory); + TRACE("buffer %p, size %#x, usage %#x, memory @ %p.\n", + buffer, buffer->resource.size, buffer->resource.usage, buffer->resource.heap_memory); if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING - || wined3d_resource_access_is_managed(access)) + || wined3d_resource_access_is_managed(desc->access)) { /* SWvp and managed buffers always return the same pointer in buffer * maps and retain data in DISCARD maps. Keep a system memory copy of * the buffer to provide the same behavior to the application. */ - TRACE("Using doublebuffer mode.\n"); + TRACE("Pinning system memory.\n"); buffer->flags |= WINED3D_BUFFER_PIN_SYSMEM; + buffer->locations = WINED3D_LOCATION_SYSMEM; } /* Observations show that draw_primitive_immediate_mode() is faster on @@ -1403,11 +1379,11 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device { TRACE("Not creating a BO because GL_ARB_vertex_buffer is not supported.\n"); } - else if (!(access & WINED3D_RESOURCE_ACCESS_GPU)) + else if (!(desc->access & WINED3D_RESOURCE_ACCESS_GPU)) { TRACE("Not creating a BO because the buffer is not GPU accessible.\n"); } - else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)) + else if (!dynamic_buffer_ok && (resource->usage & WINED3DUSAGE_DYNAMIC)) { TRACE("Not creating a BO because the buffer has dynamic usage and no GL support.\n"); } @@ -1416,48 +1392,210 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device buffer->flags |= WINED3D_BUFFER_USE_BO; } + if (buffer->locations & WINED3D_LOCATION_SYSMEM || !(buffer->flags & WINED3D_BUFFER_USE_BO)) + { + if (!wined3d_resource_prepare_sysmem(&buffer->resource)) + return E_OUTOFMEMORY; + } + if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps)))) { ERR("Out of memory.\n"); - buffer_unload(&buffer->resource); - resource_cleanup(&buffer->resource); - wined3d_resource_wait_idle(&buffer->resource); + buffer_unload(resource); + resource_cleanup(resource); + wined3d_resource_wait_idle(resource); return E_OUTOFMEMORY; } buffer->maps_size = 1; if (data) - wined3d_device_update_sub_resource(device, &buffer->resource, - 0, NULL, data->data, data->row_pitch, data->slice_pitch); + wined3d_buffer_init_data(buffer, device, data); return WINED3D_OK; } -HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc, - const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_buffer **buffer) +static BOOL wined3d_buffer_no3d_prepare_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, unsigned int location) { - struct wined3d_buffer *object; - HRESULT hr; + if (location == WINED3D_LOCATION_SYSMEM) + return wined3d_resource_prepare_sysmem(&buffer->resource); - TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n", - device, desc, data, parent, parent_ops, buffer); + FIXME("Unhandled location %s.\n", wined3d_debug_location(location)); - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; + return FALSE; +} + +static void wined3d_buffer_no3d_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + FIXME("Not implemented.\n"); +} + +static void wined3d_buffer_no3d_download_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + FIXME("Not implemented.\n"); +} - if (FAILED(hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN, - desc->access, desc->bind_flags, data, parent, parent_ops))) +static const struct wined3d_buffer_ops wined3d_buffer_no3d_ops = +{ + wined3d_buffer_no3d_prepare_location, + wined3d_buffer_no3d_upload_ranges, + wined3d_buffer_no3d_download_ranges, +}; + +HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("buffer_no3d %p, device %p, desc %p, data %p, parent %p, parent_ops %p.\n", + buffer_no3d, device, desc, data, parent, parent_ops); + + return wined3d_buffer_init(buffer_no3d, device, desc, data, parent, parent_ops, &wined3d_buffer_no3d_ops); +} + +static BOOL wined3d_buffer_gl_prepare_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, unsigned int location) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer); + + switch (location) { - WARN("Failed to initialize buffer, hr %#x.\n", hr); - heap_free(object); - return hr; + case WINED3D_LOCATION_SYSMEM: + return wined3d_resource_prepare_sysmem(&buffer->resource); + + case WINED3D_LOCATION_BUFFER: + if (buffer->buffer_object) + return TRUE; + + if (!(buffer->flags & WINED3D_BUFFER_USE_BO)) + { + WARN("Trying to create BO for buffer %p with no WINED3D_BUFFER_USE_BO.\n", buffer); + return FALSE; + } + return wined3d_buffer_gl_create_buffer_object(buffer_gl, context_gl); + + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; } - object->desc = *desc; +} - TRACE("Created buffer %p.\n", object); +/* Context activation is done by the caller. */ +static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_map_range *range; - *buffer = object; + wined3d_buffer_gl_bind(buffer_gl, context_gl); - return WINED3D_OK; + while (range_count--) + { + range = &ranges[range_count]; + GL_EXTCALL(glBufferSubData(buffer_gl->buffer_type_hint, + range->offset, range->size, (BYTE *)data + range->offset - data_offset)); + } + checkGLcall("buffer upload"); +} + +/* Context activation is done by the caller. */ +static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_map_range *range; + + wined3d_buffer_gl_bind(buffer_gl, context_gl); + + while (range_count--) + { + range = &ranges[range_count]; + GL_EXTCALL(glGetBufferSubData(buffer_gl->buffer_type_hint, + range->offset, range->size, (BYTE *)data + range->offset - data_offset)); + } + checkGLcall("buffer download"); +} + +static const struct wined3d_buffer_ops wined3d_buffer_gl_ops = +{ + wined3d_buffer_gl_prepare_location, + wined3d_buffer_gl_upload_ranges, + wined3d_buffer_gl_download_ranges, +}; + +HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + + TRACE("buffer_gl %p, device %p, desc %p, data %p, parent %p, parent_ops %p.\n", + buffer_gl, device, desc, data, parent, parent_ops); + + buffer_gl->buffer_type_hint = wined3d_buffer_gl_binding_from_bind_flags(gl_info, desc->bind_flags); + + return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops); +} + +static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, unsigned int location) +{ + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + return wined3d_resource_prepare_sysmem(&buffer->resource); + + case WINED3D_LOCATION_BUFFER: + /* The Vulkan buffer is created during resource creation. */ + return TRUE; + + default: + FIXME("Unhandled location %s.\n", wined3d_debug_location(location)); + return FALSE; + } +} + +static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + FIXME("Not implemented.\n"); +} + +static void wined3d_buffer_vk_download_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + FIXME("Not implemented.\n"); +} + +static const struct wined3d_buffer_ops wined3d_buffer_vk_ops = +{ + wined3d_buffer_vk_prepare_location, + wined3d_buffer_vk_upload_ranges, + wined3d_buffer_vk_download_ranges, +}; + +HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("buffer_vk %p, device %p, desc %p, data %p, parent %p, parent_ops %p.\n", + buffer_vk, device, desc, data, parent, parent_ops); + + return wined3d_buffer_init(&buffer_vk->b, device, desc, data, parent, parent_ops, &wined3d_buffer_vk_ops); +} + +HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc, + const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_buffer **buffer) +{ + TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n", + device, desc, data, parent, parent_ops, buffer); + + return device->adapter->adapter_ops->adapter_create_buffer(device, desc, data, parent, parent_ops, buffer); } diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c index 8a8d952c3ff..525711e353b 100644 --- a/dll/directx/wine/wined3d/context.c +++ b/dll/directx/wine/wined3d/context.c @@ -34,10 +34,6 @@ #include "wined3d_private.h" -#ifdef __REACTOS__ -#include -#endif - WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous); @@ -50,27 +46,30 @@ static DWORD wined3d_context_tls_idx; /* FBO helper functions */ /* Context activation is done by the caller. */ -static void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint fbo) +static void wined3d_context_gl_bind_fbo(struct wined3d_context_gl *context_gl, GLenum target, GLuint fbo) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; switch (target) { case GL_READ_FRAMEBUFFER: - if (context->fbo_read_binding == fbo) return; - context->fbo_read_binding = fbo; + if (context_gl->fbo_read_binding == fbo) + return; + context_gl->fbo_read_binding = fbo; break; case GL_DRAW_FRAMEBUFFER: - if (context->fbo_draw_binding == fbo) return; - context->fbo_draw_binding = fbo; + if (context_gl->fbo_draw_binding == fbo) + return; + context_gl->fbo_draw_binding = fbo; break; case GL_FRAMEBUFFER: - if (context->fbo_read_binding == fbo - && context->fbo_draw_binding == fbo) return; - context->fbo_read_binding = fbo; - context->fbo_draw_binding = fbo; + if (context_gl->fbo_read_binding == fbo + && context_gl->fbo_draw_binding == fbo) + return; + context_gl->fbo_read_binding = fbo; + context_gl->fbo_draw_binding = fbo; break; default: @@ -100,13 +99,13 @@ static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info, } /* Context activation is done by the caller. */ -static void context_destroy_fbo(struct wined3d_context *context, GLuint fbo) +static void wined3d_context_gl_destroy_fbo(struct wined3d_context_gl *context_gl, GLuint fbo) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - context_bind_fbo(context, GL_FRAMEBUFFER, fbo); + wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, fbo); context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER); - context_bind_fbo(context, GL_FRAMEBUFFER, 0); + wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, 0); gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); checkGLcall("glDeleteFramebuffers()"); @@ -128,10 +127,10 @@ static void context_attach_depth_stencil_rb(const struct wined3d_gl_info *gl_inf } } -static void context_attach_gl_texture_fbo(struct wined3d_context *context, +static void wined3d_context_gl_attach_gl_texture_fbo(struct wined3d_context_gl *context_gl, GLenum fbo_target, GLenum attachment, const struct wined3d_fbo_resource *resource) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (!resource) { @@ -148,8 +147,8 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context, gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment, resource->object, resource->level); } - else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY || - resource->target == GL_TEXTURE_3D) + else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY + || resource->target == GL_TEXTURE_3D) { if (!gl_info->fbo_ops.glFramebufferTextureLayer) { @@ -164,7 +163,6 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context, { gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment, resource->target, resource->object, resource->level); - checkGLcall("glFramebufferTexture1D()"); } else { @@ -175,11 +173,11 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context, } /* Context activation is done by the caller. */ -static void context_attach_depth_stencil_fbo(struct wined3d_context *context, +static void wined3d_context_gl_attach_depth_stencil_fbo(struct wined3d_context_gl *context_gl, GLenum fbo_target, const struct wined3d_fbo_resource *resource, BOOL rb_namespace, - DWORD flags) + uint32_t flags) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (resource->object) { @@ -193,32 +191,32 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, else { if (flags & WINED3D_FBO_ENTRY_FLAG_DEPTH) - context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, resource); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_DEPTH_ATTACHMENT, resource); if (flags & WINED3D_FBO_ENTRY_FLAG_STENCIL) - context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, resource); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_STENCIL_ATTACHMENT, resource); } if (!(flags & WINED3D_FBO_ENTRY_FLAG_DEPTH)) - context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_DEPTH_ATTACHMENT, NULL); if (!(flags & WINED3D_FBO_ENTRY_FLAG_STENCIL)) - context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_STENCIL_ATTACHMENT, NULL); } else { TRACE("Attach depth stencil 0.\n"); - context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL); - context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_DEPTH_ATTACHMENT, NULL); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_STENCIL_ATTACHMENT, NULL); } } /* Context activation is done by the caller. */ -static void context_attach_surface_fbo(struct wined3d_context *context, - GLenum fbo_target, DWORD idx, const struct wined3d_fbo_resource *resource, BOOL rb_namespace) +static void wined3d_context_gl_attach_surface_fbo(struct wined3d_context_gl *context_gl, + GLenum fbo_target, unsigned int idx, const struct wined3d_fbo_resource *resource, BOOL rb_namespace) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; TRACE("Attach GL object %u to %u.\n", resource->object, idx); @@ -232,12 +230,12 @@ static void context_attach_surface_fbo(struct wined3d_context *context, } else { - context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, resource); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_COLOR_ATTACHMENT0 + idx, resource); } } else { - context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, NULL); + wined3d_context_gl_attach_gl_texture_fbo(context_gl, fbo_target, GL_COLOR_ATTACHMENT0 + idx, NULL); } } @@ -253,6 +251,8 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G } texture_type[] = { + {GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, "1d", WINED3D_GL_EXT_NONE}, + {GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BINDING_1D_ARRAY, "1d-array", EXT_TEXTURE_ARRAY}, {GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2d", WINED3D_GL_EXT_NONE}, {GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BINDING_RECTANGLE_ARB, "rectangle", ARB_TEXTURE_RECTANGLE}, {GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2d-array" , EXT_TEXTURE_ARRAY}, @@ -378,9 +378,9 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G } /* Context activation is done by the caller. */ -void context_check_fbo_status(const struct wined3d_context *context, GLenum target) +void wined3d_context_gl_check_fbo_status(const struct wined3d_context_gl *context_gl, GLenum target) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; GLenum status; if (!FIXME_ON(d3d)) @@ -397,7 +397,7 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ FIXME("FBO status %s (%#x).\n", debug_fbostatus(status), status); - if (!context->current_fbo) + if (!context_gl->current_fbo) { ERR("FBO 0 is incomplete, driver bug?\n"); return; @@ -428,13 +428,13 @@ static inline DWORD context_generate_rt_mask_from_resource(struct wined3d_resour return (1u << 31) | wined3d_texture_get_gl_buffer(texture_from_resource(resource)); } -static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context, +static inline void wined3d_context_gl_set_fbo_key_for_render_target(const struct wined3d_context_gl *context_gl, struct wined3d_fbo_entry_key *key, unsigned int idx, const struct wined3d_rendertarget_info *render_target, DWORD location) { unsigned int sub_resource_idx = render_target->sub_resource_idx; struct wined3d_resource *resource = render_target->resource; - struct wined3d_texture *texture; + struct wined3d_texture_gl *texture_gl; if (!resource || resource->format->id == WINED3DFMT_NULL || resource->type == WINED3D_RTYPE_BUFFER) { @@ -455,23 +455,19 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co return; } - texture = wined3d_texture_from_resource(resource); - if (resource->type == WINED3D_RTYPE_TEXTURE_2D) + texture_gl = wined3d_texture_gl(wined3d_texture_from_resource(resource)); + if (texture_gl->current_renderbuffer) { - struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; - - if (surface->current_renderbuffer) - { - key->objects[idx].object = surface->current_renderbuffer->id; - key->objects[idx].target = 0; - key->objects[idx].level = key->objects[idx].layer = 0; - key->rb_namespace |= 1 << idx; - return; - } + key->objects[idx].object = texture_gl->current_renderbuffer->id; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; + key->rb_namespace |= 1 << idx; + return; } - key->objects[idx].target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - key->objects[idx].level = sub_resource_idx % texture->level_count; - key->objects[idx].layer = sub_resource_idx / texture->level_count; + + key->objects[idx].target = wined3d_texture_gl_get_sub_resource_target(texture_gl, sub_resource_idx); + key->objects[idx].level = sub_resource_idx % texture_gl->t.level_count; + key->objects[idx].layer = sub_resource_idx / texture_gl->t.level_count; if (render_target->layer_count != 1) key->objects[idx].layer = WINED3D_ALL_LAYERS; @@ -479,22 +475,22 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co switch (location) { case WINED3D_LOCATION_TEXTURE_RGB: - key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, FALSE); + key->objects[idx].object = wined3d_texture_gl_get_texture_name(texture_gl, &context_gl->c, FALSE); break; case WINED3D_LOCATION_TEXTURE_SRGB: - key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, TRUE); + key->objects[idx].object = wined3d_texture_gl_get_texture_name(texture_gl, &context_gl->c, TRUE); break; case WINED3D_LOCATION_RB_MULTISAMPLE: - key->objects[idx].object = texture->rb_multisample; + key->objects[idx].object = texture_gl->rb_multisample; key->objects[idx].target = 0; key->objects[idx].level = key->objects[idx].layer = 0; key->rb_namespace |= 1 << idx; break; case WINED3D_LOCATION_RB_RESOLVED: - key->objects[idx].object = texture->rb_resolved; + key->objects[idx].object = texture_gl->rb_resolved; key->objects[idx].target = 0; key->objects[idx].level = key->objects[idx].layer = 0; key->rb_namespace |= 1 << idx; @@ -502,31 +498,32 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co } } -static void context_generate_fbo_key(const struct wined3d_context *context, +static void wined3d_context_gl_generate_fbo_key(const struct wined3d_context_gl *context_gl, struct wined3d_fbo_entry_key *key, const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location) { - unsigned int buffers = context->gl_info->limits.buffers; + unsigned int buffers = context_gl->gl_info->limits.buffers; unsigned int i; key->rb_namespace = 0; - context_set_fbo_key_for_render_target(context, key, 0, depth_stencil, ds_location); + wined3d_context_gl_set_fbo_key_for_render_target(context_gl, key, 0, depth_stencil, ds_location); for (i = 0; i < buffers; ++i) - context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location); + wined3d_context_gl_set_fbo_key_for_render_target(context_gl, key, i + 1, &render_targets[i], color_location); memset(&key->objects[buffers + 1], 0, (ARRAY_SIZE(key->objects) - buffers - 1) * sizeof(*key->objects)); } -static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context, +static struct fbo_entry *wined3d_context_gl_create_fbo_entry(const struct wined3d_context_gl *context_gl, const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct fbo_entry *entry; entry = heap_alloc(sizeof(*entry)); - context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location); + wined3d_context_gl_generate_fbo_key(context_gl, &entry->key, + render_targets, depth_stencil, color_location, ds_location); entry->flags = 0; if (depth_stencil->resource) { @@ -544,16 +541,17 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context * } /* Context activation is done by the caller. */ -static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target, +static void wined3d_context_gl_reuse_fbo_entry(struct wined3d_context_gl *context_gl, GLenum target, const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location, struct fbo_entry *entry) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - context_bind_fbo(context, target, entry->id); + wined3d_context_gl_bind_fbo(context_gl, target, entry->id); context_clean_fbo_attachments(gl_info, target); - context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location); + wined3d_context_gl_generate_fbo_key(context_gl, &entry->key, + render_targets, depth_stencil, color_location, ds_location); entry->flags = 0; if (depth_stencil->resource) { @@ -565,25 +563,25 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum targ } /* Context activation is done by the caller. */ -static void context_destroy_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +static void wined3d_context_gl_destroy_fbo_entry(struct wined3d_context_gl *context_gl, struct fbo_entry *entry) { if (entry->id) { TRACE("Destroy FBO %u.\n", entry->id); - context_destroy_fbo(context, entry->id); + wined3d_context_gl_destroy_fbo(context_gl, entry->id); } - --context->fbo_entry_count; + --context_gl->fbo_entry_count; list_remove(&entry->entry); heap_free(entry); } /* Context activation is done by the caller. */ -static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target, +static struct fbo_entry *wined3d_context_gl_find_fbo_entry(struct wined3d_context_gl *context_gl, GLenum target, const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location) { static const struct wined3d_rendertarget_info ds_null = {{0}}; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_texture *rt_texture, *ds_texture; struct wined3d_fbo_entry_key fbo_key; unsigned int i, ds_level, rt_level; @@ -606,7 +604,8 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, depth_stencil = &ds_null; } else if (ds_texture->resource.multisample_type != rt_texture->resource.multisample_type - || ds_texture->resource.multisample_quality != rt_texture->resource.multisample_quality) + || (ds_texture->resource.multisample_type + && ds_texture->resource.multisample_quality != rt_texture->resource.multisample_quality)) { WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n", rt_texture->resource.multisample_type, rt_texture->resource.multisample_quality, @@ -615,14 +614,13 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, } else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D) { - struct wined3d_surface *surface; - - surface = ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface; - surface_set_compatible_renderbuffer(surface, &render_targets[0]); + wined3d_texture_gl_set_compatible_renderbuffer(wined3d_texture_gl(ds_texture), + context_gl, ds_level, &render_targets[0]); } } - context_generate_fbo_key(context, &fbo_key, render_targets, depth_stencil, color_location, ds_location); + wined3d_context_gl_generate_fbo_key(context_gl, &fbo_key, + render_targets, depth_stencil, color_location, ds_location); if (TRACE_ON(d3d)) { @@ -680,49 +678,52 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, } } - LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry) + LIST_FOR_EACH_ENTRY(entry, &context_gl->fbo_list, struct fbo_entry, entry) { if (memcmp(&fbo_key, &entry->key, sizeof(fbo_key))) continue; list_remove(&entry->entry); - list_add_head(&context->fbo_list, &entry->entry); + list_add_head(&context_gl->fbo_list, &entry->entry); return entry; } - if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES) + if (context_gl->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES) { - entry = context_create_fbo_entry(context, render_targets, depth_stencil, color_location, ds_location); - list_add_head(&context->fbo_list, &entry->entry); - ++context->fbo_entry_count; + entry = wined3d_context_gl_create_fbo_entry(context_gl, + render_targets, depth_stencil, color_location, ds_location); + list_add_head(&context_gl->fbo_list, &entry->entry); + ++context_gl->fbo_entry_count; } else { - entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry); - context_reuse_fbo_entry(context, target, render_targets, depth_stencil, color_location, ds_location, entry); + entry = LIST_ENTRY(list_tail(&context_gl->fbo_list), struct fbo_entry, entry); + wined3d_context_gl_reuse_fbo_entry(context_gl, target, render_targets, + depth_stencil, color_location, ds_location, entry); list_remove(&entry->entry); - list_add_head(&context->fbo_list, &entry->entry); + list_add_head(&context_gl->fbo_list, &entry->entry); } return entry; } /* Context activation is done by the caller. */ -static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry) +static void wined3d_context_gl_apply_fbo_entry(struct wined3d_context_gl *context_gl, + GLenum target, struct fbo_entry *entry) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; GLuint read_binding, draw_binding; unsigned int i; if (entry->flags & WINED3D_FBO_ENTRY_FLAG_ATTACHED) { - context_bind_fbo(context, target, entry->id); + wined3d_context_gl_bind_fbo(context_gl, target, entry->id); return; } - read_binding = context->fbo_read_binding; - draw_binding = context->fbo_draw_binding; - context_bind_fbo(context, GL_FRAMEBUFFER, entry->id); + read_binding = context_gl->fbo_read_binding; + draw_binding = context_gl->fbo_draw_binding; + wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, entry->id); if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) { @@ -737,89 +738,93 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ /* Apply render targets */ for (i = 0; i < gl_info->limits.buffers; ++i) { - context_attach_surface_fbo(context, target, i, &entry->key.objects[i + 1], - entry->key.rb_namespace & (1 << (i + 1))); + wined3d_context_gl_attach_surface_fbo(context_gl, target, i, + &entry->key.objects[i + 1], entry->key.rb_namespace & (1 << (i + 1))); } - context_attach_depth_stencil_fbo(context, target, &entry->key.objects[0], - entry->key.rb_namespace & 0x1, entry->flags); + wined3d_context_gl_attach_depth_stencil_fbo(context_gl, target, + &entry->key.objects[0], entry->key.rb_namespace & 0x1, entry->flags); /* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility * GL contexts requirements. */ gl_info->gl_ops.gl.p_glReadBuffer(GL_NONE); - context_set_draw_buffer(context, GL_NONE); + wined3d_context_gl_set_draw_buffer(context_gl, GL_NONE); if (target != GL_FRAMEBUFFER) { if (target == GL_READ_FRAMEBUFFER) - context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, draw_binding); + wined3d_context_gl_bind_fbo(context_gl, GL_DRAW_FRAMEBUFFER, draw_binding); else - context_bind_fbo(context, GL_READ_FRAMEBUFFER, read_binding); + wined3d_context_gl_bind_fbo(context_gl, GL_READ_FRAMEBUFFER, read_binding); } entry->flags |= WINED3D_FBO_ENTRY_FLAG_ATTACHED; } /* Context activation is done by the caller. */ -static void context_apply_fbo_state(struct wined3d_context *context, GLenum target, - struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, - DWORD color_location, DWORD ds_location) +static void wined3d_context_gl_apply_fbo_state(struct wined3d_context_gl *context_gl, GLenum target, + const struct wined3d_rendertarget_info *render_targets, + const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location) { struct fbo_entry *entry, *entry2; - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry) + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context_gl->fbo_destroy_list, struct fbo_entry, entry) { - context_destroy_fbo_entry(context, entry); + wined3d_context_gl_destroy_fbo_entry(context_gl, entry); } - if (context->rebind_fbo) + if (context_gl->rebind_fbo) { - context_bind_fbo(context, GL_FRAMEBUFFER, 0); - context->rebind_fbo = FALSE; + wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, 0); + context_gl->rebind_fbo = FALSE; } if (color_location == WINED3D_LOCATION_DRAWABLE) { - context->current_fbo = NULL; - context_bind_fbo(context, target, 0); + context_gl->current_fbo = NULL; + wined3d_context_gl_bind_fbo(context_gl, target, 0); } else { - struct wined3d_rendertarget_info ds = {{0}}; - - if (depth_stencil) - { - ds.resource = &depth_stencil->container->resource; - ds.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil); - ds.layer_count = 1; - } - context->current_fbo = context_find_fbo_entry(context, target, - render_targets, &ds, color_location, ds_location); - context_apply_fbo_entry(context, target, context->current_fbo); + context_gl->current_fbo = wined3d_context_gl_find_fbo_entry(context_gl, + target, render_targets, depth_stencil, color_location, ds_location); + wined3d_context_gl_apply_fbo_entry(context_gl, target, context_gl->current_fbo); } } /* Context activation is done by the caller. */ -void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, - struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) +void wined3d_context_gl_apply_fbo_state_blit(struct wined3d_context_gl *context_gl, GLenum target, + struct wined3d_resource *rt, unsigned int rt_sub_resource_idx, + struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location) { - memset(context->blit_targets, 0, sizeof(context->blit_targets)); - if (render_target) + struct wined3d_rendertarget_info ds_info = {{0}}; + + memset(context_gl->blit_targets, 0, sizeof(context_gl->blit_targets)); + if (rt) { - context->blit_targets[0].resource = &render_target->container->resource; - context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target); - context->blit_targets[0].layer_count = 1; + context_gl->blit_targets[0].resource = rt; + context_gl->blit_targets[0].sub_resource_idx = rt_sub_resource_idx; + context_gl->blit_targets[0].layer_count = 1; } - context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location); + + if (ds) + { + ds_info.resource = ds; + ds_info.sub_resource_idx = ds_sub_resource_idx; + ds_info.layer_count = 1; + } + + wined3d_context_gl_apply_fbo_state(context_gl, target, context_gl->blit_targets, &ds_info, location, location); } /* Context activation is done by the caller. */ -void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) +void wined3d_context_gl_alloc_occlusion_query(struct wined3d_context_gl *context_gl, + struct wined3d_occlusion_query *query) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - if (context->free_occlusion_query_count) + if (context_gl->free_occlusion_query_count) { - query->id = context->free_occlusion_queries[--context->free_occlusion_query_count]; + query->id = context_gl->free_occlusion_queries[--context_gl->free_occlusion_query_count]; } else { @@ -828,7 +833,7 @@ void context_alloc_occlusion_query(struct wined3d_context *context, struct wined GL_EXTCALL(glGenQueries(1, &query->id)); checkGLcall("glGenQueries"); - TRACE("Allocated occlusion query %u in context %p.\n", query->id, context); + TRACE("Allocated occlusion query %u in context %p.\n", query->id, context_gl); } else { @@ -837,36 +842,36 @@ void context_alloc_occlusion_query(struct wined3d_context *context, struct wined } } - query->context = context; - list_add_head(&context->occlusion_queries, &query->entry); + query->context_gl = context_gl; + list_add_head(&context_gl->occlusion_queries, &query->entry); } -void context_free_occlusion_query(struct wined3d_occlusion_query *query) +void wined3d_context_gl_free_occlusion_query(struct wined3d_occlusion_query *query) { - struct wined3d_context *context = query->context; + struct wined3d_context_gl *context_gl = query->context_gl; list_remove(&query->entry); - query->context = NULL; + query->context_gl = NULL; - if (!wined3d_array_reserve((void **)&context->free_occlusion_queries, - &context->free_occlusion_query_size, context->free_occlusion_query_count + 1, - sizeof(*context->free_occlusion_queries))) + if (!wined3d_array_reserve((void **)&context_gl->free_occlusion_queries, + &context_gl->free_occlusion_query_size, context_gl->free_occlusion_query_count + 1, + sizeof(*context_gl->free_occlusion_queries))) { - ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context); + ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context_gl); return; } - context->free_occlusion_queries[context->free_occlusion_query_count++] = query->id; + context_gl->free_occlusion_queries[context_gl->free_occlusion_query_count++] = query->id; } /* Context activation is done by the caller. */ -void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *fence) +void wined3d_context_gl_alloc_fence(struct wined3d_context_gl *context_gl, struct wined3d_fence *fence) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - if (context->free_fence_count) + if (context_gl->free_fence_count) { - fence->object = context->free_fences[--context->free_fence_count]; + fence->object = context_gl->free_fences[--context_gl->free_fence_count]; } else { @@ -874,21 +879,21 @@ void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence * { /* Using ARB_sync, not much to do here. */ fence->object.sync = NULL; - TRACE("Allocated sync object in context %p.\n", context); + TRACE("Allocated sync object in context %p.\n", context_gl); } else if (gl_info->supported[APPLE_FENCE]) { GL_EXTCALL(glGenFencesAPPLE(1, &fence->object.id)); checkGLcall("glGenFencesAPPLE"); - TRACE("Allocated fence %u in context %p.\n", fence->object.id, context); + TRACE("Allocated fence %u in context %p.\n", fence->object.id, context_gl); } else if(gl_info->supported[NV_FENCE]) { GL_EXTCALL(glGenFencesNV(1, &fence->object.id)); checkGLcall("glGenFencesNV"); - TRACE("Allocated fence %u in context %p.\n", fence->object.id, context); + TRACE("Allocated fence %u in context %p.\n", fence->object.id, context_gl); } else { @@ -897,75 +902,76 @@ void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence * } } - fence->context = context; - list_add_head(&context->fences, &fence->entry); + fence->context_gl = context_gl; + list_add_head(&context_gl->fences, &fence->entry); } -void context_free_fence(struct wined3d_fence *fence) +void wined3d_context_gl_free_fence(struct wined3d_fence *fence) { - struct wined3d_context *context = fence->context; + struct wined3d_context_gl *context_gl = fence->context_gl; list_remove(&fence->entry); - fence->context = NULL; + fence->context_gl = NULL; - if (!wined3d_array_reserve((void **)&context->free_fences, - &context->free_fence_size, context->free_fence_count + 1, - sizeof(*context->free_fences))) + if (!wined3d_array_reserve((void **)&context_gl->free_fences, + &context_gl->free_fence_size, context_gl->free_fence_count + 1, + sizeof(*context_gl->free_fences))) { - ERR("Failed to grow free list, leaking fence %u in context %p.\n", fence->object.id, context); + ERR("Failed to grow free list, leaking fence %u in context %p.\n", fence->object.id, context_gl); return; } - context->free_fences[context->free_fence_count++] = fence->object; + context_gl->free_fences[context_gl->free_fence_count++] = fence->object; } /* Context activation is done by the caller. */ -void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) +void wined3d_context_gl_alloc_timestamp_query(struct wined3d_context_gl *context_gl, + struct wined3d_timestamp_query *query) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - if (context->free_timestamp_query_count) + if (context_gl->free_timestamp_query_count) { - query->id = context->free_timestamp_queries[--context->free_timestamp_query_count]; + query->id = context_gl->free_timestamp_queries[--context_gl->free_timestamp_query_count]; } else { GL_EXTCALL(glGenQueries(1, &query->id)); checkGLcall("glGenQueries"); - TRACE("Allocated timestamp query %u in context %p.\n", query->id, context); + TRACE("Allocated timestamp query %u in context %p.\n", query->id, context_gl); } - query->context = context; - list_add_head(&context->timestamp_queries, &query->entry); + query->context_gl = context_gl; + list_add_head(&context_gl->timestamp_queries, &query->entry); } -void context_free_timestamp_query(struct wined3d_timestamp_query *query) +void wined3d_context_gl_free_timestamp_query(struct wined3d_timestamp_query *query) { - struct wined3d_context *context = query->context; + struct wined3d_context_gl *context_gl = query->context_gl; list_remove(&query->entry); - query->context = NULL; + query->context_gl = NULL; - if (!wined3d_array_reserve((void **)&context->free_timestamp_queries, - &context->free_timestamp_query_size, context->free_timestamp_query_count + 1, - sizeof(*context->free_timestamp_queries))) + if (!wined3d_array_reserve((void **)&context_gl->free_timestamp_queries, + &context_gl->free_timestamp_query_size, context_gl->free_timestamp_query_count + 1, + sizeof(*context_gl->free_timestamp_queries))) { - ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context); + ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context_gl); return; } - context->free_timestamp_queries[context->free_timestamp_query_count++] = query->id; + context_gl->free_timestamp_queries[context_gl->free_timestamp_query_count++] = query->id; } -void context_alloc_so_statistics_query(struct wined3d_context *context, +void wined3d_context_gl_alloc_so_statistics_query(struct wined3d_context_gl *context_gl, struct wined3d_so_statistics_query *query) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - if (context->free_so_statistics_query_count) + if (context_gl->free_so_statistics_query_count) { - query->u = context->free_so_statistics_queries[--context->free_so_statistics_query_count]; + query->u = context_gl->free_so_statistics_queries[--context_gl->free_so_statistics_query_count]; } else { @@ -973,40 +979,40 @@ void context_alloc_so_statistics_query(struct wined3d_context *context, checkGLcall("glGenQueries"); TRACE("Allocated SO statistics queries %u, %u in context %p.\n", - query->u.id[0], query->u.id[1], context); + query->u.id[0], query->u.id[1], context_gl); } - query->context = context; - list_add_head(&context->so_statistics_queries, &query->entry); + query->context_gl = context_gl; + list_add_head(&context_gl->so_statistics_queries, &query->entry); } -void context_free_so_statistics_query(struct wined3d_so_statistics_query *query) +void wined3d_context_gl_free_so_statistics_query(struct wined3d_so_statistics_query *query) { - struct wined3d_context *context = query->context; + struct wined3d_context_gl *context_gl = query->context_gl; list_remove(&query->entry); - query->context = NULL; + query->context_gl = NULL; - if (!wined3d_array_reserve((void **)&context->free_so_statistics_queries, - &context->free_so_statistics_query_size, context->free_so_statistics_query_count + 1, - sizeof(*context->free_so_statistics_queries))) + if (!wined3d_array_reserve((void **)&context_gl->free_so_statistics_queries, + &context_gl->free_so_statistics_query_size, context_gl->free_so_statistics_query_count + 1, + sizeof(*context_gl->free_so_statistics_queries))) { ERR("Failed to grow free list, leaking GL queries %u, %u in context %p.\n", - query->u.id[0], query->u.id[1], context); + query->u.id[0], query->u.id[1], context_gl); return; } - context->free_so_statistics_queries[context->free_so_statistics_query_count++] = query->u; + context_gl->free_so_statistics_queries[context_gl->free_so_statistics_query_count++] = query->u; } -void context_alloc_pipeline_statistics_query(struct wined3d_context *context, +void wined3d_context_gl_alloc_pipeline_statistics_query(struct wined3d_context_gl *context_gl, struct wined3d_pipeline_statistics_query *query) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - if (context->free_pipeline_statistics_query_count) + if (context_gl->free_pipeline_statistics_query_count) { - query->u = context->free_pipeline_statistics_queries[--context->free_pipeline_statistics_query_count]; + query->u = context_gl->free_pipeline_statistics_queries[--context_gl->free_pipeline_statistics_query_count]; } else { @@ -1014,49 +1020,49 @@ void context_alloc_pipeline_statistics_query(struct wined3d_context *context, checkGLcall("glGenQueries"); } - query->context = context; - list_add_head(&context->pipeline_statistics_queries, &query->entry); + query->context_gl = context_gl; + list_add_head(&context_gl->pipeline_statistics_queries, &query->entry); } -void context_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query) +void wined3d_context_gl_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query) { - struct wined3d_context *context = query->context; + struct wined3d_context_gl *context_gl = query->context_gl; list_remove(&query->entry); - query->context = NULL; + query->context_gl = NULL; - if (!wined3d_array_reserve((void **)&context->free_pipeline_statistics_queries, - &context->free_pipeline_statistics_query_size, context->free_pipeline_statistics_query_count + 1, - sizeof(*context->free_pipeline_statistics_queries))) + if (!wined3d_array_reserve((void **)&context_gl->free_pipeline_statistics_queries, + &context_gl->free_pipeline_statistics_query_size, context_gl->free_pipeline_statistics_query_count + 1, + sizeof(*context_gl->free_pipeline_statistics_queries))) { - ERR("Failed to grow free list, leaking GL queries in context %p.\n", context); + ERR("Failed to grow free list, leaking GL queries in context %p.\n", context_gl); return; } - context->free_pipeline_statistics_queries[context->free_pipeline_statistics_query_count++] = query->u; + context_gl->free_pipeline_statistics_queries[context_gl->free_pipeline_statistics_query_count++] = query->u; } -typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct fbo_entry *entry); +typedef void (context_fbo_entry_func_t)(struct wined3d_context_gl *context_gl, struct fbo_entry *entry); -static void context_enum_fbo_entries(const struct wined3d_device *device, +static void wined3d_context_gl_enum_fbo_entries(const struct wined3d_device *device, GLuint name, BOOL rb_namespace, context_fbo_entry_func_t *callback) { unsigned int i, j; for (i = 0; i < device->context_count; ++i) { - struct wined3d_context *context = device->contexts[i]; - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(device->contexts[i]); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct fbo_entry *entry, *entry2; - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context_gl->fbo_list, struct fbo_entry, entry) { for (j = 0; j < gl_info->limits.buffers + 1; ++j) { if (entry->key.objects[j].object == name && !(entry->key.rb_namespace & (1 << j)) == !rb_namespace) { - callback(context, entry); + callback(context_gl, entry); break; } } @@ -1064,112 +1070,104 @@ static void context_enum_fbo_entries(const struct wined3d_device *device, } } -static void context_queue_fbo_entry_destruction(struct wined3d_context *context, struct fbo_entry *entry) +static void wined3d_context_gl_queue_fbo_entry_destruction(struct wined3d_context_gl *context_gl, + struct fbo_entry *entry) { list_remove(&entry->entry); - list_add_head(&context->fbo_destroy_list, &entry->entry); + list_add_head(&context_gl->fbo_destroy_list, &entry->entry); } -void context_resource_released(const struct wined3d_device *device, - struct wined3d_resource *resource, enum wined3d_resource_type type) +void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource) { - struct wined3d_texture *texture; - UINT i; + unsigned int i; if (!device->d3d_initialized) return; - switch (type) + for (i = 0; i < device->context_count; ++i) { - case WINED3D_RTYPE_TEXTURE_2D: - case WINED3D_RTYPE_TEXTURE_3D: - texture = texture_from_resource(resource); - - for (i = 0; i < device->context_count; ++i) - { - struct wined3d_context *context = device->contexts[i]; - if (context->current_rt.texture == texture) - { - context->current_rt.texture = NULL; - context->current_rt.sub_resource_idx = 0; - } - } - break; + struct wined3d_context *context = device->contexts[i]; - default: - break; + if (&context->current_rt.texture->resource == resource) + { + context->current_rt.texture = NULL; + context->current_rt.sub_resource_idx = 0; + } } } -void context_gl_resource_released(struct wined3d_device *device, - GLuint name, BOOL rb_namespace) +void context_gl_resource_released(struct wined3d_device *device, GLuint name, BOOL rb_namespace) { - context_enum_fbo_entries(device, name, rb_namespace, context_queue_fbo_entry_destruction); + wined3d_context_gl_enum_fbo_entries(device, name, rb_namespace, + wined3d_context_gl_queue_fbo_entry_destruction); } -void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) +void wined3d_context_gl_texture_update(struct wined3d_context_gl *context_gl, + const struct wined3d_texture_gl *texture_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; - struct fbo_entry *entry = context->current_fbo; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct fbo_entry *entry = context_gl->current_fbo; unsigned int i; - if (!entry || context->rebind_fbo) return; + if (!entry || context_gl->rebind_fbo) + return; for (i = 0; i < gl_info->limits.buffers + 1; ++i) { - if (surface->container->texture_rgb.name == entry->key.objects[i].object - || surface->container->texture_srgb.name == entry->key.objects[i].object) + if (texture_gl->texture_rgb.name == entry->key.objects[i].object + || texture_gl->texture_srgb.name == entry->key.objects[i].object) { - TRACE("Updated surface %p is bound as attachment %u to the current FBO.\n", surface, i); - context->rebind_fbo = TRUE; + TRACE("Updated texture %p is bound as attachment %u to the current FBO.\n", texture_gl, i); + context_gl->rebind_fbo = TRUE; return; } } } -static BOOL context_restore_pixel_format(struct wined3d_context *ctx) +static BOOL wined3d_context_gl_restore_pixel_format(struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = ctx->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; BOOL ret = FALSE; - if (ctx->restore_pf && IsWindow(ctx->restore_pf_win)) + if (context_gl->restore_pf && IsWindow(context_gl->restore_pf_win)) { - if (ctx->gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) + if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) { - HDC dc = GetDCEx(ctx->restore_pf_win, 0, DCX_USESTYLE | DCX_CACHE); + HDC dc = GetDCEx(context_gl->restore_pf_win, 0, DCX_USESTYLE | DCX_CACHE); if (dc) { - if (!(ret = GL_EXTCALL(wglSetPixelFormatWINE(dc, ctx->restore_pf)))) + if (!(ret = GL_EXTCALL(wglSetPixelFormatWINE(dc, context_gl->restore_pf)))) { - ERR("wglSetPixelFormatWINE failed to restore pixel format %d on window %p.\n", - ctx->restore_pf, ctx->restore_pf_win); + ERR("Failed to restore pixel format %d on window %p.\n", + context_gl->restore_pf, context_gl->restore_pf_win); } - ReleaseDC(ctx->restore_pf_win, dc); + ReleaseDC(context_gl->restore_pf_win, dc); } } else { - ERR("can't restore pixel format %d on window %p\n", ctx->restore_pf, ctx->restore_pf_win); + ERR("Unable to restore pixel format %d on window %p.\n", + context_gl->restore_pf, context_gl->restore_pf_win); } } - ctx->restore_pf = 0; - ctx->restore_pf_win = NULL; + context_gl->restore_pf = 0; + context_gl->restore_pf_win = NULL; return ret; } -static BOOL context_set_pixel_format(struct wined3d_context *context) +static BOOL wined3d_context_gl_set_pixel_format(struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; - BOOL private = context->hdc_is_private; - int format = context->pixel_format; - HDC dc = context->hdc; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + BOOL private = context_gl->dc_is_private; + int format = context_gl->pixel_format; + HDC dc = context_gl->dc; int current; - if (private && context->hdc_has_format) + if (private && context_gl->dc_has_format) return TRUE; - if (!private && WindowFromDC(dc) != context->win_handle) + if (!private && WindowFromDC(dc) != context_gl->window) return FALSE; current = gl_info->gl_ops.wgl.p_wglGetPixelFormat(dc); @@ -1185,8 +1183,8 @@ static BOOL context_set_pixel_format(struct wined3d_context *context) return FALSE; } - context->restore_pf = 0; - context->restore_pf_win = private ? NULL : WindowFromDC(dc); + context_gl->restore_pf = 0; + context_gl->restore_pf_win = private ? NULL : WindowFromDC(dc); goto success; } @@ -1206,12 +1204,12 @@ static BOOL context_set_pixel_format(struct wined3d_context *context) } win = private ? NULL : WindowFromDC(dc); - if (win != context->restore_pf_win) + if (win != context_gl->restore_pf_win) { - context_restore_pixel_format(context); + wined3d_context_gl_restore_pixel_format(context_gl); - context->restore_pf = private ? 0 : current; - context->restore_pf_win = win; + context_gl->restore_pf = private ? 0 : current; + context_gl->restore_pf_win = win; } goto success; @@ -1227,68 +1225,69 @@ static BOOL context_set_pixel_format(struct wined3d_context *context) success: if (private) - context->hdc_has_format = TRUE; + context_gl->dc_has_format = TRUE; return TRUE; } -static BOOL context_set_gl_context(struct wined3d_context *ctx) +static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context_gl) { - struct wined3d_swapchain *swapchain = ctx->swapchain; + struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(context_gl->c.swapchain); BOOL backup = FALSE; - if (!context_set_pixel_format(ctx)) + if (!wined3d_context_gl_set_pixel_format(context_gl)) { WARN("Failed to set pixel format %d on device context %p.\n", - ctx->pixel_format, ctx->hdc); + context_gl->pixel_format, context_gl->dc); backup = TRUE; } - if (backup || !wglMakeCurrent(ctx->hdc, ctx->glCtx)) + if (backup || !wglMakeCurrent(context_gl->dc, context_gl->gl_ctx)) { WARN("Failed to make GL context %p current on device context %p, last error %#x.\n", - ctx->glCtx, ctx->hdc, GetLastError()); - ctx->valid = 0; + context_gl->gl_ctx, context_gl->dc, GetLastError()); + context_gl->valid = 0; WARN("Trying fallback to the backup window.\n"); /* FIXME: If the context is destroyed it's no longer associated with * a swapchain, so we can't use the swapchain to get a backup dc. To * make this work windowless contexts would need to be handled by the * device. */ - if (ctx->destroyed || !swapchain) + if (context_gl->c.destroyed || !swapchain_gl) { - FIXME("Unable to get backup dc for destroyed context %p.\n", ctx); - context_set_current(NULL); + FIXME("Unable to get backup dc for destroyed context %p.\n", context_gl); + wined3d_context_gl_set_current(NULL); return FALSE; } - if (!(ctx->hdc = swapchain_get_backup_dc(swapchain))) + if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) { - context_set_current(NULL); + wined3d_context_gl_set_current(NULL); return FALSE; } - ctx->hdc_is_private = TRUE; - ctx->hdc_has_format = FALSE; + context_gl->dc_is_private = TRUE; + context_gl->dc_has_format = FALSE; - if (!context_set_pixel_format(ctx)) + if (!wined3d_context_gl_set_pixel_format(context_gl)) { ERR("Failed to set pixel format %d on device context %p.\n", - ctx->pixel_format, ctx->hdc); - context_set_current(NULL); + context_gl->pixel_format, context_gl->dc); + wined3d_context_gl_set_current(NULL); return FALSE; } - if (!wglMakeCurrent(ctx->hdc, ctx->glCtx)) + if (!wglMakeCurrent(context_gl->dc, context_gl->gl_ctx)) { ERR("Fallback to backup window (dc %p) failed too, last error %#x.\n", - ctx->hdc, GetLastError()); - context_set_current(NULL); + context_gl->dc, GetLastError()); + wined3d_context_gl_set_current(NULL); return FALSE; } - ctx->valid = 1; + context_gl->valid = 1; } - ctx->needs_set = 0; + context_gl->needs_set = 0; + return TRUE; } @@ -1298,41 +1297,45 @@ static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HD { ERR("Failed to restore GL context %p on device context %p, last error %#x.\n", gl_ctx, dc, GetLastError()); - context_set_current(NULL); + wined3d_context_gl_set_current(NULL); } } -static void context_update_window(struct wined3d_context *context) +static void wined3d_context_gl_update_window(struct wined3d_context_gl *context_gl) { - if (!context->swapchain) + if (!context_gl->c.swapchain) return; - if (context->win_handle == context->swapchain->win_handle) + if (context_gl->window == context_gl->c.swapchain->win_handle) return; TRACE("Updating context %p window from %p to %p.\n", - context, context->win_handle, context->swapchain->win_handle); + context_gl, context_gl->window, context_gl->c.swapchain->win_handle); - if (context->hdc) - wined3d_release_dc(context->win_handle, context->hdc); + if (context_gl->dc) + wined3d_release_dc(context_gl->window, context_gl->dc); - context->win_handle = context->swapchain->win_handle; - context->hdc_is_private = FALSE; - context->hdc_has_format = FALSE; - context->needs_set = 1; - context->valid = 1; + context_gl->window = context_gl->c.swapchain->win_handle; + context_gl->dc_is_private = FALSE; + context_gl->dc_has_format = FALSE; + context_gl->needs_set = 1; + context_gl->valid = 1; - if (!(context->hdc = GetDCEx(context->win_handle, 0, DCX_USESTYLE | DCX_CACHE))) + if (!(context_gl->dc = GetDCEx(context_gl->window, 0, DCX_USESTYLE | DCX_CACHE))) { - ERR("Failed to get a device context for window %p.\n", context->win_handle); - context->valid = 0; + ERR("Failed to get a device context for window %p.\n", context_gl->window); + context_gl->valid = 0; } } -static void context_destroy_gl_resources(struct wined3d_context *context) +void wined3d_context_cleanup(struct wined3d_context *context) +{ +} + +static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl) { struct wined3d_pipeline_statistics_query *pipeline_statistics_query; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_so_statistics_query *so_statistics_query; struct wined3d_timestamp_query *timestamp_query; struct wined3d_occlusion_query *occlusion_query; @@ -1345,44 +1348,93 @@ static void context_destroy_gl_resources(struct wined3d_context *context) restore_ctx = wglGetCurrentContext(); restore_dc = wglGetCurrentDC(); - if (restore_ctx == context->glCtx) + if (restore_ctx == context_gl->gl_ctx) restore_ctx = NULL; - else if (context->valid) - context_set_gl_context(context); + else if (context_gl->valid) + wined3d_context_gl_set_gl_context(context_gl); - LIST_FOR_EACH_ENTRY(so_statistics_query, &context->so_statistics_queries, - struct wined3d_so_statistics_query, entry) + if (context_gl->valid) { - if (context->valid) - GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(so_statistics_query->u.id), so_statistics_query->u.id)); - so_statistics_query->context = NULL; + if (context_gl->dummy_arbfp_prog) + GL_EXTCALL(glDeleteProgramsARB(1, &context_gl->dummy_arbfp_prog)); + + if (context_gl->blit_vbo) + GL_EXTCALL(glDeleteBuffers(1, &context_gl->blit_vbo)); + + for (i = 0; i < context_gl->free_pipeline_statistics_query_count; ++i) + { + union wined3d_gl_pipeline_statistics_query *q = &context_gl->free_pipeline_statistics_queries[i]; + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(q->id), q->id)); + } + + for (i = 0; i < context_gl->free_so_statistics_query_count; ++i) + { + union wined3d_gl_so_statistics_query *q = &context_gl->free_so_statistics_queries[i]; + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(q->id), q->id)); + } + + if (context_gl->free_timestamp_query_count) + GL_EXTCALL(glDeleteQueries(context_gl->free_timestamp_query_count, context_gl->free_timestamp_queries)); + + if (gl_info->supported[ARB_SYNC]) + { + for (i = 0; i < context_gl->free_fence_count; ++i) + { + GL_EXTCALL(glDeleteSync(context_gl->free_fences[i].sync)); + } + } + else if (gl_info->supported[APPLE_FENCE]) + { + for (i = 0; i < context_gl->free_fence_count; ++i) + { + GL_EXTCALL(glDeleteFencesAPPLE(1, &context_gl->free_fences[i].id)); + } + } + else if (gl_info->supported[NV_FENCE]) + { + for (i = 0; i < context_gl->free_fence_count; ++i) + { + GL_EXTCALL(glDeleteFencesNV(1, &context_gl->free_fences[i].id)); + } + } + + if (context_gl->free_occlusion_query_count) + GL_EXTCALL(glDeleteQueries(context_gl->free_occlusion_query_count, context_gl->free_occlusion_queries)); + + checkGLcall("context cleanup"); } + heap_free(context_gl->free_pipeline_statistics_queries); + heap_free(context_gl->free_so_statistics_queries); + heap_free(context_gl->free_timestamp_queries); + heap_free(context_gl->free_fences); + heap_free(context_gl->free_occlusion_queries); - LIST_FOR_EACH_ENTRY(pipeline_statistics_query, &context->pipeline_statistics_queries, + LIST_FOR_EACH_ENTRY(pipeline_statistics_query, &context_gl->pipeline_statistics_queries, struct wined3d_pipeline_statistics_query, entry) { - if (context->valid) + if (context_gl->valid) GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(pipeline_statistics_query->u.id), pipeline_statistics_query->u.id)); - pipeline_statistics_query->context = NULL; + pipeline_statistics_query->context_gl = NULL; } - LIST_FOR_EACH_ENTRY(timestamp_query, &context->timestamp_queries, struct wined3d_timestamp_query, entry) + LIST_FOR_EACH_ENTRY(so_statistics_query, &context_gl->so_statistics_queries, + struct wined3d_so_statistics_query, entry) { - if (context->valid) - GL_EXTCALL(glDeleteQueries(1, ×tamp_query->id)); - timestamp_query->context = NULL; + if (context_gl->valid) + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(so_statistics_query->u.id), so_statistics_query->u.id)); + so_statistics_query->context_gl = NULL; } - LIST_FOR_EACH_ENTRY(occlusion_query, &context->occlusion_queries, struct wined3d_occlusion_query, entry) + LIST_FOR_EACH_ENTRY(timestamp_query, &context_gl->timestamp_queries, struct wined3d_timestamp_query, entry) { - if (context->valid && gl_info->supported[ARB_OCCLUSION_QUERY]) - GL_EXTCALL(glDeleteQueries(1, &occlusion_query->id)); - occlusion_query->context = NULL; + if (context_gl->valid) + GL_EXTCALL(glDeleteQueries(1, ×tamp_query->id)); + timestamp_query->context_gl = NULL; } - LIST_FOR_EACH_ENTRY(fence, &context->fences, struct wined3d_fence, entry) + LIST_FOR_EACH_ENTRY(fence, &context_gl->fences, struct wined3d_fence, entry) { - if (context->valid) + if (context_gl->valid) { if (gl_info->supported[ARB_SYNC]) { @@ -1398,100 +1450,52 @@ static void context_destroy_gl_resources(struct wined3d_context *context) GL_EXTCALL(glDeleteFencesNV(1, &fence->object.id)); } } - fence->context = NULL; + fence->context_gl = NULL; } - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry) + LIST_FOR_EACH_ENTRY(occlusion_query, &context_gl->occlusion_queries, struct wined3d_occlusion_query, entry) { - if (!context->valid) entry->id = 0; - context_destroy_fbo_entry(context, entry); + if (context_gl->valid) + GL_EXTCALL(glDeleteQueries(1, &occlusion_query->id)); + occlusion_query->context_gl = NULL; } - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context_gl->fbo_destroy_list, struct fbo_entry, entry) { - if (!context->valid) entry->id = 0; - context_destroy_fbo_entry(context, entry); + if (!context_gl->valid) + entry->id = 0; + wined3d_context_gl_destroy_fbo_entry(context_gl, entry); } - if (context->valid) + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context_gl->fbo_list, struct fbo_entry, entry) { - if (context->dummy_arbfp_prog) - { - GL_EXTCALL(glDeleteProgramsARB(1, &context->dummy_arbfp_prog)); - } - - if (gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY]) - { - for (i = 0; i < context->free_so_statistics_query_count; ++i) - { - union wined3d_gl_so_statistics_query *q = &context->free_so_statistics_queries[i]; - GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(q->id), q->id)); - } - } - - if (gl_info->supported[ARB_PIPELINE_STATISTICS_QUERY]) - { - for (i = 0; i < context->free_pipeline_statistics_query_count; ++i) - { - union wined3d_gl_pipeline_statistics_query *q = &context->free_pipeline_statistics_queries[i]; - GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(q->id), q->id)); - } - } - - if (gl_info->supported[ARB_TIMER_QUERY]) - GL_EXTCALL(glDeleteQueries(context->free_timestamp_query_count, context->free_timestamp_queries)); - - if (gl_info->supported[ARB_OCCLUSION_QUERY]) - GL_EXTCALL(glDeleteQueries(context->free_occlusion_query_count, context->free_occlusion_queries)); - - if (gl_info->supported[ARB_SYNC]) - { - for (i = 0; i < context->free_fence_count; ++i) - { - GL_EXTCALL(glDeleteSync(context->free_fences[i].sync)); - } - } - else if (gl_info->supported[APPLE_FENCE]) - { - for (i = 0; i < context->free_fence_count; ++i) - { - GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_fences[i].id)); - } - } - else if (gl_info->supported[NV_FENCE]) - { - for (i = 0; i < context->free_fence_count; ++i) - { - GL_EXTCALL(glDeleteFencesNV(1, &context->free_fences[i].id)); - } - } - - checkGLcall("context cleanup"); + if (!context_gl->valid) + entry->id = 0; + wined3d_context_gl_destroy_fbo_entry(context_gl, entry); } - heap_free(context->free_so_statistics_queries); - heap_free(context->free_pipeline_statistics_queries); - heap_free(context->free_timestamp_queries); - heap_free(context->free_occlusion_queries); - heap_free(context->free_fences); + heap_free(context_gl->texture_type); - context_restore_pixel_format(context); + wined3d_context_gl_restore_pixel_format(context_gl); if (restore_ctx) - { context_restore_gl_context(gl_info, restore_dc, restore_ctx); - } else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL)) - { ERR("Failed to disable GL context.\n"); - } - wined3d_release_dc(context->win_handle, context->hdc); + wined3d_release_dc(context_gl->window, context_gl->dc); - if (!wglDeleteContext(context->glCtx)) + if (!wglDeleteContext(context_gl->gl_ctx)) { DWORD err = GetLastError(); - ERR("wglDeleteContext(%p) failed, last error %#x.\n", context->glCtx, err); + ERR("Failed to delete GL context %p, last error %#x.\n", context_gl->gl_ctx, err); } + + wined3d_context_cleanup(&context_gl->c); +} + +void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) +{ + wined3d_context_cleanup(&context_vk->c); } DWORD context_get_tls_idx(void) @@ -1504,27 +1508,27 @@ void context_set_tls_idx(DWORD idx) wined3d_context_tls_idx = idx; } -struct wined3d_context *context_get_current(void) +struct wined3d_context_gl *wined3d_context_gl_get_current(void) { return TlsGetValue(wined3d_context_tls_idx); } -BOOL context_set_current(struct wined3d_context *ctx) +BOOL wined3d_context_gl_set_current(struct wined3d_context_gl *context_gl) { - struct wined3d_context *old = context_get_current(); + struct wined3d_context_gl *old = wined3d_context_gl_get_current(); - if (old == ctx) + if (old == context_gl) { - TRACE("Already using D3D context %p.\n", ctx); + TRACE("Already using D3D context %p.\n", context_gl); return TRUE; } if (old) { - if (old->destroyed) + if (old->c.destroyed) { TRACE("Switching away from destroyed context %p.\n", old); - context_destroy_gl_resources(old); + wined3d_context_gl_cleanup(old); heap_free((void *)old->gl_info); heap_free(old); } @@ -1533,25 +1537,26 @@ BOOL context_set_current(struct wined3d_context *ctx) if (wglGetCurrentContext()) { const struct wined3d_gl_info *gl_info = old->gl_info; - TRACE("Flushing context %p before switching to %p.\n", old, ctx); + TRACE("Flushing context %p before switching to %p.\n", old, context_gl); gl_info->gl_ops.gl.p_glFlush(); } - old->current = 0; + old->c.current = 0; } } - if (ctx) + if (context_gl) { - if (!ctx->valid) + if (!context_gl->valid) { - ERR("Trying to make invalid context %p current\n", ctx); + ERR("Trying to make invalid context %p current.\n", context_gl); return FALSE; } - TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", ctx, ctx->glCtx, ctx->hdc); - if (!context_set_gl_context(ctx)) + TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", + context_gl, context_gl->gl_ctx, context_gl->dc); + if (!wined3d_context_gl_set_gl_context(context_gl)) return FALSE; - ctx->current = 1; + context_gl->c.current = 1; } else if (wglGetCurrentContext()) { @@ -1565,37 +1570,37 @@ BOOL context_set_current(struct wined3d_context *ctx) } } - return TlsSetValue(wined3d_context_tls_idx, ctx); + return TlsSetValue(wined3d_context_tls_idx, context_gl); } -void context_release(struct wined3d_context *context) +void wined3d_context_gl_release(struct wined3d_context_gl *context_gl) { - TRACE("Releasing context %p, level %u.\n", context, context->level); + TRACE("Releasing context %p, level %u.\n", context_gl, context_gl->level); if (WARN_ON(d3d)) { - if (!context->level) - WARN("Context %p is not active.\n", context); - else if (context != context_get_current()) - WARN("Context %p is not the current context.\n", context); + if (!context_gl->level) + WARN("Context %p is not active.\n", context_gl); + else if (context_gl != wined3d_context_gl_get_current()) + WARN("Context %p is not the current context.\n", context_gl); } - if (!--context->level) + if (!--context_gl->level) { - if (context_restore_pixel_format(context)) - context->needs_set = 1; - if (context->restore_ctx) + if (wined3d_context_gl_restore_pixel_format(context_gl)) + context_gl->needs_set = 1; + if (context_gl->restore_ctx) { - TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc); - context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx); - context->restore_ctx = NULL; - context->restore_dc = NULL; + TRACE("Restoring GL context %p on device context %p.\n", context_gl->restore_ctx, context_gl->restore_dc); + context_restore_gl_context(context_gl->gl_info, context_gl->restore_dc, context_gl->restore_ctx); + context_gl->restore_ctx = NULL; + context_gl->restore_dc = NULL; } - if (context->destroy_delayed) + if (context_gl->c.destroy_delayed) { - TRACE("Destroying context %p.\n", context); - context_destroy(context->device, context); + TRACE("Destroying context %p.\n", context_gl); + wined3d_context_gl_destroy(context_gl); } } } @@ -1603,39 +1608,37 @@ void context_release(struct wined3d_context *context) /* This is used when a context for render target A is active, but a separate context is * needed to access the WGL framebuffer for render target B. Re-acquire a context for rt * A to avoid breaking caller code. */ -void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) +void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, unsigned int sub_resource_idx) { - if (context->current_rt.texture != restore->container - || context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore)) + if (context->current_rt.texture != texture || context->current_rt.sub_resource_idx != sub_resource_idx) { context_release(context); - context = context_acquire(restore->container->resource.device, - restore->container, surface_get_sub_resource_idx(restore)); + context = context_acquire(texture->resource.device, texture, sub_resource_idx); } context_release(context); } -static void context_enter(struct wined3d_context *context) +static void wined3d_context_gl_enter(struct wined3d_context_gl *context_gl) { - TRACE("Entering context %p, level %u.\n", context, context->level + 1); + TRACE("Entering context %p, level %u.\n", context_gl, context_gl->level + 1); - if (!context->level++) + if (!context_gl->level++) { - const struct wined3d_context *current_context = context_get_current(); + const struct wined3d_context_gl *current_context = wined3d_context_gl_get_current(); HGLRC current_gl = wglGetCurrentContext(); - if (current_gl && (!current_context || current_context->glCtx != current_gl)) + if (current_gl && (!current_context || current_context->gl_ctx != current_gl)) { TRACE("Another GL context (%p on device context %p) is already current.\n", current_gl, wglGetCurrentDC()); - context->restore_ctx = current_gl; - context->restore_dc = wglGetCurrentDC(); - context->needs_set = 1; + context_gl->restore_ctx = current_gl; + context_gl->restore_dc = wglGetCurrentDC(); + context_gl->needs_set = 1; } - else if (!context->needs_set && !(context->hdc_is_private && context->hdc_has_format) - && context->pixel_format != context->gl_info->gl_ops.wgl.p_wglGetPixelFormat(context->hdc)) - context->needs_set = 1; + else if (!context_gl->needs_set && !(context_gl->dc_is_private && context_gl->dc_has_format) + && context_gl->pixel_format != context_gl->gl_info->gl_ops.wgl.p_wglGetPixelFormat(context_gl->dc)) + context_gl->needs_set = 1; } } @@ -1649,18 +1652,14 @@ void context_invalidate_compute_state(struct wined3d_context *context, DWORD sta context->dirty_compute_states[index] |= (1u << shift); } -void context_invalidate_state(struct wined3d_context *context, DWORD state) +void context_invalidate_state(struct wined3d_context *context, unsigned int state_id) { - DWORD rep = context->state_table[state].representative; - DWORD idx; - BYTE shift; - - if (isStateDirty(context, rep)) return; + unsigned int representative = context->state_table[state_id].representative; + unsigned int index, shift; - context->dirtyArray[context->numDirtyEntries++] = rep; - idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] |= (1u << shift); + index = representative / (sizeof(*context->dirty_graphics_states) * CHAR_BIT); + shift = representative & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1); + context->dirty_graphics_states[index] |= (1u << shift); } /* This function takes care of wined3d pixel format selection. */ @@ -1668,7 +1667,7 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC const struct wined3d_format *color_format, const struct wined3d_format *ds_format, BOOL auxBuffers) { - unsigned int cfg_count = device->adapter->cfg_count; + unsigned int cfg_count = wined3d_adapter_gl(device->adapter)->pixel_format_count; unsigned int current_value; PIXELFORMATDESCRIPTOR pfd; int iPixelFormat = 0; @@ -1681,7 +1680,7 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC current_value = 0; for (i = 0; i < cfg_count; ++i) { - const struct wined3d_pixel_format *cfg = &device->adapter->cfgs[i]; + const struct wined3d_pixel_format *cfg = &wined3d_adapter_gl(device->adapter)->pixel_formats[i]; unsigned int value; /* For now only accept RGBA formats. Perhaps some day we will @@ -1761,10 +1760,10 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC } /* Context activation is done by the caller. */ -void context_bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context) +void wined3d_context_gl_bind_dummy_textures(const struct wined3d_context_gl *context_gl) { - const struct wined3d_dummy_textures *textures = &context->device->dummy_textures; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_dummy_textures *textures = &wined3d_device_gl(context_gl->c.device)->dummy_textures; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int i; for (i = 0; i < gl_info->limits.combined_samplers; ++i) @@ -1791,6 +1790,7 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array); gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array); } + if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer); @@ -1866,8 +1866,6 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version >> 16; ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_MINOR_VERSION_ARB; ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version & 0xffff; - if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2)) - ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (ctx_flags) { ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB; @@ -1877,9 +1875,20 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs))) { - if (ctx_flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) + if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2)) { - ctx_attribs[ctx_attrib_idx - 1] &= ~WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + if (ctx_flags) + { + ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + ctx_attribs[ctx_attrib_idx - 1] = ctx_flags; + } + else + { + ctx_flags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB; + ctx_attribs[ctx_attrib_idx++] = ctx_flags; + ctx_attribs[ctx_attrib_idx] = 0; + } if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs))) WARN("Failed to create a WGL context with wglCreateContextAttribsARB, last error %#x.\n", GetLastError()); @@ -1888,240 +1897,264 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, return ctx; } -struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, - struct wined3d_texture *target, const struct wined3d_format *ds_format) +static void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapchain *swapchain) { struct wined3d_device *device = swapchain->device; - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *color_format; - struct wined3d_context *ret; - BOOL auxBuffers = FALSE; - HGLRC ctx, share_ctx; - DWORD target_usage; - unsigned int i; DWORD state; - TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle); + context->d3d_info = &device->adapter->d3d_info; + context->state_table = device->state_table; - wined3d_from_cs(device->cs); + /* Mark all states dirty to force a proper initialization of the states on + * the first use of the context. Compute states do not need initialization. */ + for (state = 0; state <= STATE_HIGHEST; ++state) + { + if (context->state_table[state].representative && !STATE_IS_COMPUTE(state)) + context_invalidate_state(context, state); + } - if (!(ret = heap_alloc_zero(sizeof(*ret)))) - return NULL; + context->device = device; + context->swapchain = swapchain; + context->current_rt.texture = swapchain->front_buffer; + context->current_rt.sub_resource_idx = 0; + + context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) + | (1u << WINED3D_SHADER_TYPE_VERTEX) + | (1u << WINED3D_SHADER_TYPE_GEOMETRY) + | (1u << WINED3D_SHADER_TYPE_HULL) + | (1u << WINED3D_SHADER_TYPE_DOMAIN) + | (1u << WINED3D_SHADER_TYPE_COMPUTE); +} + +HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct wined3d_swapchain *swapchain) +{ + TRACE("context_no3d %p, swapchain %p.\n", context_no3d, swapchain); - ret->free_timestamp_query_size = 4; - if (!(ret->free_timestamp_queries = heap_calloc(ret->free_timestamp_query_size, - sizeof(*ret->free_timestamp_queries)))) - goto out; - list_init(&ret->timestamp_queries); + wined3d_context_init(context_no3d, swapchain); - ret->free_occlusion_query_size = 4; - if (!(ret->free_occlusion_queries = heap_calloc(ret->free_occlusion_query_size, - sizeof(*ret->free_occlusion_queries)))) - goto out; - list_init(&ret->occlusion_queries); + return WINED3D_OK; +} - ret->free_fence_size = 4; - if (!(ret->free_fences = heap_calloc(ret->free_fence_size, sizeof(*ret->free_fences)))) - goto out; - list_init(&ret->fences); +HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wined3d_swapchain_gl *swapchain_gl) +{ + const struct wined3d_format *color_format, *ds_format; + struct wined3d_context *context = &context_gl->c; + const struct wined3d_d3d_info *d3d_info; + const struct wined3d_gl_info *gl_info; + struct wined3d_resource *target; + unsigned int target_bind_flags; + struct wined3d_device *device; + HGLRC ctx, share_ctx; + unsigned int i; - list_init(&ret->so_statistics_queries); + TRACE("context_gl %p, swapchain %p.\n", context_gl, swapchain_gl); - list_init(&ret->pipeline_statistics_queries); + wined3d_context_init(&context_gl->c, &swapchain_gl->s); - list_init(&ret->fbo_list); - list_init(&ret->fbo_destroy_list); + device = context->device; + gl_info = &device->adapter->gl_info; + context_gl->gl_info = gl_info; + d3d_info = context->d3d_info; - if (!device->shader_backend->shader_allocate_context_data(ret)) + context_gl->tid = GetCurrentThreadId(); + context_gl->window = context->swapchain->win_handle; + if (context_gl->window == GetDesktopWindow()) { - ERR("Failed to allocate shader backend context data.\n"); - goto out; + TRACE("Swapchain is created on the desktop window, trying backup device context.\n"); + context_gl->dc = NULL; } - if (!device->adapter->fragment_pipe->allocate_context_data(ret)) + else if (!(context_gl->dc = GetDCEx(context_gl->window, 0, DCX_USESTYLE | DCX_CACHE))) + WARN("Failed to retrieve device context, trying swapchain backup.\n"); + + if (!context_gl->dc) { - ERR("Failed to allocate fragment pipeline context data.\n"); - goto out; + if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + { + ERR("Failed to retrieve a device context.\n"); + return E_FAIL; + } + context_gl->dc_is_private = TRUE; } - for (i = 0; i < ARRAY_SIZE(ret->tex_unit_map); ++i) - ret->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; - for (i = 0; i < ARRAY_SIZE(ret->rev_tex_unit_map); ++i) - ret->rev_tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; - if (gl_info->limits.graphics_samplers >= MAX_COMBINED_SAMPLERS) + list_init(&context_gl->fbo_list); + list_init(&context_gl->fbo_destroy_list); + + list_init(&context_gl->occlusion_queries); + list_init(&context_gl->fences); + list_init(&context_gl->timestamp_queries); + list_init(&context_gl->so_statistics_queries); + list_init(&context_gl->pipeline_statistics_queries); + + for (i = 0; i < ARRAY_SIZE(context_gl->tex_unit_map); ++i) + context_gl->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + for (i = 0; i < ARRAY_SIZE(context_gl->rev_tex_unit_map); ++i) + context_gl->rev_tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + if (gl_info->limits.graphics_samplers >= WINED3D_MAX_COMBINED_SAMPLERS) { /* Initialize the texture unit mapping to a 1:1 mapping. */ unsigned int base, count; wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_PIXEL, &base, &count); - if (base + MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(ret->rev_tex_unit_map)) + if (base + WINED3D_MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(context_gl->rev_tex_unit_map)) { ERR("Unexpected texture unit base index %u.\n", base); - goto out; + goto fail; } - for (i = 0; i < min(count, MAX_FRAGMENT_SAMPLERS); ++i) + for (i = 0; i < min(count, WINED3D_MAX_FRAGMENT_SAMPLERS); ++i) { - ret->tex_unit_map[i] = base + i; - ret->rev_tex_unit_map[base + i] = i; + context_gl->tex_unit_map[i] = base + i; + context_gl->rev_tex_unit_map[base + i] = i; } wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, &base, &count); - if (base + MAX_VERTEX_SAMPLERS > ARRAY_SIZE(ret->rev_tex_unit_map)) + if (base + WINED3D_MAX_VERTEX_SAMPLERS > ARRAY_SIZE(context_gl->rev_tex_unit_map)) { ERR("Unexpected texture unit base index %u.\n", base); - goto out; + goto fail; } - for (i = 0; i < min(count, MAX_VERTEX_SAMPLERS); ++i) + for (i = 0; i < min(count, WINED3D_MAX_VERTEX_SAMPLERS); ++i) { - ret->tex_unit_map[MAX_FRAGMENT_SAMPLERS + i] = base + i; - ret->rev_tex_unit_map[base + i] = MAX_FRAGMENT_SAMPLERS + i; + context_gl->tex_unit_map[WINED3D_MAX_FRAGMENT_SAMPLERS + i] = base + i; + context_gl->rev_tex_unit_map[base + i] = WINED3D_MAX_FRAGMENT_SAMPLERS + i; } } - if (!(ret->texture_type = heap_calloc(gl_info->limits.combined_samplers, - sizeof(*ret->texture_type)))) - goto out; - - if (!(ret->hdc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE))) - { - WARN("Failed to retrieve device context, trying swapchain backup.\n"); - - if ((ret->hdc = swapchain_get_backup_dc(swapchain))) - ret->hdc_is_private = TRUE; - else - { - ERR("Failed to retrieve a device context.\n"); - goto out; - } - } + if (!(context_gl->texture_type = heap_calloc(gl_info->limits.combined_samplers, + sizeof(*context_gl->texture_type)))) + goto fail; - color_format = target->resource.format; - target_usage = target->resource.usage; + target = &context->current_rt.texture->resource; + target_bind_flags = target->bind_flags; - /* In case of ORM_BACKBUFFER, make sure to request an alpha component for - * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { - auxBuffers = TRUE; + static const enum wined3d_format_id ds_formats[] = + { + WINED3DFMT_D24_UNORM_S8_UINT, + WINED3DFMT_D32_UNORM, + WINED3DFMT_R24_UNORM_X8_TYPELESS, + WINED3DFMT_D16_UNORM, + WINED3DFMT_S1_UINT_D15_UNORM, + }; + color_format = target->format; + + /* In case of ORM_BACKBUFFER, make sure to request an alpha component for + * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ if (color_format->id == WINED3DFMT_B4G4R4X4_UNORM) - color_format = wined3d_get_format(gl_info, WINED3DFMT_B4G4R4A4_UNORM, target_usage); + color_format = wined3d_get_format(device->adapter, WINED3DFMT_B4G4R4A4_UNORM, target_bind_flags); else if (color_format->id == WINED3DFMT_B8G8R8X8_UNORM) - color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, target_usage); - } + color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); - /* DirectDraw supports 8bit paletted render targets and these are used by - * old games like StarCraft and C&C. Most modern hardware doesn't support - * 8bit natively so we perform some form of 8bit -> 32bit conversion. The - * conversion (ab)uses the alpha component for storing the palette index. - * For this reason we require a format with 8bit alpha, so request - * A8R8G8B8. */ - if (color_format->id == WINED3DFMT_P8_UINT) - color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, target_usage); + /* DirectDraw supports 8bit paletted render targets and these are used by + * old games like StarCraft and C&C. Most modern hardware doesn't support + * 8bit natively so we perform some form of 8bit -> 32bit conversion. The + * conversion (ab)uses the alpha component for storing the palette index. + * For this reason we require a format with 8bit alpha, so request + * A8R8G8B8. */ + if (color_format->id == WINED3DFMT_P8_UINT) + color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); - /* When using FBOs for off-screen rendering, we only use the drawable for - * presentation blits, and don't do any rendering to it. That means we - * don't need depth or stencil buffers, and can mostly ignore the render - * target format. This wouldn't necessarily be quite correct for 10bpc - * display modes, but we don't currently support those. - * Using the same format regardless of the color/depth/stencil targets - * makes it much less likely that different wined3d instances will set - * conflicting pixel formats. */ - if (wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER) + /* Try to find a pixel format which matches our requirements. */ + if (!swapchain_gl->s.ds_format) + { + for (i = 0; i < ARRAY_SIZE(ds_formats); ++i) + { + ds_format = wined3d_get_format(device->adapter, ds_formats[i], WINED3D_BIND_DEPTH_STENCIL); + if ((context_gl->pixel_format = context_choose_pixel_format(device, + context_gl->dc, color_format, ds_format, TRUE))) + { + swapchain_gl->s.ds_format = ds_format; + break; + } + + TRACE("Depth stencil format %s is not supported, trying next format.\n", + debug_d3dformat(ds_format->id)); + } + } + else + { + context_gl->pixel_format = context_choose_pixel_format(device, + context_gl->dc, color_format, swapchain_gl->s.ds_format, TRUE); + } + } + else { - color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, target_usage); - ds_format = wined3d_get_format(gl_info, WINED3DFMT_UNKNOWN, WINED3DUSAGE_DEPTHSTENCIL); + /* When using FBOs for off-screen rendering, we only use the drawable for + * presentation blits, and don't do any rendering to it. That means we + * don't need depth or stencil buffers, and can mostly ignore the render + * target format. This wouldn't necessarily be quite correct for 10bpc + * display modes, but we don't currently support those. + * Using the same format regardless of the color/depth/stencil targets + * makes it much less likely that different wined3d instances will set + * conflicting pixel formats. */ + color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); + ds_format = wined3d_get_format(device->adapter, WINED3DFMT_UNKNOWN, WINED3D_BIND_DEPTH_STENCIL); + context_gl->pixel_format = context_choose_pixel_format(device, + context_gl->dc, color_format, ds_format, FALSE); } - /* Try to find a pixel format which matches our requirements. */ - if (!(ret->pixel_format = context_choose_pixel_format(device, ret->hdc, color_format, ds_format, auxBuffers))) - goto out; - - ret->gl_info = gl_info; - ret->win_handle = swapchain->win_handle; + if (!context_gl->pixel_format) + goto fail; - context_enter(ret); + wined3d_context_gl_enter(context_gl); - if (!context_set_pixel_format(ret)) + if (!wined3d_context_gl_set_pixel_format(context_gl)) { - ERR("Failed to set pixel format %d on device context %p.\n", ret->pixel_format, ret->hdc); - context_release(ret); - goto out; + ERR("Failed to set pixel format %d on device context %p.\n", context_gl->pixel_format, context_gl->dc); + context_release(context); + goto fail; } - share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL; + share_ctx = device->context_count ? wined3d_context_gl(device->contexts[0])->gl_ctx : NULL; if (gl_info->p_wglCreateContextAttribsARB) { - if (!(ctx = context_create_wgl_attribs(gl_info, ret->hdc, share_ctx))) - goto out; + if (!(ctx = context_create_wgl_attribs(gl_info, context_gl->dc, share_ctx))) + { + context_release(context); + goto fail; + } } else { - if (!(ctx = wglCreateContext(ret->hdc))) + if (!(ctx = wglCreateContext(context_gl->dc))) { ERR("Failed to create a WGL context.\n"); - context_release(ret); - goto out; + context_release(context); + goto fail; } if (share_ctx && !wglShareLists(share_ctx, ctx)) { ERR("wglShareLists(%p, %p) failed, last error %#x.\n", share_ctx, ctx, GetLastError()); - context_release(ret); + context_release(context); if (!wglDeleteContext(ctx)) ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); - goto out; + goto fail; } } - if (!device_context_add(device, ret)) - { - ERR("Failed to add the newly created context to the context list\n"); - context_release(ret); - if (!wglDeleteContext(ctx)) - ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); - goto out; - } - - ret->d3d_info = d3d_info; - ret->state_table = device->StateTable; - - /* Mark all states dirty to force a proper initialization of the states on - * the first use of the context. Compute states do not need initialization. */ - for (state = 0; state <= STATE_HIGHEST; ++state) - { - if (ret->state_table[state].representative && !STATE_IS_COMPUTE(state)) - context_invalidate_state(ret, state); - } - - ret->device = device; - ret->swapchain = swapchain; - ret->current_rt.texture = target; - ret->current_rt.sub_resource_idx = 0; - ret->tid = GetCurrentThreadId(); - - ret->render_offscreen = wined3d_resource_is_offscreen(&target->resource); - ret->draw_buffers_mask = context_generate_rt_mask(GL_BACK); - ret->valid = 1; + context->render_offscreen = wined3d_resource_is_offscreen(target); + context_gl->draw_buffers_mask = context_generate_rt_mask(GL_BACK); + context_gl->valid = 1; - ret->glCtx = ctx; - ret->hdc_has_format = TRUE; - ret->needs_set = 1; + context_gl->gl_ctx = ctx; + context_gl->dc_has_format = TRUE; + context_gl->needs_set = 1; /* Set up the context defaults */ - if (!context_set_current(ret)) + if (!wined3d_context_gl_set_current(context_gl)) { ERR("Cannot activate context to set up defaults.\n"); - device_context_remove(device, ret); - context_release(ret); + context_release(context); if (!wglDeleteContext(ctx)) ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); - goto out; + goto fail; } if (context_debug_output_enabled(gl_info)) { - GL_EXTCALL(glDebugMessageCallback(wined3d_debug_callback, ret)); + GL_EXTCALL(glDebugMessageCallback(wined3d_debug_callback, context)); if (TRACE_ON(d3d_synchronous)) gl_info->gl_ops.gl.p_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE)); @@ -2147,7 +2180,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, } if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - gl_info->gl_ops.gl.p_glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_AUX_BUFFERS, &context_gl->aux_buffers); TRACE("Setting up the screen\n"); @@ -2176,15 +2209,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, 1);"); - if (gl_info->supported[ARB_VERTEX_BLEND]) - { - /* Direct3D always uses n-1 weights for n world matrices and uses - * 1 - sum for the last one this is equal to GL_WEIGHT_SUM_UNITY_ARB. - * Enabling it doesn't do anything unless GL_VERTEX_BLEND_ARB isn't - * enabled as well. */ - gl_info->gl_ops.gl.p_glEnable(GL_WEIGHT_SUM_UNITY_ARB); - checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)"); - } if (gl_info->supported[NV_TEXTURE_SHADER2]) { /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d @@ -2192,7 +2216,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, */ for (i = 1; i < gl_info->limits.textures; ++i) { - context_active_texture(ret, gl_info, i); + wined3d_context_gl_active_texture(context_gl, gl_info, i); gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + i - 1); checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ..."); @@ -2213,16 +2237,17 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, "!!ARBfp1.0\n" "MOV result.color, fragment.color.primary;\n" "END\n"; - GL_EXTCALL(glGenProgramsARB(1, &ret->dummy_arbfp_prog)); - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ret->dummy_arbfp_prog)); - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(dummy_program), dummy_program)); + GL_EXTCALL(glGenProgramsARB(1, &context_gl->dummy_arbfp_prog)); + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, context_gl->dummy_arbfp_prog)); + GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, strlen(dummy_program), dummy_program)); } if (gl_info->supported[ARB_POINT_SPRITE]) { for (i = 0; i < gl_info->limits.textures; ++i) { - context_active_texture(ret, gl_info, i); + wined3d_context_gl_active_texture(context_gl, gl_info, i); gl_info->gl_ops.gl.p_glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)"); } @@ -2256,91 +2281,85 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, } if (gl_info->supported[ARB_CLIP_CONTROL]) GL_EXTCALL(glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT)); - device->shader_backend->shader_init_context_state(ret); - ret->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) - | (1u << WINED3D_SHADER_TYPE_VERTEX) - | (1u << WINED3D_SHADER_TYPE_GEOMETRY) - | (1u << WINED3D_SHADER_TYPE_HULL) - | (1u << WINED3D_SHADER_TYPE_DOMAIN) - | (1u << WINED3D_SHADER_TYPE_COMPUTE); /* If this happens to be the first context for the device, dummy textures * are not created yet. In that case, they will be created (and bound) by * create_dummy_textures right after this context is initialized. */ - if (device->dummy_textures.tex_2d) - context_bind_dummy_textures(device, ret); + if (wined3d_device_gl(device)->dummy_textures.tex_2d) + wined3d_context_gl_bind_dummy_textures(context_gl); - TRACE("Created context %p.\n", ret); + /* Initialise all rectangles to avoid resetting unused ones later. */ + gl_info->gl_ops.gl.p_glScissor(0, 0, 0, 0); + checkGLcall("glScissor"); - return ret; + return WINED3D_OK; + +fail: + heap_free(context_gl->texture_type); + wined3d_release_dc(context_gl->window, context_gl->dc); + return E_FAIL; +} + +HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wined3d_swapchain *swapchain) +{ + TRACE("context_vk %p, swapchain %p.\n", context_vk, swapchain); + + wined3d_context_init(&context_vk->c, swapchain); -out: - if (ret->hdc) - wined3d_release_dc(swapchain->win_handle, ret->hdc); - device->shader_backend->shader_free_context_data(ret); - device->adapter->fragment_pipe->free_context_data(ret); - heap_free(ret->texture_type); - heap_free(ret->free_fences); - heap_free(ret->free_occlusion_queries); - heap_free(ret->free_timestamp_queries); - heap_free(ret); - return NULL; + return WINED3D_OK; } -void context_destroy(struct wined3d_device *device, struct wined3d_context *context) +void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) { - BOOL destroy; + struct wined3d_device *device = context_gl->c.device; - TRACE("Destroying ctx %p\n", context); + TRACE("Destroying context %p.\n", context_gl); wined3d_from_cs(device->cs); /* We delay destroying a context when it is active. The context_release() - * function invokes context_destroy() again while leaving the last level. */ - if (context->level) + * function invokes wined3d_context_gl_destroy() again while leaving the + * last level. */ + if (context_gl->level) { - TRACE("Delaying destruction of context %p.\n", context); - context->destroy_delayed = 1; + TRACE("Delaying destruction of context %p.\n", context_gl); + context_gl->c.destroy_delayed = 1; /* FIXME: Get rid of a pointer to swapchain from wined3d_context. */ - context->swapchain = NULL; + context_gl->c.swapchain = NULL; return; } - if (context->tid == GetCurrentThreadId() || !context->current) - { - context_destroy_gl_resources(context); - TlsSetValue(wined3d_context_tls_idx, NULL); - destroy = TRUE; - } - else + device_context_remove(device, &context_gl->c); + + if (context_gl->c.current && context_gl->tid != GetCurrentThreadId()) { - /* Make a copy of gl_info for context_destroy_gl_resources use, the one - in wined3d_adapter may go away in the meantime */ - struct wined3d_gl_info *gl_info = heap_alloc(sizeof(*gl_info)); - *gl_info = *context->gl_info; - context->gl_info = gl_info; - context->destroyed = 1; - destroy = FALSE; + struct wined3d_gl_info *gl_info; + + /* Make a copy of gl_info for wined3d_context_gl_cleanup() use, the + * one in wined3d_adapter may go away in the meantime. */ + gl_info = heap_alloc(sizeof(*gl_info)); + *gl_info = *context_gl->gl_info; + context_gl->gl_info = gl_info; + context_gl->c.destroyed = 1; + + return; } - device->shader_backend->shader_free_context_data(context); - device->adapter->fragment_pipe->free_context_data(context); - heap_free(context->texture_type); - device_context_remove(device, context); - if (destroy) - heap_free(context); + wined3d_context_gl_cleanup(context_gl); + TlsSetValue(context_get_tls_idx(), NULL); + heap_free(context_gl); } -const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, +const unsigned int *wined3d_context_gl_get_tex_unit_mapping(const struct wined3d_context_gl *context_gl, const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (!shader_version) { *base = 0; - *count = MAX_TEXTURES; - return context->tex_unit_map; + *count = WINED3D_MAX_TEXTURES; + return context_gl->tex_unit_map; } if (shader_version->major >= 4) @@ -2353,11 +2372,11 @@ const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, { case WINED3D_SHADER_TYPE_PIXEL: *base = 0; - *count = MAX_FRAGMENT_SAMPLERS; + *count = WINED3D_MAX_FRAGMENT_SAMPLERS; break; case WINED3D_SHADER_TYPE_VERTEX: - *base = MAX_FRAGMENT_SAMPLERS; - *count = MAX_VERTEX_SAMPLERS; + *base = WINED3D_MAX_FRAGMENT_SAMPLERS; + *count = WINED3D_MAX_VERTEX_SAMPLERS; break; default: ERR("Unhandled shader type %#x.\n", shader_version->type); @@ -2365,63 +2384,42 @@ const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, *count = 0; } - return context->tex_unit_map; -} - -/* Context activation is done by the caller. */ -static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height) -{ - const GLdouble projection[] = - { - 2.0 / width, 0.0, 0.0, 0.0, - 0.0, 2.0 / height, 0.0, 0.0, - 0.0, 0.0, 2.0, 0.0, - -1.0, -1.0, -1.0, 1.0, - }; - - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); - checkGLcall("glMatrixMode(GL_PROJECTION)"); - gl_info->gl_ops.gl.p_glLoadMatrixd(projection); - checkGLcall("glLoadMatrixd"); - } - gl_info->gl_ops.gl.p_glViewport(0, 0, width, height); - checkGLcall("glViewport"); + return context_gl->tex_unit_map; } -static void context_get_rt_size(const struct wined3d_context *context, SIZE *size) +static void wined3d_context_gl_get_rt_size(const struct wined3d_context_gl *context_gl, SIZE *size) { - const struct wined3d_texture *rt = context->current_rt.texture; + const struct wined3d_texture *rt = context_gl->c.current_rt.texture; unsigned int level; if (rt->swapchain) { RECT window_size; - GetClientRect(context->win_handle, &window_size); + GetClientRect(context_gl->window, &window_size); size->cx = window_size.right - window_size.left; size->cy = window_size.bottom - window_size.top; return; } - level = context->current_rt.sub_resource_idx % rt->level_count; + level = context_gl->c.current_rt.sub_resource_idx % rt->level_count; size->cx = wined3d_texture_get_level_width(rt, level); size->cy = wined3d_texture_get_level_height(rt, level); } -void context_enable_clip_distances(struct wined3d_context *context, unsigned int enable_mask) +void wined3d_context_gl_enable_clip_distances(struct wined3d_context_gl *context_gl, uint32_t enable_mask) { - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int clip_distance_count = gl_info->limits.user_clip_distances; - unsigned int i, disable_mask, current_mask; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int clip_distance_count, i; + uint32_t disable_mask, current_mask; + clip_distance_count = gl_info->limits.user_clip_distances; disable_mask = ~enable_mask; enable_mask &= (1u << clip_distance_count) - 1; disable_mask &= (1u << clip_distance_count) - 1; - current_mask = context->clip_distance_mask; - context->clip_distance_mask = enable_mask; + current_mask = context_gl->c.clip_distance_mask; + context_gl->c.clip_distance_mask = enable_mask; enable_mask &= ~current_mask; while (enable_mask) @@ -2438,223 +2436,23 @@ void context_enable_clip_distances(struct wined3d_context *context, unsigned int checkGLcall("toggle clip distances"); } -/***************************************************************************** - * SetupForBlit - * - * Sets up a context for DirectDraw blitting. - * All texture units are disabled, texture unit 0 is set as current unit - * fog, lighting, blending, alpha test, z test, scissor test, culling disabled - * color writing enabled for all channels - * register combiners disabled, shaders disabled - * world matrix is set to identity, texture matrix 0 too - * projection matrix is setup for drawing screen coordinates - * - * Params: - * This: Device to activate the context for - * context: Context to setup - * - *****************************************************************************/ -/* Context activation is done by the caller. */ -static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context) +static inline BOOL is_rt_mask_onscreen(DWORD rt_mask) { - const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD sampler; - SIZE rt_size; - int i; + return rt_mask & (1u << 31); +} - TRACE("Setting up context %p for blitting\n", context); +static inline GLenum draw_buffer_from_rt_mask(DWORD rt_mask) +{ + return rt_mask & ~(1u << 31); +} - context_get_rt_size(context, &rt_size); +/* Context activation is done by the caller. */ +static void wined3d_context_gl_apply_draw_buffers(struct wined3d_context_gl *context_gl, uint32_t rt_mask) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLenum draw_buffers[MAX_RENDER_TARGET_VIEWS]; - if (context->last_was_blit) - { - if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy) - { - set_blit_dimension(gl_info, rt_size.cx, rt_size.cy); - context->blit_w = rt_size.cx; - context->blit_h = rt_size.cy; - /* No need to dirtify here, the states are still dirtified because - * they weren't applied since the last SetupForBlit() call. */ - } - TRACE("Context is already set up for blitting, nothing to do\n"); - return; - } - context->last_was_blit = TRUE; - - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - /* Disable all textures. The caller can then bind a texture it wants to blit - * from - * - * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed - * function texture unit. No need to care for higher samplers - */ - for (i = gl_info->limits.textures - 1; i > 0 ; --i) - { - sampler = context->rev_tex_unit_map[i]; - context_active_texture(context, gl_info, i); - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB"); - } - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable GL_TEXTURE_3D"); - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB"); - } - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable GL_TEXTURE_2D"); - - gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);"); - - if (sampler != WINED3D_UNMAPPED_STAGE) - { - if (sampler < MAX_TEXTURES) - context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); - context_invalidate_state(context, STATE_SAMPLER(sampler)); - } - } - - context_active_texture(context, gl_info, 0); - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB"); - } - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable GL_TEXTURE_3D"); - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB"); - } - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable GL_TEXTURE_2D"); - - gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE); - checkGLcall("glMatrixMode(GL_TEXTURE)"); - gl_info->gl_ops.gl.p_glLoadIdentity(); - checkGLcall("glLoadIdentity()"); - - if (gl_info->supported[EXT_TEXTURE_LOD_BIAS]) - { - gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, - GL_TEXTURE_LOD_BIAS_EXT, 0.0f); - checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ..."); - } - - /* Setup transforms */ - gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode(GL_MODELVIEW)"); - gl_info->gl_ops.gl.p_glLoadIdentity(); - checkGLcall("glLoadIdentity()"); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); - - /* Other misc states */ - gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); - checkGLcall("glDisable(GL_ALPHA_TEST)"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING); - checkGLcall("glDisable GL_LIGHTING"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING)); - glDisableWINE(GL_FOG); - checkGLcall("glDisable GL_FOG"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE)); - } - - if (gl_info->supported[ARB_SAMPLER_OBJECTS]) - GL_EXTCALL(glBindSampler(0, 0)); - context_active_texture(context, gl_info, 0); - - sampler = context->rev_tex_unit_map[0]; - if (sampler != WINED3D_UNMAPPED_STAGE) - { - if (sampler < MAX_TEXTURES) - { - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler)); - context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); - } - context_invalidate_state(context, STATE_SAMPLER(sampler)); - } - - /* Other misc states */ - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); - checkGLcall("glDisable GL_DEPTH_TEST"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); - checkGLcall("glDisable GL_CULL_FACE"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE)); - gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); - checkGLcall("glDisable GL_STENCIL_TEST"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE)); - gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); - checkGLcall("glDisable GL_SCISSOR_TEST"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); - if (gl_info->supported[ARB_POINT_SPRITE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB); - checkGLcall("glDisable GL_POINT_SPRITE_ARB"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE)); - } - gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE); - checkGLcall("glColorMask"); - for (i = 0; i < MAX_RENDER_TARGETS; ++i) - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); - if (gl_info->supported[EXT_SECONDARY_COLOR]) - { - gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); - checkGLcall("glDisable(GL_COLOR_SUM_EXT)"); - } - - context->last_was_rhw = TRUE; - context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ - - context_enable_clip_distances(context, 0); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING)); - - /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ - if (gl_info->supported[ARB_CLIP_CONTROL]) - GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE)); - - set_blit_dimension(gl_info, rt_size.cx, rt_size.cy); - - /* Disable shaders */ - device->shader_backend->shader_disable(device->shader_priv, context); - - context->blit_w = rt_size.cx; - context->blit_h = rt_size.cy; - context_invalidate_state(context, STATE_VIEWPORT); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); -} - -static inline BOOL is_rt_mask_onscreen(DWORD rt_mask) -{ - return rt_mask & (1u << 31); -} - -static inline GLenum draw_buffer_from_rt_mask(DWORD rt_mask) -{ - return rt_mask & ~(1u << 31); -} - -/* Context activation is done by the caller. */ -static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt_mask) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum draw_buffers[MAX_RENDER_TARGET_VIEWS]; - - if (!rt_mask) + if (!rt_mask) { gl_info->gl_ops.gl.p_glDrawBuffer(GL_NONE); } @@ -2698,12 +2496,14 @@ static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt } /* Context activation is done by the caller. */ -void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) +void wined3d_context_gl_set_draw_buffer(struct wined3d_context_gl *context_gl, GLenum buffer) { - const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD *current_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; - DWORD new_mask = context_generate_rt_mask(buffer); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct fbo_entry *current_fbo = context_gl->current_fbo; + uint32_t new_mask = context_generate_rt_mask(buffer); + uint32_t *current_mask; + current_mask = current_fbo ? ¤t_fbo->rt_mask : &context_gl->draw_buffers_mask; if (new_mask == *current_mask) return; @@ -2714,39 +2514,38 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) } /* Context activation is done by the caller. */ -void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit) +void wined3d_context_gl_active_texture(struct wined3d_context_gl *context_gl, + const struct wined3d_gl_info *gl_info, unsigned int unit) { GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + unit)); checkGLcall("glActiveTexture"); - context->active_texture = unit; + context_gl->active_texture = unit; } -void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) +void wined3d_context_gl_bind_bo(struct wined3d_context_gl *context_gl, GLenum binding, GLuint name) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (binding == GL_ELEMENT_ARRAY_BUFFER) - context_invalidate_state(context, STATE_INDEXBUFFER); + context_invalidate_state(&context_gl->c, STATE_INDEXBUFFER); GL_EXTCALL(glBindBuffer(binding, name)); } -void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) +void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl, GLenum target, GLuint name) { - const struct wined3d_dummy_textures *textures = &context->device->dummy_textures; - const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD unit = context->active_texture; - DWORD old_texture_type = context->texture_type[unit]; + const struct wined3d_dummy_textures *textures = &wined3d_device_gl(context_gl->c.device)->dummy_textures; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLenum old_texture_type; + unsigned int unit; if (name) - { gl_info->gl_ops.gl.p_glBindTexture(target, name); - } else - { target = GL_NONE; - } + unit = context_gl->active_texture; + old_texture_type = context_gl->texture_type[unit]; if (old_texture_type != target) { switch (old_texture_type) @@ -2756,11 +2555,9 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint break; case GL_TEXTURE_1D: gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d); - checkGLcall("glBindTexture"); break; case GL_TEXTURE_1D_ARRAY: gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array); - checkGLcall("glBindTexture"); break; case GL_TEXTURE_2D: gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d); @@ -2793,13 +2590,13 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint ERR("Unexpected texture target %#x.\n", old_texture_type); } - context->texture_type[unit] = target; + context_gl->texture_type[unit] = target; } checkGLcall("bind texture"); } -void *context_map_bo_address(struct wined3d_context *context, +void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *data, size_t size, GLenum binding, DWORD flags) { const struct wined3d_gl_info *gl_info; @@ -2808,13 +2605,13 @@ void *context_map_bo_address(struct wined3d_context *context, if (!data->buffer_object) return data->addr; - gl_info = context->gl_info; - context_bind_bo(context, binding, data->buffer_object); + gl_info = context_gl->gl_info; + wined3d_context_gl_bind_bo(context_gl, binding, data->buffer_object); if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { - GLbitfield map_flags = wined3d_resource_gl_map_flags(flags) & ~GL_MAP_FLUSH_EXPLICIT_BIT; - memory = GL_EXTCALL(glMapBufferRange(binding, (INT_PTR)data->addr, size, map_flags)); + memory = GL_EXTCALL(glMapBufferRange(binding, (INT_PTR)data->addr, + size, wined3d_resource_gl_map_flags(flags))); } else { @@ -2822,35 +2619,46 @@ void *context_map_bo_address(struct wined3d_context *context, memory += (INT_PTR)data->addr; } - context_bind_bo(context, binding, 0); + wined3d_context_gl_bind_bo(context_gl, binding, 0); checkGLcall("Map buffer object"); return memory; } -void context_unmap_bo_address(struct wined3d_context *context, - const struct wined3d_bo_address *data, GLenum binding) +void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *data, + GLenum binding, unsigned int range_count, const struct wined3d_map_range *ranges) { const struct wined3d_gl_info *gl_info; + unsigned int i; if (!data->buffer_object) return; - gl_info = context->gl_info; - context_bind_bo(context, binding, data->buffer_object); + gl_info = context_gl->gl_info; + wined3d_context_gl_bind_bo(context_gl, binding, data->buffer_object); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + for (i = 0; i < range_count; ++i) + { + GL_EXTCALL(glFlushMappedBufferRange(binding, (UINT_PTR)data->addr + ranges[i].offset, ranges[i].size)); + } + } + GL_EXTCALL(glUnmapBuffer(binding)); - context_bind_bo(context, binding, 0); + wined3d_context_gl_bind_bo(context_gl, binding, 0); checkGLcall("Unmap buffer object"); } -void context_copy_bo_address(struct wined3d_context *context, +void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *dst, GLenum dst_binding, const struct wined3d_bo_address *src, GLenum src_binding, size_t size) { const struct wined3d_gl_info *gl_info; + struct wined3d_map_range range; BYTE *dst_ptr, *src_ptr; - gl_info = context->gl_info; + gl_info = context_gl->gl_info; if (dst->buffer_object && src->buffer_object) { @@ -2864,24 +2672,26 @@ void context_copy_bo_address(struct wined3d_context *context, } else { - src_ptr = context_map_bo_address(context, src, size, src_binding, WINED3D_MAP_READ); - dst_ptr = context_map_bo_address(context, dst, size, dst_binding, WINED3D_MAP_WRITE); + src_ptr = wined3d_context_gl_map_bo_address(context_gl, src, size, src_binding, WINED3D_MAP_READ); + dst_ptr = wined3d_context_gl_map_bo_address(context_gl, dst, size, dst_binding, WINED3D_MAP_WRITE); memcpy(dst_ptr, src_ptr, size); - context_unmap_bo_address(context, dst, dst_binding); - context_unmap_bo_address(context, src, src_binding); + range.offset = 0; + range.size = size; + wined3d_context_gl_unmap_bo_address(context_gl, dst, dst_binding, 1, &range); + wined3d_context_gl_unmap_bo_address(context_gl, src, src_binding, 0, NULL); } } else if (!dst->buffer_object && src->buffer_object) { - context_bind_bo(context, src_binding, src->buffer_object); + wined3d_context_gl_bind_bo(context_gl, src_binding, src->buffer_object); GL_EXTCALL(glGetBufferSubData(src_binding, (GLintptr)src->addr, size, dst->addr)); checkGLcall("buffer download"); } else if (dst->buffer_object && !src->buffer_object) { - context_bind_bo(context, dst_binding, dst->buffer_object); + wined3d_context_gl_bind_bo(context_gl, dst_binding, dst->buffer_object); GL_EXTCALL(glBufferSubData(dst_binding, (GLintptr)dst->addr, size, src->addr)); checkGLcall("buffer upload"); } @@ -2891,67 +2701,26 @@ void context_copy_bo_address(struct wined3d_context *context, } } -static void context_set_render_offscreen(struct wined3d_context *context, BOOL offscreen) +static void wined3d_context_gl_set_render_offscreen(struct wined3d_context_gl *context_gl, BOOL offscreen) { - if (context->render_offscreen == offscreen) + if (context_gl->c.render_offscreen == offscreen) return; - context_invalidate_state(context, STATE_VIEWPORT); - context_invalidate_state(context, STATE_SCISSORRECT); - if (!context->gl_info->supported[ARB_CLIP_CONTROL]) + context_invalidate_state(&context_gl->c, STATE_VIEWPORT); + context_invalidate_state(&context_gl->c, STATE_SCISSORRECT); + if (!context_gl->gl_info->supported[ARB_CLIP_CONTROL]) { - context_invalidate_state(context, STATE_FRONTFACE); - context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); + context_invalidate_state(&context_gl->c, STATE_RASTERIZER); + context_invalidate_state(&context_gl->c, STATE_POINTSPRITECOORDORIGIN); + context_invalidate_state(&context_gl->c, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); } - context_invalidate_state(context, STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN)); - if (context->gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) - context_invalidate_state(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); - context->render_offscreen = offscreen; -} - -static BOOL match_depth_stencil_format(const struct wined3d_format *existing, - const struct wined3d_format *required) -{ - if (existing == required) - return TRUE; - if ((existing->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) - != (required->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)) - return FALSE; - if (existing->depth_size < required->depth_size) - return FALSE; - /* If stencil bits are used the exact amount is required - otherwise - * wrapping won't work correctly. */ - if (required->stencil_size && required->stencil_size != existing->stencil_size) - return FALSE; - return TRUE; -} - -/* Context activation is done by the caller. */ -static void context_validate_onscreen_formats(struct wined3d_context *context, - const struct wined3d_rendertarget_view *depth_stencil) -{ - /* Onscreen surfaces are always in a swapchain */ - struct wined3d_swapchain *swapchain = context->current_rt.texture->swapchain; - - if (context->render_offscreen || !depth_stencil) return; - if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->format)) return; - - /* TODO: If the requested format would satisfy the needs of the existing one(reverse match), - * or no onscreen depth buffer was created, the OpenGL drawable could be changed to the new - * format. */ - WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); - - /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ - if (!(wined3d_texture_load_location(context->current_rt.texture, context->current_rt.sub_resource_idx, - context, WINED3D_LOCATION_TEXTURE_RGB))) - ERR("Failed to load location.\n"); - swapchain->render_to_fbo = TRUE; - swapchain_update_draw_bindings(swapchain); - context_set_render_offscreen(context, TRUE); + context_invalidate_state(&context_gl->c, STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN)); + if (context_gl->gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + context_invalidate_state(&context_gl->c, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); + context_gl->c.render_offscreen = offscreen; } -GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) +GLenum wined3d_context_gl_get_offscreen_gl_buffer(const struct wined3d_context_gl *context_gl) { switch (wined3d_settings.offscreen_rendering_mode) { @@ -2959,7 +2728,7 @@ GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) return GL_COLOR_ATTACHMENT0; case ORM_BACKBUFFER: - return context->aux_buffers > 0 ? GL_AUX0 : GL_BACK; + return context_gl->aux_buffers > 0 ? GL_AUX0 : GL_BACK; default: FIXME("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode); @@ -2967,22 +2736,31 @@ GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) } } -static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_texture *rt) +static uint32_t wined3d_context_gl_generate_rt_mask_no_fbo(const struct wined3d_context_gl *context_gl, + struct wined3d_resource *rt) { - if (!rt || rt->resource.format->id == WINED3DFMT_NULL) + if (!rt || rt->format->id == WINED3DFMT_NULL) return 0; - else if (rt->swapchain) - return context_generate_rt_mask_from_resource(&rt->resource); + else if (rt->type != WINED3D_RTYPE_BUFFER && texture_from_resource(rt)->swapchain) + return context_generate_rt_mask_from_resource(rt); else - return context_generate_rt_mask(context_get_offscreen_gl_buffer(context)); + return context_generate_rt_mask(wined3d_context_gl_get_offscreen_gl_buffer(context_gl)); } /* Context activation is done by the caller. */ -void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) +void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, const struct wined3d_device *device) { - struct wined3d_texture *rt = context->current_rt.texture; - struct wined3d_surface *surface; - DWORD rt_mask, *cur_mask; + struct wined3d_context *context = &context_gl->c; + const struct wined3d_gl_info *gl_info; + uint32_t rt_mask, *cur_mask; + struct wined3d_texture *rt; + unsigned int i, sampler; + SIZE rt_size; + + TRACE("Setting up context %p for blitting.\n", context); + + gl_info = context_gl->gl_info; + rt = context->current_rt.texture; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { @@ -2990,8 +2768,8 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine { wined3d_texture_load(rt, context, FALSE); - surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface; - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding); + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_FRAMEBUFFER, &rt->resource, + context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding); if (rt->resource.format->id != WINED3DFMT_NULL) rt_mask = 1; else @@ -2999,31 +2777,217 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine } else { - context->current_fbo = NULL; - context_bind_fbo(context, GL_FRAMEBUFFER, 0); + context_gl->current_fbo = NULL; + wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, 0); rt_mask = context_generate_rt_mask_from_resource(&rt->resource); } } else { - rt_mask = context_generate_rt_mask_no_fbo(context, rt); + rt_mask = wined3d_context_gl_generate_rt_mask_no_fbo(context_gl, &rt->resource); } - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; + cur_mask = context_gl->current_fbo ? &context_gl->current_fbo->rt_mask : &context_gl->draw_buffers_mask; if (rt_mask != *cur_mask) { - context_apply_draw_buffers(context, rt_mask); + wined3d_context_gl_apply_draw_buffers(context_gl, rt_mask); *cur_mask = rt_mask; } if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + wined3d_context_gl_check_fbo_status(context_gl, GL_FRAMEBUFFER); + context_invalidate_state(context, STATE_FRAMEBUFFER); + + wined3d_context_gl_get_rt_size(context_gl, &rt_size); + + if (context->last_was_blit) { - context_check_fbo_status(context, GL_FRAMEBUFFER); + if (context_gl->blit_size.cx != rt_size.cx || context_gl->blit_size.cy != rt_size.cy) + { + gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy); + context->viewport_count = WINED3D_MAX_VIEWPORTS; + context_gl->blit_size = rt_size; + /* No need to dirtify here, the states are still dirtified because + * they weren't applied since the last context_apply_blit_state() + * call. */ + } + checkGLcall("blit state application"); + TRACE("Context is already set up for blitting, nothing to do.\n"); + return; } + context->last_was_blit = TRUE; - SetupForBlit(device, context); - context_invalidate_state(context, STATE_FRAMEBUFFER); + if (gl_info->supported[ARB_SAMPLER_OBJECTS]) + GL_EXTCALL(glBindSampler(0, 0)); + wined3d_context_gl_active_texture(context_gl, gl_info, 0); + + sampler = context_gl->rev_tex_unit_map[0]; + if (sampler != WINED3D_UNMAPPED_STAGE) + { + if (sampler < WINED3D_MAX_TEXTURES) + { + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler)); + context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); + } + context_invalidate_state(context, STATE_SAMPLER(sampler)); + } + context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE)); + } + gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_BLEND); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE)); + gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE)); + gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); + if (gl_info->supported[ARB_POINT_SPRITE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE)); + } + if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) + { + gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + } + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + for (i = 0; i < MAX_RENDER_TARGETS; ++i) + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); + + context->last_was_rhw = TRUE; + context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ + + wined3d_context_gl_enable_clip_distances(context_gl, 0); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING)); + + /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ + if (gl_info->supported[ARB_CLIP_CONTROL]) + GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE)); + gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy); + context->viewport_count = WINED3D_MAX_VIEWPORTS; + context_invalidate_state(context, STATE_VIEWPORT); + + device->shader_backend->shader_disable(device->shader_priv, context); + + context_gl->blit_size = rt_size; + + checkGLcall("blit state application"); +} + +static void wined3d_context_gl_apply_blit_projection(const struct wined3d_context_gl *context_gl, + unsigned int w, unsigned int h) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const GLdouble projection[] = + { + 2.0 / w, 0.0, 0.0, 0.0, + 0.0, 2.0 / h, 0.0, 0.0, + 0.0, 0.0, 2.0, 0.0, + -1.0, -1.0, -1.0, 1.0, + }; + + gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); + gl_info->gl_ops.gl.p_glLoadMatrixd(projection); +} + +/* Setup OpenGL states for fixed-function blitting. */ +/* Context activation is done by the caller. */ +void wined3d_context_gl_apply_ffp_blit_state(struct wined3d_context_gl *context_gl, + const struct wined3d_device *device) +{ + struct wined3d_context *context = &context_gl->c; + const struct wined3d_gl_info *gl_info; + unsigned int i, sampler; + + gl_info = context_gl->gl_info; + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + ERR("Applying fixed-function state without legacy context support.\n"); + + if (context->last_was_ffp_blit) + { + SIZE rt_size; + + wined3d_context_gl_get_rt_size(context_gl, &rt_size); + if (context_gl->blit_size.cx != rt_size.cx || context_gl->blit_size.cy != rt_size.cy) + wined3d_context_gl_apply_blit_projection(context_gl, rt_size.cx, rt_size.cy); + wined3d_context_gl_apply_blit_state(context_gl, device); + + checkGLcall("ffp blit state application"); + return; + } + context->last_was_ffp_blit = TRUE; + + wined3d_context_gl_apply_blit_state(context_gl, device); + + /* Disable all textures. The caller can then bind a texture it wants to blit + * from. */ + for (i = gl_info->limits.textures - 1; i > 0 ; --i) + { + wined3d_context_gl_active_texture(context_gl, gl_info, i); + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + + gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + sampler = context_gl->rev_tex_unit_map[i]; + if (sampler != WINED3D_UNMAPPED_STAGE) + { + if (sampler < WINED3D_MAX_TEXTURES) + context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)); + context_invalidate_state(context, STATE_SAMPLER(sampler)); + } + } + + wined3d_context_gl_active_texture(context_gl, gl_info, 0); + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + + gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + if (gl_info->supported[EXT_TEXTURE_LOD_BIAS]) + gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.0f); + + gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE); + gl_info->gl_ops.gl.p_glLoadIdentity(); + + /* Setup transforms. */ + gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); + gl_info->gl_ops.gl.p_glLoadIdentity(); + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); + wined3d_context_gl_apply_blit_projection(context_gl, context_gl->blit_size.cx, context_gl->blit_size.cy); + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); + + /* Other misc states. */ + gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING)); + gl_info->p_glDisableWINE(GL_FOG); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE)); + + if (gl_info->supported[EXT_SECONDARY_COLOR]) + { + gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); + } + checkGLcall("ffp blit state application"); } static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts, @@ -3044,16 +3008,16 @@ static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_re } /* Context activation is done by the caller. */ -BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state, - UINT rt_count, const struct wined3d_fb_state *fb) +BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, + const struct wined3d_state *state, unsigned int rt_count, const struct wined3d_fb_state *fb) { struct wined3d_rendertarget_view * const *rts = fb->render_targets; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_rendertarget_view *dsv = fb->depth_stencil; - const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD rt_mask = 0, *cur_mask; + uint32_t rt_mask = 0, *cur_mask; unsigned int i; - if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb + if (isStateDirty(&context_gl->c, STATE_FRAMEBUFFER) || fb != state->fb || rt_count != gl_info->limits.buffers) { if (!have_framebuffer_attachment(rt_count, rts, dsv)) @@ -3064,31 +3028,40 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - context_validate_onscreen_formats(context, dsv); + struct wined3d_rendertarget_info ds_info = {{0}}; if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource)) { - memset(context->blit_targets, 0, sizeof(context->blit_targets)); + memset(context_gl->blit_targets, 0, sizeof(context_gl->blit_targets)); for (i = 0; i < rt_count; ++i) { if (rts[i]) { - context->blit_targets[i].gl_view = rts[i]->gl_view; - context->blit_targets[i].resource = rts[i]->resource; - context->blit_targets[i].sub_resource_idx = rts[i]->sub_resource_idx; - context->blit_targets[i].layer_count = rts[i]->layer_count; + struct wined3d_rendertarget_view_gl *rtv_gl = wined3d_rendertarget_view_gl(rts[i]); + context_gl->blit_targets[i].gl_view = rtv_gl->gl_view; + context_gl->blit_targets[i].resource = rtv_gl->v.resource; + context_gl->blit_targets[i].sub_resource_idx = rtv_gl->v.sub_resource_idx; + context_gl->blit_targets[i].layer_count = rtv_gl->v.layer_count; } if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL) rt_mask |= (1u << i); } - context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, - wined3d_rendertarget_view_get_surface(dsv), - rt_count ? rts[0]->resource->draw_binding : 0, - dsv ? dsv->resource->draw_binding : 0); - } - else + + if (dsv) + { + struct wined3d_rendertarget_view_gl *dsv_gl = wined3d_rendertarget_view_gl(dsv); + ds_info.gl_view = dsv_gl->gl_view; + ds_info.resource = dsv_gl->v.resource; + ds_info.sub_resource_idx = dsv_gl->v.sub_resource_idx; + ds_info.layer_count = dsv_gl->v.layer_count; + } + + wined3d_context_gl_apply_fbo_state(context_gl, GL_FRAMEBUFFER, context_gl->blit_targets, &ds_info, + rt_count ? rts[0]->resource->draw_binding : 0, dsv ? dsv->resource->draw_binding : 0); + } + else { - context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, + wined3d_context_gl_apply_fbo_state(context_gl, GL_FRAMEBUFFER, NULL, &ds_info, WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE); rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource); } @@ -3096,12 +3069,11 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win /* If the framebuffer is not the device's fb the device's fb has to be reapplied * next draw. Otherwise we could mark the framebuffer state clean here, once the * state management allows this */ - context_invalidate_state(context, STATE_FRAMEBUFFER); + context_invalidate_state(&context_gl->c, STATE_FRAMEBUFFER); } else { - rt_mask = context_generate_rt_mask_no_fbo(context, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL); + rt_mask = wined3d_context_gl_generate_rt_mask_no_fbo(context_gl, rt_count ? rts[0]->resource : NULL); } } else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO @@ -3115,25 +3087,23 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win } else { - rt_mask = context_generate_rt_mask_no_fbo(context, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL); + rt_mask = wined3d_context_gl_generate_rt_mask_no_fbo(context_gl, rt_count ? rts[0]->resource : NULL); } - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; + cur_mask = context_gl->current_fbo ? &context_gl->current_fbo->rt_mask : &context_gl->draw_buffers_mask; if (rt_mask != *cur_mask) { - context_apply_draw_buffers(context, rt_mask); + wined3d_context_gl_apply_draw_buffers(context_gl, rt_mask); *cur_mask = rt_mask; - context_invalidate_state(context, STATE_FRAMEBUFFER); + context_invalidate_state(&context_gl->c, STATE_FRAMEBUFFER); } if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - context_check_fbo_status(context, GL_FRAMEBUFFER); - } + wined3d_context_gl_check_fbo_status(context_gl, GL_FRAMEBUFFER); - context->last_was_blit = FALSE; + context_gl->c.last_was_blit = FALSE; + context_gl->c.last_was_ffp_blit = FALSE; /* Blending and clearing should be orthogonal, but tests on the nvidia * driver show that disabling blending when clearing improves the clearing @@ -3142,31 +3112,32 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST); if (rt_count && gl_info->supported[ARB_FRAMEBUFFER_SRGB]) { - if (needs_srgb_write(context, state, fb)) + if (needs_srgb_write(&context_gl->c, state, fb)) gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); else gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + context_invalidate_state(&context_gl->c, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); } checkGLcall("setting up state for clear"); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); - context_invalidate_state(context, STATE_SCISSORRECT); + context_invalidate_state(&context_gl->c, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); + context_invalidate_state(&context_gl->c, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); + context_invalidate_state(&context_gl->c, STATE_SCISSORRECT); return TRUE; } -static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) +static uint32_t find_draw_buffers_mask(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { struct wined3d_rendertarget_view * const *rts = state->fb->render_targets; struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - DWORD rt_mask, mask; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int rt_mask, mask; unsigned int i; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])->container); - else if (!context->render_offscreen) + return wined3d_context_gl_generate_rt_mask_no_fbo(context_gl, rts[0]->resource); + else if (!context_gl->c.render_offscreen) return context_generate_rt_mask_from_resource(rts[0]->resource); /* If we attach more buffers than supported in dual blend mode, the NVIDIA @@ -3175,10 +3146,14 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const * DX11 does not treat this configuration as invalid, so disable the unused ones. */ rt_mask = ps ? ps->reg_maps.rt_mask : 1; - if (wined3d_dualblend_enabled(state, context->gl_info)) - rt_mask &= context->d3d_info->valid_dual_rt_mask; + + if (wined3d_dualblend_enabled(state, gl_info) && ps) + { + const struct wined3d_d3d_info *d3d_info = &ps->device->adapter->d3d_info; + rt_mask &= d3d_info->valid_dual_rt_mask; + } else - rt_mask &= context->d3d_info->valid_rt_mask; + rt_mask &= (1u << gl_info->limits.buffers) - 1; mask = rt_mask; i = 0; @@ -3195,64 +3170,78 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const /* Context activation is done by the caller. */ void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD rt_mask = find_draw_buffers_mask(context, state); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + uint32_t rt_mask = find_draw_buffers_mask(context_gl, state); const struct wined3d_fb_state *fb = state->fb; DWORD color_location = 0; DWORD *cur_mask; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { + struct wined3d_rendertarget_info ds_info = {{0}}; + if (!context->render_offscreen) { - context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, + wined3d_context_gl_apply_fbo_state(context_gl, GL_FRAMEBUFFER, NULL, &ds_info, WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE); } else { + const struct wined3d_rendertarget_view_gl *view_gl; unsigned int i; - memset(context->blit_targets, 0, sizeof(context->blit_targets)); - for (i = 0; i < context->gl_info->limits.buffers; ++i) + memset(context_gl->blit_targets, 0, sizeof(context_gl->blit_targets)); + for (i = 0; i < context_gl->gl_info->limits.buffers; ++i) { if (!fb->render_targets[i]) continue; - context->blit_targets[i].gl_view = fb->render_targets[i]->gl_view; - context->blit_targets[i].resource = fb->render_targets[i]->resource; - context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx; - context->blit_targets[i].layer_count = fb->render_targets[i]->layer_count; + view_gl = wined3d_rendertarget_view_gl(fb->render_targets[i]); + context_gl->blit_targets[i].gl_view = view_gl->gl_view; + context_gl->blit_targets[i].resource = view_gl->v.resource; + context_gl->blit_targets[i].sub_resource_idx = view_gl->v.sub_resource_idx; + context_gl->blit_targets[i].layer_count = view_gl->v.layer_count; if (!color_location) - color_location = fb->render_targets[i]->resource->draw_binding; + color_location = view_gl->v.resource->draw_binding; + } + + if (fb->depth_stencil) + { + view_gl = wined3d_rendertarget_view_gl(fb->depth_stencil); + ds_info.gl_view = view_gl->gl_view; + ds_info.resource = view_gl->v.resource; + ds_info.sub_resource_idx = view_gl->v.sub_resource_idx; + ds_info.layer_count = view_gl->v.layer_count; } - context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, - wined3d_rendertarget_view_get_surface(fb->depth_stencil), + + wined3d_context_gl_apply_fbo_state(context_gl, GL_FRAMEBUFFER, context_gl->blit_targets, &ds_info, color_location, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0); } } - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; + cur_mask = context_gl->current_fbo ? &context_gl->current_fbo->rt_mask : &context_gl->draw_buffers_mask; if (rt_mask != *cur_mask) { - context_apply_draw_buffers(context, rt_mask); + wined3d_context_gl_apply_draw_buffers(context_gl, rt_mask); *cur_mask = rt_mask; } context->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR; } -static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) +static void wined3d_context_gl_map_stage(struct wined3d_context_gl *context_gl, unsigned int stage, unsigned int unit) { - DWORD i = context->rev_tex_unit_map[unit]; - DWORD j = context->tex_unit_map[stage]; + unsigned int i = context_gl->rev_tex_unit_map[unit]; + unsigned int j = context_gl->tex_unit_map[stage]; TRACE("Mapping stage %u to unit %u.\n", stage, unit); - context->tex_unit_map[stage] = unit; + context_gl->tex_unit_map[stage] = unit; if (i != WINED3D_UNMAPPED_STAGE && i != stage) - context->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + context_gl->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; - context->rev_tex_unit_map[unit] = stage; + context_gl->rev_tex_unit_map[unit] = stage; if (j != WINED3D_UNMAPPED_STAGE && j != unit) - context->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE; + context_gl->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE; } static void context_invalidate_texture_stage(struct wined3d_context *context, DWORD stage) @@ -3269,7 +3258,7 @@ static void context_update_fixed_function_usage_map(struct wined3d_context *cont UINT i, start, end; context->fixed_function_usage_map = 0; - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP]; enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP]; @@ -3295,7 +3284,7 @@ static void context_update_fixed_function_usage_map(struct wined3d_context *cont context->fixed_function_usage_map |= (1u << i); if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE) - && i < MAX_TEXTURES - 1) + && i < WINED3D_MAX_TEXTURES - 1) context->fixed_function_usage_map |= (1u << (i + 1)); } @@ -3317,28 +3306,28 @@ static void context_update_fixed_function_usage_map(struct wined3d_context *cont } } -static void context_map_fixed_function_samplers(struct wined3d_context *context, +static void wined3d_context_gl_map_fixed_function_samplers(struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { - const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; unsigned int i, tex; WORD ffu_map; - ffu_map = context->fixed_function_usage_map; + ffu_map = context_gl->c.fixed_function_usage_map; if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages - || context->lowest_disabled_stage <= d3d_info->limits.ffp_textures) + || context_gl->c.lowest_disabled_stage <= d3d_info->limits.ffp_textures) { for (i = 0; ffu_map; ffu_map >>= 1, ++i) { if (!(ffu_map & 1)) continue; - if (context->tex_unit_map[i] != i) + if (context_gl->tex_unit_map[i] != i) { - context_map_stage(context, i, i); - context_invalidate_state(context, STATE_SAMPLER(i)); - context_invalidate_texture_stage(context, i); + wined3d_context_gl_map_stage(context_gl, i, i); + context_invalidate_state(&context_gl->c, STATE_SAMPLER(i)); + context_invalidate_texture_stage(&context_gl->c, i); } } return; @@ -3351,53 +3340,54 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context, if (!(ffu_map & 1)) continue; - if (context->tex_unit_map[i] != tex) + if (context_gl->tex_unit_map[i] != tex) { - context_map_stage(context, i, tex); - context_invalidate_state(context, STATE_SAMPLER(i)); - context_invalidate_texture_stage(context, i); + wined3d_context_gl_map_stage(context_gl, i, tex); + context_invalidate_state(&context_gl->c, STATE_SAMPLER(i)); + context_invalidate_texture_stage(&context_gl->c, i); } ++tex; } } -static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state) +static void wined3d_context_gl_map_psamplers(struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { - const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; const struct wined3d_shader_resource_info *resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info; unsigned int i; - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) { - if (resource_info[i].type && context->tex_unit_map[i] != i) + if (resource_info[i].type && context_gl->tex_unit_map[i] != i) { - context_map_stage(context, i, i); - context_invalidate_state(context, STATE_SAMPLER(i)); + wined3d_context_gl_map_stage(context_gl, i, i); + context_invalidate_state(&context_gl->c, STATE_SAMPLER(i)); if (i < d3d_info->limits.ffp_blend_stages) - context_invalidate_texture_stage(context, i); + context_invalidate_texture_stage(&context_gl->c, i); } } } -static BOOL context_unit_free_for_vs(const struct wined3d_context *context, - const struct wined3d_shader_resource_info *ps_resource_info, DWORD unit) +static BOOL wined3d_context_gl_unit_free_for_vs(const struct wined3d_context_gl *context_gl, + const struct wined3d_shader_resource_info *ps_resource_info, unsigned int unit) { - DWORD current_mapping = context->rev_tex_unit_map[unit]; + unsigned int current_mapping = context_gl->rev_tex_unit_map[unit]; /* Not currently used */ if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE; - if (current_mapping < MAX_FRAGMENT_SAMPLERS) + if (current_mapping < WINED3D_MAX_FRAGMENT_SAMPLERS) { /* Used by a fragment sampler */ if (!ps_resource_info) { /* No pixel shader, check fixed function */ - return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1u << current_mapping)); + return current_mapping >= WINED3D_MAX_TEXTURES + || !(context_gl->c.fixed_function_usage_map & (1u << current_mapping)); } /* Pixel shader, check the shader's sampler map */ @@ -3407,13 +3397,14 @@ static BOOL context_unit_free_for_vs(const struct wined3d_context *context, return TRUE; } -static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state) +static void wined3d_context_gl_map_vsamplers(struct wined3d_context_gl *context_gl, + BOOL ps, const struct wined3d_state *state) { const struct wined3d_shader_resource_info *vs_resource_info = state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info; const struct wined3d_shader_resource_info *ps_resource_info = NULL; - const struct wined3d_gl_info *gl_info = context->gl_info; - int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.graphics_samplers) - 1; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + int start = min(WINED3D_MAX_COMBINED_SAMPLERS, gl_info->limits.graphics_samplers) - 1; int i; /* Note that we only care if a resource is used or not, not the @@ -3422,19 +3413,19 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons if (ps) ps_resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info; - for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_VERTEX_SAMPLERS; ++i) { - DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS; + DWORD vsampler_idx = i + WINED3D_MAX_FRAGMENT_SAMPLERS; if (vs_resource_info[i].type) { while (start >= 0) { - if (context_unit_free_for_vs(context, ps_resource_info, start)) + if (wined3d_context_gl_unit_free_for_vs(context_gl, ps_resource_info, start)) { - if (context->tex_unit_map[vsampler_idx] != start) + if (context_gl->tex_unit_map[vsampler_idx] != start) { - context_map_stage(context, vsampler_idx, start); - context_invalidate_state(context, STATE_SAMPLER(vsampler_idx)); + wined3d_context_gl_map_stage(context_gl, vsampler_idx, start); + context_invalidate_state(&context_gl->c, STATE_SAMPLER(vsampler_idx)); } --start; @@ -3443,50 +3434,52 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons --start; } - if (context->tex_unit_map[vsampler_idx] == WINED3D_UNMAPPED_STAGE) + if (context_gl->tex_unit_map[vsampler_idx] == WINED3D_UNMAPPED_STAGE) WARN("Couldn't find a free texture unit for vertex sampler %u.\n", i); } } } -static void context_update_tex_unit_map(struct wined3d_context *context, const struct wined3d_state *state) +static void wined3d_context_gl_update_tex_unit_map(struct wined3d_context_gl *context_gl, + const struct wined3d_state *state) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; BOOL vs = use_vs(state); BOOL ps = use_ps(state); if (!ps) - context_update_fixed_function_usage_map(context, state); + context_update_fixed_function_usage_map(&context_gl->c, state); /* Try to go for a 1:1 mapping of the samplers when possible. Pixel shaders * need a 1:1 map at the moment. * When the mapping of a stage is changed, sampler and ALL texture stage * states have to be reset. */ - if (gl_info->limits.graphics_samplers >= MAX_COMBINED_SAMPLERS) + if (gl_info->limits.graphics_samplers >= WINED3D_MAX_COMBINED_SAMPLERS) return; if (ps) - context_map_psamplers(context, state); + wined3d_context_gl_map_psamplers(context_gl, state); else - context_map_fixed_function_samplers(context, state); + wined3d_context_gl_map_fixed_function_samplers(context_gl, state); if (vs) - context_map_vsamplers(context, ps, state); + wined3d_context_gl_map_vsamplers(context_gl, ps, state); } /* Context activation is done by the caller. */ void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD rt_mask, *cur_mask; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + uint32_t rt_mask, *cur_mask; if (isStateDirty(context, STATE_FRAMEBUFFER)) return; - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; - rt_mask = find_draw_buffers_mask(context, state); + cur_mask = context_gl->current_fbo ? &context_gl->current_fbo->rt_mask : &context_gl->draw_buffers_mask; + rt_mask = find_draw_buffers_mask(context_gl, state); if (rt_mask != *cur_mask) { - context_apply_draw_buffers(context, rt_mask); + wined3d_context_gl_apply_draw_buffers(context_gl, rt_mask); *cur_mask = rt_mask; } } @@ -3521,8 +3514,7 @@ static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum) /* Context activation is done by the caller. */ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, - const struct wined3d_state *state, const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info) + const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) { /* We need to deal with frequency data! */ struct wined3d_vertex_declaration *declaration = state->vertex_declaration; @@ -3618,8 +3610,7 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf stream_info->elements[idx].divisor = 0; } - if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] - && element->format->id == WINED3DFMT_B8G8R8A8_UNORM) + if (!d3d_info->vertex_bgra && element->format->id == WINED3DFMT_B8G8R8A8_UNORM) { stream_info->swizzle_map |= 1u << idx; } @@ -3633,12 +3624,11 @@ static void context_update_stream_info(struct wined3d_context *context, const st { struct wined3d_stream_info *stream_info = &context->stream_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; DWORD prev_all_vbo = stream_info->all_vbo; unsigned int i; WORD map; - wined3d_stream_info_from_declaration(stream_info, state, gl_info, d3d_info); + wined3d_stream_info_from_declaration(stream_info, state, d3d_info); stream_info->all_vbo = 1; context->buffer_fence_count = 0; @@ -3685,7 +3675,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st if (buffer->fence) context->buffer_fences[context->buffer_fence_count++] = buffer->fence; - TRACE("Load array %u {%#x:%p}.\n", i, element->data.buffer_object, element->data.addr); + TRACE("Load array %u %s.\n", i, debug_bo_address(&element->data)); } if (prev_all_vbo != stream_info->all_vbo) @@ -3696,18 +3686,10 @@ static void context_update_stream_info(struct wined3d_context *context, const st if (stream_info->all_vbo) return; - if (use_vs(state)) - { - if (state->vertex_declaration->half_float_conv_needed) - { - TRACE("Using immediate mode draw with vertex shaders for FLOAT16 conversion.\n"); - context->use_immediate_mode_draw = TRUE; - } - } - else + if (!use_vs(state)) { WORD slow_mask = -!d3d_info->ffp_generic_attributes & (1u << WINED3D_FFP_PSIZE); - slow_mask |= -(!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && !d3d_info->ffp_generic_attributes) + slow_mask |= -(!d3d_info->vertex_bgra && !d3d_info->ffp_generic_attributes) & ((1u << WINED3D_FFP_DIFFUSE) | (1u << WINED3D_FFP_SPECULAR) | (1u << WINED3D_FFP_BLENDWEIGHT)); if ((stream_info->position_transformed && !d3d_info->xyzrhw) @@ -3725,7 +3707,7 @@ static void context_preload_texture(struct wined3d_context *context, if (!(texture = state->textures[idx])) return; - wined3d_texture_load(texture, context, state->sampler_states[idx][WINED3D_SAMP_SRGB_TEXTURE]); + wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[idx])); } /* Context activation is done by the caller. */ @@ -3735,16 +3717,16 @@ static void context_preload_textures(struct wined3d_context *context, const stru if (use_vs(state)) { - for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_VERTEX_SAMPLERS; ++i) { if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info[i].type) - context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + i); + context_preload_texture(context, state, WINED3D_MAX_FRAGMENT_SAMPLERS + i); } } if (use_ps(state)) { - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) { if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info[i].type) context_preload_texture(context, state, i); @@ -3799,21 +3781,21 @@ static void context_load_shader_resources(struct wined3d_context *context, const } } -static void context_bind_shader_resources(struct wined3d_context *context, +static void wined3d_context_gl_bind_shader_resources(struct wined3d_context_gl *context_gl, const struct wined3d_state *state, enum wined3d_shader_type shader_type) { unsigned int bind_idx, shader_sampler_count, base, count, i; - const struct wined3d_device *device = context->device; + const struct wined3d_device *device = context_gl->c.device; struct wined3d_shader_sampler_map_entry *entry; struct wined3d_shader_resource_view *view; const struct wined3d_shader *shader; + const unsigned int *tex_unit_map; struct wined3d_sampler *sampler; - const DWORD *tex_unit_map; if (!(shader = state->shader[shader_type])) return; - tex_unit_map = context_get_tex_unit_mapping(context, + tex_unit_map = wined3d_context_gl_get_tex_unit_mapping(context_gl, &shader->reg_maps.shader_version, &base, &count); shader_sampler_count = shader->reg_maps.sampler_map.count; @@ -3839,7 +3821,8 @@ static void context_bind_shader_resources(struct wined3d_context *context, sampler = device->default_sampler; else if (!(sampler = state->sampler[shader_type][entry->sampler_idx])) sampler = device->null_sampler; - wined3d_shader_resource_view_bind(view, bind_idx, sampler, context); + wined3d_shader_resource_view_gl_bind(wined3d_shader_resource_view_gl(view), + bind_idx, wined3d_sampler_gl(sampler), context_gl); } } @@ -3878,11 +3861,12 @@ static void context_load_unordered_access_resources(struct wined3d_context *cont } } -static void context_bind_unordered_access_views(struct wined3d_context *context, +static void wined3d_context_gl_bind_unordered_access_views(struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views) { - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_unordered_access_view *view; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_unordered_access_view_gl *view_gl; + const struct wined3d_format_gl *format_gl; GLuint texture_name; unsigned int i; GLint level; @@ -3892,7 +3876,7 @@ static void context_bind_unordered_access_views(struct wined3d_context *context, for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i) { - if (!(view = views[i])) + if (!views[i]) { if (shader->reg_maps.uav_resource_info[i].type) WARN("No unordered access view bound at index %u.\n", i); @@ -3900,16 +3884,17 @@ static void context_bind_unordered_access_views(struct wined3d_context *context, continue; } - if (view->gl_view.name) + view_gl = wined3d_unordered_access_view_gl(views[i]); + if (view_gl->gl_view.name) { - texture_name = view->gl_view.name; + texture_name = view_gl->gl_view.name; level = 0; } - else if (view->resource->type != WINED3D_RTYPE_BUFFER) + else if (view_gl->v.resource->type != WINED3D_RTYPE_BUFFER) { - struct wined3d_texture *texture = texture_from_resource(view->resource); - texture_name = wined3d_texture_get_texture_name(texture, context, FALSE); - level = view->desc.u.texture.level_idx; + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(view_gl->v.resource)); + texture_name = wined3d_texture_gl_get_texture_name(texture_gl, &context_gl->c, FALSE); + level = view_gl->v.desc.u.texture.level_idx; } else { @@ -3918,11 +3903,12 @@ static void context_bind_unordered_access_views(struct wined3d_context *context, continue; } + format_gl = wined3d_format_gl(view_gl->v.format); GL_EXTCALL(glBindImageTexture(i, texture_name, level, GL_TRUE, 0, GL_READ_WRITE, - view->format->glInternal)); + format_gl->internal)); - if (view->counter_bo) - GL_EXTCALL(glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i, view->counter_bo)); + if (view_gl->counter_bo) + GL_EXTCALL(glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i, view_gl->counter_bo)); } checkGLcall("Bind unordered access views"); } @@ -3947,10 +3933,11 @@ static void context_load_stream_output_buffers(struct wined3d_context *context, static BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, const struct wined3d_state *state) { - const struct StateEntry *state_table = context->state_table; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state_entry *state_table = context->state_table; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_fb_state *fb = state->fb; - unsigned int i; + unsigned int i, base; WORD map; if (!have_framebuffer_attachment(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil)) @@ -3961,18 +3948,13 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, return FALSE; } - context_set_render_offscreen(context, TRUE); - } - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && isStateDirty(context, STATE_FRAMEBUFFER)) - { - context_validate_onscreen_formats(context, fb->depth_stencil); + wined3d_context_gl_set_render_offscreen(context_gl, TRUE); } /* Preload resources before FBO setup. Texture preload in particular may * result in changes to the current FBO, due to using e.g. FBO blits for * updating a resource location. */ - context_update_tex_unit_map(context, state); + wined3d_context_gl_update_tex_unit_map(context_gl, state); context_preload_textures(context, state); context_load_shader_resources(context, state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_PIXEL], @@ -4007,13 +3989,18 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, wined3d_buffer_load_sysmem(state->index_buffer, context); } - for (i = 0; i < context->numDirtyEntries; ++i) + for (i = 0, base = 0; i < ARRAY_SIZE(context->dirty_graphics_states); ++i) { - DWORD rep = context->dirtyArray[i]; - DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] &= ~(1u << shift); - state_table[rep].apply(context, state, rep); + uint32_t dirty_mask = context->dirty_graphics_states[i]; + + while (dirty_mask) + { + unsigned int state_id = base + wined3d_bit_scan(&dirty_mask); + + state_table[state_id].apply(context, state, state_id); + context->dirty_graphics_states[i] &= ~(1u << (state_id - base)); + } + base += sizeof(dirty_mask) * CHAR_BIT; } if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) @@ -4031,7 +4018,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, if (context->update_shader_resource_bindings) { for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) - context_bind_shader_resources(context, state, i); + wined3d_context_gl_bind_shader_resources(context_gl, state, i); context->update_shader_resource_bindings = 0; if (gl_info->limits.combined_samplers == gl_info->limits.graphics_samplers) context->update_compute_shader_resource_bindings = 1; @@ -4039,7 +4026,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, if (context->update_unordered_access_view_bindings) { - context_bind_unordered_access_views(context, + wined3d_context_gl_bind_unordered_access_views(context_gl, state->shader[WINED3D_SHADER_TYPE_PIXEL], state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); context->update_unordered_access_view_bindings = 0; @@ -4047,60 +4034,59 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, } if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - context_check_fbo_status(context, GL_FRAMEBUFFER); - } + wined3d_context_gl_check_fbo_status(context_gl, GL_FRAMEBUFFER); - context->numDirtyEntries = 0; /* This makes the whole list clean */ context->last_was_blit = FALSE; + context->last_was_ffp_blit = FALSE; return TRUE; } -static void context_apply_compute_state(struct wined3d_context *context, +static void wined3d_context_gl_apply_compute_state(struct wined3d_context_gl *context_gl, const struct wined3d_device *device, const struct wined3d_state *state) { - const struct StateEntry *state_table = context->state_table; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state_entry *state_table = context_gl->c.state_table; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int state_id, i; - context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE); - context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_COMPUTE], + context_load_shader_resources(&context_gl->c, state, 1u << WINED3D_SHADER_TYPE_COMPUTE); + context_load_unordered_access_resources(&context_gl->c, state->shader[WINED3D_SHADER_TYPE_COMPUTE], state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); - for (i = 0, state_id = STATE_COMPUTE_OFFSET; i < ARRAY_SIZE(context->dirty_compute_states); ++i) + for (i = 0, state_id = STATE_COMPUTE_OFFSET; i < ARRAY_SIZE(context_gl->c.dirty_compute_states); ++i) { - unsigned int dirty_mask = context->dirty_compute_states[i]; + unsigned int dirty_mask = context_gl->c.dirty_compute_states[i]; + while (dirty_mask) { unsigned int current_state_id = state_id + wined3d_bit_scan(&dirty_mask); - state_table[current_state_id].apply(context, state, current_state_id); + state_table[current_state_id].apply(&context_gl->c, state, current_state_id); } - state_id += sizeof(*context->dirty_compute_states) * CHAR_BIT; + state_id += sizeof(*context_gl->c.dirty_compute_states) * CHAR_BIT; } - memset(context->dirty_compute_states, 0, sizeof(*context->dirty_compute_states)); + memset(context_gl->c.dirty_compute_states, 0, sizeof(*context_gl->c.dirty_compute_states)); - if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE)) + if (context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE)) { - device->shader_backend->shader_select_compute(device->shader_priv, context, state); - context->shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE); + device->shader_backend->shader_select_compute(device->shader_priv, &context_gl->c, state); + context_gl->c.shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE); } - if (context->update_compute_shader_resource_bindings) + if (context_gl->c.update_compute_shader_resource_bindings) { - context_bind_shader_resources(context, state, WINED3D_SHADER_TYPE_COMPUTE); - context->update_compute_shader_resource_bindings = 0; + wined3d_context_gl_bind_shader_resources(context_gl, state, WINED3D_SHADER_TYPE_COMPUTE); + context_gl->c.update_compute_shader_resource_bindings = 0; if (gl_info->limits.combined_samplers == gl_info->limits.graphics_samplers) - context->update_shader_resource_bindings = 1; + context_gl->c.update_shader_resource_bindings = 1; } - if (context->update_compute_unordered_access_view_bindings) + if (context_gl->c.update_compute_unordered_access_view_bindings) { - context_bind_unordered_access_views(context, + wined3d_context_gl_bind_unordered_access_views(context_gl, state->shader[WINED3D_SHADER_TYPE_COMPUTE], state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); - context->update_compute_unordered_access_view_bindings = 0; - context->update_unordered_access_view_bindings = 1; + context_gl->c.update_compute_unordered_access_view_bindings = 0; + context_gl->c.update_unordered_access_view_bindings = 1; } /* Updates to currently bound render targets aren't necessarily coherent @@ -4110,10 +4096,11 @@ static void context_apply_compute_state(struct wined3d_context *context, * * Without this, the bloom effect in Nier:Automata is too bright on the * Mesa radeonsi driver, and presumably on other Mesa based drivers. */ - context_bind_fbo(context, GL_FRAMEBUFFER, 0); - context_invalidate_state(context, STATE_FRAMEBUFFER); + wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, 0); + context_invalidate_state(&context_gl->c, STATE_FRAMEBUFFER); - context->last_was_blit = FALSE; + context_gl->c.last_was_blit = FALSE; + context_gl->c.last_was_ffp_blit = FALSE; } static BOOL use_transform_feedback(const struct wined3d_state *state) @@ -4124,59 +4111,60 @@ static BOOL use_transform_feedback(const struct wined3d_state *state) return shader->u.gs.so_desc.element_count; } -void context_end_transform_feedback(struct wined3d_context *context) +void wined3d_context_gl_end_transform_feedback(struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; - if (context->transform_feedback_active) + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + + if (context_gl->c.transform_feedback_active) { GL_EXTCALL(glEndTransformFeedback()); checkGLcall("glEndTransformFeedback"); - context->transform_feedback_active = 0; - context->transform_feedback_paused = 0; + context_gl->c.transform_feedback_active = 0; + context_gl->c.transform_feedback_paused = 0; } } -static void context_pause_transform_feedback(struct wined3d_context *context, BOOL force) +static void wined3d_context_gl_pause_transform_feedback(struct wined3d_context_gl *context_gl, BOOL force) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; - if (!context->transform_feedback_active || context->transform_feedback_paused) + if (!context_gl->c.transform_feedback_active || context_gl->c.transform_feedback_paused) return; if (gl_info->supported[ARB_TRANSFORM_FEEDBACK2]) { GL_EXTCALL(glPauseTransformFeedback()); checkGLcall("glPauseTransformFeedback"); - context->transform_feedback_paused = 1; + context_gl->c.transform_feedback_paused = 1; return; } WARN("Cannot pause transform feedback operations.\n"); if (force) - context_end_transform_feedback(context); + wined3d_context_gl_end_transform_feedback(context_gl); } -static void context_setup_target(struct wined3d_context *context, +static void wined3d_context_gl_setup_target(struct wined3d_context_gl *context_gl, struct wined3d_texture *texture, unsigned int sub_resource_idx) { - BOOL old_render_offscreen = context->render_offscreen, render_offscreen; + BOOL old_render_offscreen = context_gl->c.render_offscreen, render_offscreen; render_offscreen = wined3d_resource_is_offscreen(&texture->resource); - if (context->current_rt.texture == texture - && context->current_rt.sub_resource_idx == sub_resource_idx + if (context_gl->c.current_rt.texture == texture + && context_gl->c.current_rt.sub_resource_idx == sub_resource_idx && render_offscreen == old_render_offscreen) return; /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers * the alpha blend state changes with different render target formats. */ - if (!context->current_rt.texture) + if (!context_gl->c.current_rt.texture) { - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); + context_invalidate_state(&context_gl->c, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); } else { - const struct wined3d_format *old = context->current_rt.texture->resource.format; + const struct wined3d_format *old = context_gl->c.current_rt.texture->resource.format; const struct wined3d_format *new = texture->resource.format; if (old->id != new->id) @@ -4184,12 +4172,12 @@ static void context_setup_target(struct wined3d_context *context, /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ if ((old->alpha_size && !new->alpha_size) || (!old->alpha_size && new->alpha_size) || !(texture->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); + context_invalidate_state(&context_gl->c, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); /* Update sRGB writing when switching between formats that do/do not support sRGB writing */ - if ((context->current_rt.texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE) + if ((context_gl->c.current_rt.texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE) != (texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)) - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + context_invalidate_state(&context_gl->c, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); } /* When switching away from an offscreen render target, and we're not @@ -4200,68 +4188,64 @@ static void context_setup_target(struct wined3d_context *context, * has to be called with the old rendertarget active, otherwise a * wrong drawable is read. */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && old_render_offscreen && (context->current_rt.texture != texture - || context->current_rt.sub_resource_idx != sub_resource_idx)) + && old_render_offscreen && (context_gl->c.current_rt.texture != texture + || context_gl->c.current_rt.sub_resource_idx != sub_resource_idx)) { - unsigned int prev_sub_resource_idx = context->current_rt.sub_resource_idx; - struct wined3d_texture *prev_texture = context->current_rt.texture; + struct wined3d_texture_gl *prev_texture = wined3d_texture_gl(context_gl->c.current_rt.texture); + unsigned int prev_sub_resource_idx = context_gl->c.current_rt.sub_resource_idx; /* Read the back buffer of the old drawable into the destination texture. */ if (prev_texture->texture_srgb.name) - wined3d_texture_load(prev_texture, context, TRUE); - wined3d_texture_load(prev_texture, context, FALSE); - wined3d_texture_invalidate_location(prev_texture, prev_sub_resource_idx, WINED3D_LOCATION_DRAWABLE); + wined3d_texture_load(&prev_texture->t, &context_gl->c, TRUE); + wined3d_texture_load(&prev_texture->t, &context_gl->c, FALSE); + wined3d_texture_invalidate_location(&prev_texture->t, prev_sub_resource_idx, WINED3D_LOCATION_DRAWABLE); } } - context->current_rt.texture = texture; - context->current_rt.sub_resource_idx = sub_resource_idx; - context_set_render_offscreen(context, render_offscreen); + context_gl->c.current_rt.texture = texture; + context_gl->c.current_rt.sub_resource_idx = sub_resource_idx; + wined3d_context_gl_set_render_offscreen(context_gl, render_offscreen); } -static void context_activate(struct wined3d_context *context, +static void wined3d_context_gl_activate(struct wined3d_context_gl *context_gl, struct wined3d_texture *texture, unsigned int sub_resource_idx) { - context_enter(context); - context_update_window(context); - context_setup_target(context, texture, sub_resource_idx); - if (!context->valid) + wined3d_context_gl_enter(context_gl); + wined3d_context_gl_update_window(context_gl); + wined3d_context_gl_setup_target(context_gl, texture, sub_resource_idx); + if (!context_gl->valid) return; - if (context != context_get_current()) + if (context_gl != wined3d_context_gl_get_current()) { - if (!context_set_current(context)) + if (!wined3d_context_gl_set_current(context_gl)) ERR("Failed to activate the new context.\n"); } - else if (context->needs_set) + else if (context_gl->needs_set) { - context_set_gl_context(context); + wined3d_context_gl_set_gl_context(context_gl); } } -struct wined3d_context *context_acquire(const struct wined3d_device *device, +struct wined3d_context *wined3d_context_gl_acquire(const struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx) { - struct wined3d_context *current_context = context_get_current(); - struct wined3d_context *context; - BOOL swapchain_texture; + struct wined3d_context_gl *current_context = wined3d_context_gl_get_current(); + struct wined3d_context_gl *context_gl; TRACE("device %p, texture %p, sub_resource_idx %u.\n", device, texture, sub_resource_idx); - wined3d_from_cs(device->cs); - - if (current_context && current_context->destroyed) + if (current_context && current_context->c.destroyed) current_context = NULL; - swapchain_texture = texture && texture->swapchain; if (!texture) { if (current_context - && current_context->current_rt.texture - && current_context->device == device) + && current_context->c.current_rt.texture + && current_context->c.device == device) { - texture = current_context->current_rt.texture; - sub_resource_idx = current_context->current_rt.sub_resource_idx; + texture = current_context->c.current_rt.texture; + sub_resource_idx = current_context->c.current_rt.sub_resource_idx; } else { @@ -4275,15 +4259,16 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, } } - if (current_context && current_context->current_rt.texture == texture) + if (current_context && current_context->c.current_rt.texture == texture) { - context = current_context; + context_gl = current_context; } - else if (swapchain_texture) + else if (!wined3d_resource_is_offscreen(&texture->resource)) { TRACE("Rendering onscreen.\n"); - context = swapchain_get_context(texture->swapchain); + if (!(context_gl = wined3d_swapchain_gl_get_context(wined3d_swapchain_gl(texture->swapchain)))) + return NULL; } else { @@ -4291,69 +4276,71 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, /* Stay with the current context if possible. Otherwise use the * context for the primary swapchain. */ - if (current_context && current_context->device == device) - context = current_context; - else - context = swapchain_get_context(device->swapchains[0]); + if (current_context && current_context->c.device == device) + context_gl = current_context; + else if (!(context_gl = wined3d_swapchain_gl_get_context(wined3d_swapchain_gl(device->swapchains[0])))) + return NULL; } - context_activate(context, texture, sub_resource_idx); + wined3d_context_gl_activate(context_gl, texture, sub_resource_idx); - return context; + return &context_gl->c; } -struct wined3d_context *context_reacquire(const struct wined3d_device *device, - struct wined3d_context *context) +struct wined3d_context_gl *wined3d_context_gl_reacquire(struct wined3d_context_gl *context_gl) { struct wined3d_context *acquired_context; + struct wined3d_device *device; - wined3d_from_cs(device->cs); - - if (!context || context->tid != GetCurrentThreadId()) + if (!context_gl || context_gl->tid != GetCurrentThreadId()) return NULL; - if (context->current_rt.texture) + device = context_gl->c.device; + wined3d_from_cs(device->cs); + + if (context_gl->c.current_rt.texture) { - context_activate(context, context->current_rt.texture, context->current_rt.sub_resource_idx); - return context; + wined3d_context_gl_activate(context_gl, context_gl->c.current_rt.texture, + context_gl->c.current_rt.sub_resource_idx); + return context_gl; } acquired_context = context_acquire(device, NULL, 0); - if (acquired_context != context) - ERR("Acquired context %p instead of %p.\n", acquired_context, context); - return acquired_context; + if (acquired_context != &context_gl->c) + ERR("Acquired context %p instead of %p.\n", acquired_context, &context_gl->c); + return wined3d_context_gl(acquired_context); } void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state, const struct wined3d_dispatch_parameters *parameters) { const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; - context = context_acquire(device, NULL, 0); - if (!context->valid) + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + if (!context_gl->valid) { - context_release(context); + context_release(&context_gl->c); WARN("Invalid context, skipping dispatch.\n"); return; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; if (!gl_info->supported[ARB_COMPUTE_SHADER]) { - context_release(context); + context_release(&context_gl->c); FIXME("OpenGL implementation does not support compute shaders.\n"); return; } if (parameters->indirect) - wined3d_buffer_load(parameters->u.indirect.buffer, context, state); + wined3d_buffer_load(parameters->u.indirect.buffer, &context_gl->c, state); - context_apply_compute_state(context, device, state); + wined3d_context_gl_apply_compute_state(context_gl, device, state); if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE]) { - context_release(context); + context_release(&context_gl->c); WARN("No compute shader bound, skipping dispatch.\n"); return; } @@ -4377,22 +4364,19 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); checkGLcall("glMemoryBarrier"); - if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); + context_release(&context_gl->c); } /* Context activation is done by the caller. */ -static void draw_primitive_arrays(struct wined3d_context *context, const struct wined3d_state *state, - const void *idx_data, unsigned int idx_size, int base_vertex_idx, unsigned int start_idx, - unsigned int count, unsigned int start_instance, unsigned int instance_count) +static void wined3d_context_gl_draw_primitive_arrays(struct wined3d_context_gl *context_gl, + const struct wined3d_state *state, const void *idx_data, unsigned int idx_size, int base_vertex_idx, + unsigned int start_idx, unsigned int count, unsigned int start_instance, unsigned int instance_count) { - const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops; + const struct wined3d_ffp_attrib_ops *ops = &context_gl->c.d3d_info->ffp_attrib_ops; GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; - const struct wined3d_stream_info *si = &context->stream_info; + const struct wined3d_stream_info *si = &context_gl->c.stream_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int instanced_elements[ARRAY_SIZE(si->elements)]; - const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int instanced_element_count = 0; GLenum mode = state->gl_primitive_type; const void *indices; @@ -4497,7 +4481,8 @@ static void draw_primitive_arrays(struct wined3d_context *context, const struct element = &si->elements[element_idx]; ptr = element->data.addr + element->stride * i; if (element->data.buffer_object) - ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(state->streams[element->stream_idx].buffer, context); + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(state->streams[element->stream_idx].buffer, + &context_gl->c); ops->generic[element->format->emit_idx](element_idx, ptr); } @@ -4514,100 +4499,6 @@ static void draw_primitive_arrays(struct wined3d_context *context, const struct } } -static const BYTE *software_vertex_blending(struct wined3d_context *context, - const struct wined3d_state *state, const struct wined3d_stream_info *si, - unsigned int element_idx, unsigned int stride_idx, float *result) -{ -#define SI_FORMAT(idx) (si->elements[(idx)].format->emit_idx) -#define SI_PTR(idx1, idx2) (si->elements[(idx1)].data.addr + si->elements[(idx1)].stride * (idx2)) - - const float *data = (const float *)SI_PTR(element_idx, stride_idx); - float vector[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - float cur_weight, weight_sum = 0.0f; - struct wined3d_matrix m; - const BYTE *blend_index; - const float *weights; - int i, num_weights; - - if (element_idx != WINED3D_FFP_POSITION && element_idx != WINED3D_FFP_NORMAL) - return (BYTE *)data; - - if (!use_indexed_vertex_blending(state, si) || !use_software_vertex_processing(context->device)) - return (BYTE *)data; - - if (!si->elements[WINED3D_FFP_BLENDINDICES].data.addr || - !si->elements[WINED3D_FFP_BLENDWEIGHT].data.addr) - { - FIXME("no blend indices / weights set\n"); - return (BYTE *)data; - } - - if (SI_FORMAT(WINED3D_FFP_BLENDINDICES) != WINED3D_FFP_EMIT_UBYTE4) - { - FIXME("unsupported blend index format: %u\n", SI_FORMAT(WINED3D_FFP_BLENDINDICES)); - return (BYTE *)data; - } - - /* FIXME: validate weight format */ - switch (state->render_states[WINED3D_RS_VERTEXBLEND]) - { - case WINED3D_VBF_0WEIGHTS: num_weights = 0; break; - case WINED3D_VBF_1WEIGHTS: num_weights = 1; break; - case WINED3D_VBF_2WEIGHTS: num_weights = 2; break; - case WINED3D_VBF_3WEIGHTS: num_weights = 3; break; - default: - FIXME("unsupported vertex blend render state: %u\n", state->render_states[WINED3D_RS_VERTEXBLEND]); - return (BYTE *)data; - } - - switch (SI_FORMAT(element_idx)) - { - case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3]; - case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2]; - case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1]; - default: - FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx)); - return (BYTE *)data; - } - - blend_index = SI_PTR(WINED3D_FFP_BLENDINDICES, stride_idx); - weights = (const float *)SI_PTR(WINED3D_FFP_BLENDWEIGHT, stride_idx); - result[0] = result[1] = result[2] = result[3] = 0.0f; - - for (i = 0; i < num_weights + 1; i++) - { - cur_weight = (i < num_weights) ? weights[i] : 1.0f - weight_sum; - get_modelview_matrix(context, state, blend_index[i], &m); - - if (element_idx == WINED3D_FFP_POSITION) - { - result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._21 + vector[2] * m._31 + vector[3] * m._41); - result[1] += cur_weight * (vector[0] * m._12 + vector[1] * m._22 + vector[2] * m._32 + vector[3] * m._42); - result[2] += cur_weight * (vector[0] * m._13 + vector[1] * m._23 + vector[2] * m._33 + vector[3] * m._43); - result[3] += cur_weight * (vector[0] * m._14 + vector[1] * m._24 + vector[2] * m._34 + vector[3] * m._44); - } - else - { - if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING) - invert_matrix_3d(&m, &m); - else - invert_matrix(&m, &m); - - /* multiply with transposed M */ - result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._12 + vector[2] * m._13); - result[1] += cur_weight * (vector[0] * m._21 + vector[1] * m._22 + vector[2] * m._23); - result[2] += cur_weight * (vector[0] * m._31 + vector[1] * m._32 + vector[2] * m._33); - } - - weight_sum += weights[i]; - } - -#undef SI_FORMAT -#undef SI_PTR - - return (BYTE *)result; -} - static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size, unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx) { @@ -4619,14 +4510,14 @@ static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size, } /* Context activation is done by the caller. */ -static void draw_primitive_immediate_mode(struct wined3d_context *context, const struct wined3d_state *state, +static void draw_primitive_immediate_mode(struct wined3d_context_gl *context_gl, const struct wined3d_state *state, const struct wined3d_stream_info *si, const void *idx_data, unsigned int idx_size, int base_vertex_idx, unsigned int start_idx, unsigned int vertex_count, unsigned int instance_count) { const BYTE *position = NULL, *normal = NULL, *diffuse = NULL, *specular = NULL; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int coord_idx, stride_idx, texture_idx, vertex_idx; - const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_stream_info_element *element; const BYTE *tex_coords[WINED3DDP_MAXTEXCOORD]; unsigned int texture_unit, texture_stages; @@ -4636,7 +4527,6 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const BOOL specular_fog = FALSE; BOOL ps = use_ps(state); const void *ptr; - float tmp[4]; static unsigned int once; @@ -4654,7 +4544,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const /* Immediate mode drawing can't make use of indices in a VBO - get the * data from the index buffer. */ if (idx_size) - idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context) + state->index_offset; + idx_data = wined3d_buffer_load_sysmem(state->index_buffer, &context_gl->c) + state->index_offset; ops = &d3d_info->ffp_attrib_ops; @@ -4673,7 +4563,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const if (!(use_map & 1u << element_idx)) continue; - ptr = software_vertex_blending(context, state, si, element_idx, stride_idx, tmp); + ptr = si->elements[element_idx].data.addr + si->elements[element_idx].stride * stride_idx; ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr); } } @@ -4690,7 +4580,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const else gl_info->gl_ops.gl.p_glNormal3f(0.0f, 0.0f, 0.0f); - untracked_material_count = context->num_untracked_materials; + untracked_material_count = context_gl->untracked_material_count; if (si->use_map & (1u << WINED3D_FFP_DIFFUSE)) { element = &si->elements[WINED3D_FFP_DIFFUSE]; @@ -4748,7 +4638,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const if (!ps && !state->textures[texture_idx]) continue; - texture_unit = context->tex_unit_map[texture_idx]; + texture_unit = context_gl->tex_unit_map[texture_idx]; if (texture_unit == WINED3D_UNMAPPED_STAGE) continue; @@ -4785,7 +4675,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const if (normal) { - ptr = software_vertex_blending(context, state, si, WINED3D_FFP_NORMAL, stride_idx, tmp); + ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride; ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr); } @@ -4802,7 +4692,8 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const wined3d_color_from_d3dcolor(&color, *(const DWORD *)ptr); for (i = 0; i < untracked_material_count; ++i) { - gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], &color.r); + gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, + context_gl->untracked_materials[i], &color.r); } } } @@ -4825,12 +4716,12 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX]; ptr = tex_coords[coord_idx] + (stride_idx * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride); ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx]( - GL_TEXTURE0_ARB + context->tex_unit_map[texture_idx], ptr); + GL_TEXTURE0_ARB + context_gl->tex_unit_map[texture_idx], ptr); } if (position) { - ptr = software_vertex_blending(context, state, si, WINED3D_FFP_POSITION, stride_idx, tmp); + ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride; ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr); } } @@ -4839,10 +4730,10 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const checkGLcall("draw immediate mode"); } -static void draw_indirect(struct wined3d_context *context, const struct wined3d_state *state, +static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_gl, const struct wined3d_state *state, const struct wined3d_indirect_draw_parameters *parameters, unsigned int idx_size) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_buffer *buffer = parameters->buffer; const void *offset; @@ -4931,6 +4822,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s struct wined3d_stream_info si_emulated; struct wined3d_fence *ib_fence = NULL; const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; struct wined3d_context *context; unsigned int i, idx_size = 0; const void *idx_data = NULL; @@ -4940,20 +4832,28 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (!(rtv = fb->render_targets[0])) rtv = fb->depth_stencil; + + if (rtv && rtv->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Buffer render targets not implemented.\n"); + return; + } + if (rtv) context = context_acquire(device, wined3d_texture_from_resource(rtv->resource), rtv->sub_resource_idx); else context = context_acquire(device, NULL, 0); - if (!context->valid) + context_gl = wined3d_context_gl(context); + if (!context_gl->valid) { context_release(context); WARN("Invalid context, skipping draw.\n"); return; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; if (!use_transform_feedback(state)) - context_pause_transform_feedback(context, TRUE); + wined3d_context_gl_pause_transform_feedback(context_gl, TRUE); for (i = 0; i < gl_info->limits.buffers; ++i) { @@ -5028,7 +4928,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (!use_vs(state)) { - if (!stream_info->position_transformed && context->num_untracked_materials + if (!stream_info->position_transformed && context_gl->untracked_material_count && state->render_states[WINED3D_RS_LIGHTING]) { static BOOL warned; @@ -5052,12 +4952,6 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n"); emulation = TRUE; } - else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device)) - { - WARN_(d3d_perf)("Using software emulation because application requested SVP.\n"); - emulation = TRUE; - } - if (emulation) { @@ -5086,7 +4980,9 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s } else if (!context->transform_feedback_active) { - GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type); + enum wined3d_primitive_type primitive_type = shader->u.gs.output_type + ? shader->u.gs.output_type : d3d_primitive_type_from_gl(state->gl_primitive_type); + GLenum mode = gl_tfb_primitive_type_from_d3d(primitive_type); GL_EXTCALL(glBeginTransformFeedback(mode)); checkGLcall("glBeginTransformFeedback"); context->transform_feedback_active = 1; @@ -5102,7 +4998,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (parameters->indirect) { if (!context->use_immediate_mode_draw && !emulation) - draw_indirect(context, state, ¶meters->u.indirect, idx_size); + wined3d_context_gl_draw_indirect(context_gl, state, ¶meters->u.indirect, idx_size); else FIXME("Indirect draws with immediate mode/emulation are not supported.\n"); } @@ -5113,13 +5009,13 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s instance_count = context->instance_count; if (context->use_immediate_mode_draw || emulation) - draw_primitive_immediate_mode(context, state, stream_info, idx_data, + draw_primitive_immediate_mode(wined3d_context_gl(context), state, stream_info, idx_data, idx_size, parameters->u.direct.base_vertex_idx, parameters->u.direct.start_idx, parameters->u.direct.index_count, instance_count); else - draw_primitive_arrays(context, state, idx_data, idx_size, parameters->u.direct.base_vertex_idx, - parameters->u.direct.start_idx, parameters->u.direct.index_count, - parameters->u.direct.start_instance, instance_count); + wined3d_context_gl_draw_primitive_arrays(context_gl, state, idx_data, idx_size, + parameters->u.direct.base_vertex_idx, parameters->u.direct.start_idx, + parameters->u.direct.index_count, parameters->u.direct.start_instance, instance_count); } if (context->uses_uavs) @@ -5128,7 +5024,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s checkGLcall("glMemoryBarrier"); } - context_pause_transform_feedback(context, FALSE); + wined3d_context_gl_pause_transform_feedback(context_gl, FALSE); if (rasterizer_discard) { @@ -5141,8 +5037,694 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s for (i = 0; i < context->buffer_fence_count; ++i) wined3d_fence_issue(context->buffer_fences[i], device); - if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - context_release(context); } + +void wined3d_context_gl_unload_tex_coords(const struct wined3d_context_gl *context_gl) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int texture_idx; + + for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx) + { + gl_info->gl_ops.ext.p_glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx); + gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } +} + +void wined3d_context_gl_load_tex_coords(const struct wined3d_context_gl *context_gl, + const struct wined3d_stream_info *si, GLuint *current_bo, const struct wined3d_state *state) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_format_gl *format_gl; + unsigned int mapped_stage = 0; + unsigned int texture_idx; + + for (texture_idx = 0; texture_idx < context_gl->c.d3d_info->limits.ffp_blend_stages; ++texture_idx) + { + unsigned int coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX]; + + if ((mapped_stage = context_gl->tex_unit_map[texture_idx]) == WINED3D_UNMAPPED_STAGE) + continue; + + if (mapped_stage >= gl_info->limits.texture_coords) + { + FIXME("Attempted to load unsupported texture coordinate %u.\n", mapped_stage); + continue; + } + + if (coord_idx < WINED3D_MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) + { + const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx]; + + TRACE("Setting up texture %u, idx %u, coord_idx %u, data %s.\n", + texture_idx, mapped_stage, coord_idx, debug_bo_address(&e->data)); + + if (*current_bo != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + *current_bo = e->data.buffer_object; + } + + GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); + checkGLcall("glClientActiveTextureARB"); + + /* The coords to supply depend completely on the fvf/vertex shader. */ + format_gl = wined3d_format_gl(e->format); + gl_info->gl_ops.gl.p_glTexCoordPointer(format_gl->vtx_format, format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else + { + GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1)); + } + } + if (gl_info->supported[NV_REGISTER_COMBINERS]) + { + /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */ + for (texture_idx = mapped_stage + 1; texture_idx < gl_info->limits.textures; ++texture_idx) + { + GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1)); + } + } + + checkGLcall("loadTexCoords"); +} + +/* This should match any arrays loaded in wined3d_context_gl_load_vertex_data(). */ +static void wined3d_context_gl_unload_vertex_data(struct wined3d_context_gl *context_gl) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + + if (!context_gl->c.namedArraysLoaded) + return; + gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY); + gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY); + gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY); + if (gl_info->supported[EXT_SECONDARY_COLOR]) + gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); + wined3d_context_gl_unload_tex_coords(context_gl); + context_gl->c.namedArraysLoaded = FALSE; +} + +static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *context_gl, + const struct wined3d_stream_info *si, const struct wined3d_state *state) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_stream_info_element *e; + const struct wined3d_format_gl *format_gl; + GLuint current_bo; + + TRACE("context_gl %p, si %p, state %p.\n", context_gl, si, state); + + /* This is used for the fixed-function pipeline only, and the + * fixed-function pipeline doesn't do instancing. */ + context_gl->c.instance_count = 0; + current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0; + + /* Blend data */ + if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT)) + || si->use_map & (1u << WINED3D_FFP_BLENDINDICES)) + { + /* TODO: Support vertex blending in immediate mode draws. No need to + * write a FIXME here, this is done after the general vertex + * declaration decoding. */ + WARN("Vertex blending not supported.\n"); + } + + /* Point Size */ + if (si->use_map & (1u << WINED3D_FFP_PSIZE)) + { + /* No such functionality in the fixed-function GL pipeline. */ + WARN("Per-vertex point size not supported.\n"); + } + + /* Position */ + if (si->use_map & (1u << WINED3D_FFP_POSITION)) + { + e = &si->elements[WINED3D_FFP_POSITION]; + format_gl = wined3d_format_gl(e->format); + + if (current_bo != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + current_bo = e->data.buffer_object; + } + + TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", + format_gl->vtx_format, format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glVertexPointer(format_gl->vtx_format, format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + checkGLcall("glVertexPointer(...)"); + gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY); + checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); + } + + /* Normals */ + if (si->use_map & (1u << WINED3D_FFP_NORMAL)) + { + e = &si->elements[WINED3D_FFP_NORMAL]; + format_gl = wined3d_format_gl(e->format); + + if (current_bo != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + current_bo = e->data.buffer_object; + } + + TRACE("glNormalPointer(%#x, %#x, %p);\n", format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glNormalPointer(format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + checkGLcall("glNormalPointer(...)"); + gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY); + checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); + + } + else + { + gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0); + checkGLcall("glNormal3f(0, 0, 0)"); + } + + /* Diffuse colour */ + if (si->use_map & (1u << WINED3D_FFP_DIFFUSE)) + { + e = &si->elements[WINED3D_FFP_DIFFUSE]; + format_gl = wined3d_format_gl(e->format); + + if (current_bo != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + current_bo = e->data.buffer_object; + } + + TRACE("glColorPointer(%#x, %#x %#x, %p);\n", + format_gl->vtx_format, format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + gl_info->gl_ops.gl.p_glColorPointer(format_gl->vtx_format, format_gl->vtx_type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); + gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY); + checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); + + } + else + { + gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + checkGLcall("glColor4f(1, 1, 1, 1)"); + } + + /* Specular colour */ + if (si->use_map & (1u << WINED3D_FFP_SPECULAR)) + { + TRACE("Setting specular colour.\n"); + + e = &si->elements[WINED3D_FFP_SPECULAR]; + + if (gl_info->supported[EXT_SECONDARY_COLOR]) + { + GLint format; + GLenum type; + + format_gl = wined3d_format_gl(e->format); + type = format_gl->vtx_type; + format = format_gl->vtx_format; + + if (current_bo != e->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); + checkGLcall("glBindBuffer"); + current_bo = e->data.buffer_object; + } + + if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA)) + { + /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha + * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function + * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts + * 4 component secondary colors use it + */ + TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); + } + else + { + switch (type) + { + case GL_UNSIGNED_BYTE: + TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); + break; + + default: + FIXME("Add 4 component specular colour pointers for type %#x.\n", type); + /* Make sure that the right colour component is dropped. */ + TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride); + GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, + e->data.addr + state->load_base_vertex_index * e->stride)); + checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); + } + } + gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); + checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); + } + } + else + { + if (gl_info->supported[EXT_SECONDARY_COLOR]) + { + GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); + checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); + } + } + + /* Texture coordinates */ + wined3d_context_gl_load_tex_coords(context_gl, si, ¤t_bo, state); +} + +static void wined3d_context_gl_unload_numbered_array(struct wined3d_context_gl *context_gl, unsigned int i) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + + GL_EXTCALL(glDisableVertexAttribArray(i)); + checkGLcall("glDisableVertexAttribArray"); + if (gl_info->supported[ARB_INSTANCED_ARRAYS]) + GL_EXTCALL(glVertexAttribDivisor(i, 0)); + + context_gl->c.numbered_array_mask &= ~(1u << i); +} + +static void wined3d_context_gl_unload_numbered_arrays(struct wined3d_context_gl *context_gl) +{ + uint32_t mask = context_gl->c.numbered_array_mask; + unsigned int i; + + while (mask) + { + i = wined3d_bit_scan(&mask); + wined3d_context_gl_unload_numbered_array(context_gl, i); + } +} + +static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *context_gl, + const struct wined3d_stream_info *stream_info, const struct wined3d_state *state) +{ + struct wined3d_context *context = &context_gl->c; + const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLuint current_bo; + unsigned int i; + + /* Default to no instancing. */ + context->instance_count = 0; + current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0; + + for (i = 0; i < MAX_ATTRIBS; ++i) + { + const struct wined3d_stream_info_element *element = &stream_info->elements[i]; + const struct wined3d_stream_state *stream; + const struct wined3d_format_gl *format_gl; + + if (!(stream_info->use_map & (1u << i))) + { + if (context->numbered_array_mask & (1u << i)) + wined3d_context_gl_unload_numbered_array(context_gl, i); + if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE) + { + if (!(context_gl->default_attrib_value_set & (1u << i)) || !context_gl->diffuse_attrib_to_1) + { + GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f)); + context_gl->diffuse_attrib_to_1 = 1; + } + } + else + { + if (!(context_gl->default_attrib_value_set & (1u << i))) + { + GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f)); + if (i == WINED3D_FFP_DIFFUSE) + context_gl->diffuse_attrib_to_1 = 0; + } + } + context_gl->default_attrib_value_set |= 1u << i; + continue; + } + + format_gl = wined3d_format_gl(element->format); + stream = &state->streams[element->stream_idx]; + + if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count) + context->instance_count = state->streams[0].frequency; + + if (gl_info->supported[ARB_INSTANCED_ARRAYS]) + { + GL_EXTCALL(glVertexAttribDivisor(i, element->divisor)); + } + else if (element->divisor) + { + /* Unload instanced arrays, they will be loaded using immediate + * mode instead. */ + if (context->numbered_array_mask & (1u << i)) + wined3d_context_gl_unload_numbered_array(context_gl, i); + context_gl->default_attrib_value_set &= ~(1u << i); + continue; + } + + TRACE("Loading array %u %s.\n", i, debug_bo_address(&element->data)); + + if (element->stride) + { + DWORD format_flags = format_gl->f.flags[WINED3D_GL_RES_TYPE_BUFFER]; + + if (current_bo != element->data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object)); + checkGLcall("glBindBuffer"); + current_bo = element->data.buffer_object; + } + /* Use the VBO to find out if a vertex buffer exists, not the vb + * pointer. vb can point to a user pointer data blob. In that case + * current_bo will be 0. If there is a vertex buffer but no vbo we + * won't be load converted attributes anyway. */ + if (vs && vs->reg_maps.shader_version.major >= 4 && (format_flags & WINED3DFMT_FLAG_INTEGER)) + { + GL_EXTCALL(glVertexAttribIPointer(i, format_gl->vtx_format, format_gl->vtx_type, + element->stride, element->data.addr + state->load_base_vertex_index * element->stride)); + } + else + { + GL_EXTCALL(glVertexAttribPointer(i, format_gl->vtx_format, format_gl->vtx_type, + !!(format_flags & WINED3DFMT_FLAG_NORMALISED), element->stride, + element->data.addr + state->load_base_vertex_index * element->stride)); + } + + if (!(context->numbered_array_mask & (1u << i))) + { + GL_EXTCALL(glEnableVertexAttribArray(i)); + context->numbered_array_mask |= (1u << i); + } + } + else + { + /* Stride = 0 means always the same values. + * glVertexAttribPointer() doesn't do that. Instead disable the + * pointer and set up the attribute statically. But we have to + * figure out the system memory address. */ + const BYTE *ptr = element->data.addr; + if (element->data.buffer_object) + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context); + + if (context->numbered_array_mask & (1u << i)) + wined3d_context_gl_unload_numbered_array(context_gl, i); + + switch (format_gl->f.id) + { + case WINED3DFMT_R32_FLOAT: + GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R32G32_FLOAT: + GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R32G32B32_FLOAT: + GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R32G32B32A32_FLOAT: + GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr)); + break; + case WINED3DFMT_R8G8B8A8_UINT: + GL_EXTCALL(glVertexAttrib4ubv(i, ptr)); + break; + case WINED3DFMT_B8G8R8A8_UNORM: + if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + { + const DWORD *src = (const DWORD *)ptr; + DWORD c = *src & 0xff00ff00u; + c |= (*src & 0xff0000u) >> 16; + c |= (*src & 0xffu) << 16; + GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c)); + break; + } + /* else fallthrough */ + case WINED3DFMT_R8G8B8A8_UNORM: + GL_EXTCALL(glVertexAttrib4Nubv(i, ptr)); + break; + case WINED3DFMT_R16G16_SINT: + GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr)); + break; + case WINED3DFMT_R16G16B16A16_SINT: + GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr)); + break; + case WINED3DFMT_R16G16_SNORM: + { + const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1}; + GL_EXTCALL(glVertexAttrib4Nsv(i, s)); + break; + } + case WINED3DFMT_R16G16_UNORM: + { + const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1}; + GL_EXTCALL(glVertexAttrib4Nusv(i, s)); + break; + } + case WINED3DFMT_R16G16B16A16_SNORM: + GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr)); + break; + case WINED3DFMT_R16G16B16A16_UNORM: + GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr)); + break; + case WINED3DFMT_R10G10B10X2_UINT: + FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n"); + /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */ + break; + case WINED3DFMT_R10G10B10X2_SNORM: + FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n"); + /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */ + break; + case WINED3DFMT_R16G16_FLOAT: + if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) + { + /* Not supported by GL_ARB_half_float_vertex. */ + GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr)); + } + else + { + float x = float_16_to_32(((const unsigned short *)ptr) + 0); + float y = float_16_to_32(((const unsigned short *)ptr) + 1); + GL_EXTCALL(glVertexAttrib2f(i, x, y)); + } + break; + case WINED3DFMT_R16G16B16A16_FLOAT: + if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) + { + /* Not supported by GL_ARB_half_float_vertex. */ + GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr)); + } + else + { + float x = float_16_to_32(((const unsigned short *)ptr) + 0); + float y = float_16_to_32(((const unsigned short *)ptr) + 1); + float z = float_16_to_32(((const unsigned short *)ptr) + 2); + float w = float_16_to_32(((const unsigned short *)ptr) + 3); + GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w)); + } + break; + default: + ERR("Unexpected declaration in stride 0 attributes.\n"); + break; + + } + context_gl->default_attrib_value_set &= ~(1u << i); + } + } + checkGLcall("Loading numbered arrays"); +} + +void wined3d_context_gl_update_stream_sources(struct wined3d_context_gl *context_gl, + const struct wined3d_state *state) +{ + if (context_gl->c.use_immediate_mode_draw) + return; + + wined3d_context_gl_unload_vertex_data(context_gl); + if (context_gl->c.d3d_info->ffp_generic_attributes || use_vs(state)) + { + TRACE("Loading numbered arrays.\n"); + wined3d_context_gl_load_numbered_arrays(context_gl, &context_gl->c.stream_info, state); + return; + } + + TRACE("Loading named arrays.\n"); + wined3d_context_gl_unload_numbered_arrays(context_gl); + wined3d_context_gl_load_vertex_data(context_gl, &context_gl->c.stream_info, state); + context_gl->c.namedArraysLoaded = TRUE; +} + +static void apply_texture_blit_state(const struct wined3d_gl_info *gl_info, struct gl_texture *texture, + GLenum target, unsigned int level, enum wined3d_texture_filter_type filter) +{ + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, level); + + /* We changed the filtering settings on the texture. Make sure they get + * reset on subsequent draws. */ + texture->sampler_desc.mag_filter = WINED3D_TEXF_POINT; + texture->sampler_desc.min_filter = WINED3D_TEXF_POINT; + texture->sampler_desc.mip_filter = WINED3D_TEXF_NONE; + texture->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP; + texture->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP; + texture->sampler_desc.srgb_decode = FALSE; + texture->base_level = level; +} + +/* Context activation is done by the caller. */ +void wined3d_context_gl_draw_shaded_quad(struct wined3d_context_gl *context_gl, struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect, + enum wined3d_texture_filter_type filter) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_blt_info info; + unsigned int level, w, h, i; + SIZE dst_size; + struct blit_vertex + { + float x, y; + struct wined3d_vec3 texcoord; + } + quad[4]; + + texture2d_get_blt_info(texture_gl, sub_resource_idx, src_rect, &info); + + level = sub_resource_idx % texture_gl->t.level_count; + wined3d_context_gl_bind_texture(context_gl, info.bind_target, texture_gl->texture_rgb.name); + apply_texture_blit_state(gl_info, &texture_gl->texture_rgb, info.bind_target, level, filter); + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level); + + wined3d_context_gl_get_rt_size(context_gl, &dst_size); + w = dst_size.cx; + h = dst_size.cy; + + quad[0].x = dst_rect->left * 2.0f / w - 1.0f; + quad[0].y = dst_rect->top * 2.0f / h - 1.0f; + quad[0].texcoord = info.texcoords[0]; + + quad[1].x = dst_rect->right * 2.0f / w - 1.0f; + quad[1].y = dst_rect->top * 2.0f / h - 1.0f; + quad[1].texcoord = info.texcoords[1]; + + quad[2].x = dst_rect->left * 2.0f / w - 1.0f; + quad[2].y = dst_rect->bottom * 2.0f / h - 1.0f; + quad[2].texcoord = info.texcoords[2]; + + quad[3].x = dst_rect->right * 2.0f / w - 1.0f; + quad[3].y = dst_rect->bottom * 2.0f / h - 1.0f; + quad[3].texcoord = info.texcoords[3]; + + /* Draw a quad. */ + if (gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) + { + if (!context_gl->blit_vbo) + GL_EXTCALL(glGenBuffers(1, &context_gl->blit_vbo)); + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, context_gl->blit_vbo)); + + wined3d_context_gl_unload_vertex_data(context_gl); + wined3d_context_gl_unload_numbered_arrays(context_gl); + + GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW)); + GL_EXTCALL(glVertexAttribPointer(0, 2, GL_FLOAT, FALSE, sizeof(*quad), NULL)); + GL_EXTCALL(glVertexAttribPointer(1, 3, GL_FLOAT, FALSE, sizeof(*quad), + (void *)FIELD_OFFSET(struct blit_vertex, texcoord))); + + GL_EXTCALL(glEnableVertexAttribArray(0)); + GL_EXTCALL(glEnableVertexAttribArray(1)); + + gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); + GL_EXTCALL(glDisableVertexAttribArray(1)); + GL_EXTCALL(glDisableVertexAttribArray(0)); + } + else + { + gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); + + for (i = 0; i < ARRAY_SIZE(quad); ++i) + { + GL_EXTCALL(glVertexAttrib3fv(1, &quad[i].texcoord.x)); + GL_EXTCALL(glVertexAttrib2fv(0, &quad[i].x)); + } + + gl_info->gl_ops.gl.p_glEnd(); + } + checkGLcall("draw"); + + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture_gl->t.level_count - 1); + wined3d_context_gl_bind_texture(context_gl, info.bind_target, 0); +} + +/* Context activation is done by the caller. */ +void wined3d_context_gl_draw_textured_quad(struct wined3d_context_gl *context_gl, + struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_blt_info info; + unsigned int level; + + texture2d_get_blt_info(texture_gl, sub_resource_idx, src_rect, &info); + + gl_info->gl_ops.gl.p_glEnable(info.bind_target); + checkGLcall("glEnable(bind_target)"); + + level = sub_resource_idx % texture_gl->t.level_count; + wined3d_context_gl_bind_texture(context_gl, info.bind_target, texture_gl->texture_rgb.name); + apply_texture_blit_state(gl_info, &texture_gl->texture_rgb, info.bind_target, level, filter); + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level); + gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + checkGLcall("glTexEnvi"); + + /* Draw a quad. */ + gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top); + + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top); + + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom); + + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); + gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom); + gl_info->gl_ops.gl.p_glEnd(); + + gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture_gl->t.level_count - 1); + wined3d_context_gl_bind_texture(context_gl, info.bind_target, 0); +} \ No newline at end of file diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c index 460fe12c7dc..52cd7733690 100644 --- a/dll/directx/wine/wined3d/cs.c +++ b/dll/directx/wine/wined3d/cs.c @@ -33,8 +33,8 @@ enum wined3d_cs_op WINED3D_CS_OP_DRAW, WINED3D_CS_OP_FLUSH, WINED3D_CS_OP_SET_PREDICATION, - WINED3D_CS_OP_SET_VIEWPORT, - WINED3D_CS_OP_SET_SCISSOR_RECT, + WINED3D_CS_OP_SET_VIEWPORTS, + WINED3D_CS_OP_SET_SCISSOR_RECTS, WINED3D_CS_OP_SET_RENDERTARGET_VIEW, WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, @@ -138,16 +138,18 @@ struct wined3d_cs_set_predication BOOL value; }; -struct wined3d_cs_set_viewport +struct wined3d_cs_set_viewports { enum wined3d_cs_op opcode; - struct wined3d_viewport viewport; + unsigned int viewport_count; + struct wined3d_viewport viewports[1]; }; -struct wined3d_cs_set_scissor_rect +struct wined3d_cs_set_scissor_rects { enum wined3d_cs_op opcode; - RECT rect; + unsigned int rect_count; + RECT rects[1]; }; struct wined3d_cs_set_rendertarget_view @@ -262,6 +264,7 @@ struct wined3d_cs_set_blend_state { enum wined3d_cs_op opcode; struct wined3d_blend_state *state; + struct wined3d_color factor; }; struct wined3d_cs_set_rasterizer_state @@ -444,6 +447,76 @@ struct wined3d_cs_stop enum wined3d_cs_op opcode; }; +static inline void *wined3d_cs_require_space(struct wined3d_cs *cs, + size_t size, enum wined3d_cs_queue_id queue_id) +{ + return cs->ops->require_space(cs, size, queue_id); +} + +static inline void wined3d_cs_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) +{ + cs->ops->submit(cs, queue_id); +} + +static const char *debug_cs_op(enum wined3d_cs_op op) +{ + switch (op) + { +#define WINED3D_TO_STR(type) case type: return #type + WINED3D_TO_STR(WINED3D_CS_OP_NOP); + WINED3D_TO_STR(WINED3D_CS_OP_PRESENT); + WINED3D_TO_STR(WINED3D_CS_OP_CLEAR); + WINED3D_TO_STR(WINED3D_CS_OP_DISPATCH); + WINED3D_TO_STR(WINED3D_CS_OP_DRAW); + WINED3D_TO_STR(WINED3D_CS_OP_FLUSH); + WINED3D_TO_STR(WINED3D_CS_OP_SET_PREDICATION); + WINED3D_TO_STR(WINED3D_CS_OP_SET_VIEWPORTS); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SCISSOR_RECTS); + WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); + WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ); + WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUT); + WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); + WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFER); + WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER); + WINED3D_TO_STR(WINED3D_CS_OP_SET_BLEND_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_RASTERIZER_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDER_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_TRANSFORM); + WINED3D_TO_STR(WINED3D_CS_OP_SET_CLIP_PLANE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_COLOR_KEY); + WINED3D_TO_STR(WINED3D_CS_OP_SET_MATERIAL); + WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT); + WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT_ENABLE); + WINED3D_TO_STR(WINED3D_CS_OP_PUSH_CONSTANTS); + WINED3D_TO_STR(WINED3D_CS_OP_RESET_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_CALLBACK); + WINED3D_TO_STR(WINED3D_CS_OP_QUERY_ISSUE); + WINED3D_TO_STR(WINED3D_CS_OP_PRELOAD_RESOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_UNLOAD_RESOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_MAP); + WINED3D_TO_STR(WINED3D_CS_OP_UNMAP); + WINED3D_TO_STR(WINED3D_CS_OP_BLT_SUB_RESOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_UPDATE_SUB_RESOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION); + WINED3D_TO_STR(WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_COPY_UAV_COUNTER); + WINED3D_TO_STR(WINED3D_CS_OP_GENERATE_MIPMAPS); + WINED3D_TO_STR(WINED3D_CS_OP_STOP); +#undef WINED3D_TO_STR + default: + return wine_dbg_sprintf("UNKNOWN_OP(%#x)", op); + } +} + static void wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) { } @@ -457,16 +530,10 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) swapchain = op->swapchain; wined3d_swapchain_set_window(swapchain, op->dst_window_override); - if (op->swap_interval && swapchain->desc.swap_interval != op->swap_interval) - { - swapchain->desc.swap_interval = op->swap_interval; - swapchain_update_swap_interval(swapchain); - } - - swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags); + swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->swap_interval, op->flags); wined3d_resource_release(&swapchain->front_buffer->resource); - for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + for (i = 0; i < swapchain->state.desc.backbuffer_count; ++i) { wined3d_resource_release(&swapchain->back_buffers[i]->resource); } @@ -476,13 +543,13 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - DWORD swap_interval, DWORD flags) + unsigned int swap_interval, DWORD flags) { struct wined3d_cs_present *op; unsigned int i; LONG pending; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_PRESENT; op->dst_window_override = dst_window_override; op->swapchain = swapchain; @@ -494,17 +561,16 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw pending = InterlockedIncrement(&cs->pending_presents); wined3d_resource_acquire(&swapchain->front_buffer->resource); - for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + for (i = 0; i < swapchain->state.desc.backbuffer_count; ++i) { wined3d_resource_acquire(&swapchain->back_buffers[i]->resource); } - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); /* Limit input latency by limiting the number of presents that we can get - * ahead of the worker thread. We have a constant limit here, but - * IDXGIDevice1 allows tuning this. */ - while (pending > 1) + * ahead of the worker thread. */ + while (pending >= swapchain->max_frame_latency) { wined3d_pause(); pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); @@ -536,39 +602,41 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers; const struct wined3d_state *state = &cs->device->state; - const struct wined3d_viewport *vp = &state->viewport; + const struct wined3d_viewport *vp = &state->viewports[0]; + struct wined3d_rendertarget_view *view; struct wined3d_cs_clear *op; - unsigned int i; + unsigned int rt_count, i; - op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]), + rt_count = flags & WINED3DCLEAR_TARGET ? cs->device->adapter->d3d_info.limits.max_rt_count : 0; + + op = wined3d_cs_require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_CLEAR; - op->flags = flags; + op->flags = flags & (WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); op->rt_count = rt_count; op->fb = &cs->fb; SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height); if (state->render_states[WINED3D_RS_SCISSORTESTENABLE]) - IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rect); + IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rects[0]); op->color = *color; op->depth = depth; op->stencil = stencil; op->rect_count = rect_count; memcpy(op->rects, rects, sizeof(*rects) * rect_count); - if (flags & WINED3DCLEAR_TARGET) + for (i = 0; i < rt_count; ++i) { - for (i = 0; i < rt_count; ++i) - { - if (state->fb->render_targets[i]) - wined3d_resource_acquire(state->fb->render_targets[i]->resource); - } + if ((view = state->fb->render_targets[i])) + wined3d_resource_acquire(view->resource); } if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - wined3d_resource_acquire(state->fb->depth_stencil->resource); + { + view = state->fb->depth_stencil; + wined3d_resource_acquire(view->resource); + } - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, @@ -578,11 +646,11 @@ void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined size_t size; size = FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(struct wined3d_fb_state); - op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT); op->fb = (void *)&op->rects[1]; op->opcode = WINED3D_CS_OP_CLEAR; - op->flags = flags; + op->flags = flags & (WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); if (flags & WINED3DCLEAR_TARGET) { op->rt_count = 1; @@ -604,7 +672,9 @@ void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined wined3d_resource_acquire(view->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); + if (flags & WINED3DCLEAR_SYNCHRONOUS) + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); } static void acquire_shader_resources(const struct wined3d_state *state, unsigned int shader_mask) @@ -741,7 +811,7 @@ void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, const struct wined3d_state *state = &cs->device->state; struct wined3d_cs_dispatch *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DISPATCH; op->parameters.indirect = FALSE; op->parameters.u.direct.group_count_x = group_count_x; @@ -750,7 +820,7 @@ void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, acquire_compute_pipeline_resources(state); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, @@ -759,7 +829,7 @@ void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, const struct wined3d_state *state = &cs->device->state; struct wined3d_cs_dispatch *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DISPATCH; op->parameters.indirect = TRUE; op->parameters.u.indirect.buffer = buffer; @@ -768,23 +838,43 @@ void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, acquire_compute_pipeline_resources(state); wined3d_resource_acquire(&buffer->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) { - const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; + const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; + const struct wined3d_shader *geometry_shader; + struct wined3d_device *device = cs->device; + int base_vertex_idx, load_base_vertex_idx; struct wined3d_state *state = &cs->state; const struct wined3d_cs_draw *op = data; - int load_base_vertex_idx; unsigned int i; + base_vertex_idx = 0; + if (!op->parameters.indirect) + { + const struct wined3d_direct_draw_parameters *direct = &op->parameters.u.direct; + + if (op->parameters.indexed && d3d_info->draw_base_vertex_offset) + base_vertex_idx = direct->base_vertex_idx; + else if (!op->parameters.indexed) + base_vertex_idx = direct->start_idx; + } + /* ARB_draw_indirect always supports a base vertex offset. */ - if (!op->parameters.indirect && !gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + if (!op->parameters.indirect && !d3d_info->draw_base_vertex_offset) load_base_vertex_idx = op->parameters.u.direct.base_vertex_idx; else load_base_vertex_idx = 0; + if (state->base_vertex_index != base_vertex_idx) + { + state->base_vertex_index = base_vertex_idx; + for (i = 0; i < device->context_count; ++i) + device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_BASE_VERTEX_ID; + } + if (state->load_base_vertex_index != load_base_vertex_idx) { state->load_base_vertex_index = load_base_vertex_idx; @@ -793,6 +883,8 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) if (state->gl_primitive_type != op->primitive_type) { + if ((geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) && !geometry_shader->function) + device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY)); if (state->gl_primitive_type == GL_POINTS || op->primitive_type == GL_POINTS) device_invalidate_state(cs->device, STATE_POINT_ENABLE); state->gl_primitive_type = op->primitive_type; @@ -824,7 +916,7 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) if (state->textures[i]) wined3d_resource_release(&state->textures[i]->resource); } - for (i = 0; i < gl_info->limits.buffers; ++i) + for (i = 0; i < d3d_info->limits.max_rt_count; ++i) { if (state->fb->render_targets[i]) wined3d_resource_release(state->fb->render_targets[i]->resource); @@ -837,7 +929,7 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) } static void acquire_graphics_pipeline_resources(const struct wined3d_state *state, - BOOL indexed, const struct wined3d_gl_info *gl_info) + BOOL indexed, const struct wined3d_d3d_info *d3d_info) { unsigned int i; @@ -858,7 +950,7 @@ static void acquire_graphics_pipeline_resources(const struct wined3d_state *stat if (state->textures[i]) wined3d_resource_acquire(&state->textures[i]->resource); } - for (i = 0; i < gl_info->limits.buffers; ++i) + for (i = 0; i < d3d_info->limits.max_rt_count; ++i) { if (state->fb->render_targets[i]) wined3d_resource_acquire(state->fb->render_targets[i]->resource); @@ -874,11 +966,11 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int base_vertex_idx, unsigned int start_idx, unsigned int index_count, unsigned int start_instance, unsigned int instance_count, BOOL indexed) { - const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; + const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; const struct wined3d_state *state = &cs->device->state; struct wined3d_cs_draw *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DRAW; op->primitive_type = primitive_type; op->patch_vertex_count = patch_vertex_count; @@ -890,19 +982,19 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned op->parameters.u.direct.instance_count = instance_count; op->parameters.indexed = indexed; - acquire_graphics_pipeline_resources(state, indexed, gl_info); + acquire_graphics_pipeline_resources(state, indexed, d3d_info); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count, struct wined3d_buffer *buffer, unsigned int offset, BOOL indexed) { - const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; + const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; const struct wined3d_state *state = &cs->device->state; struct wined3d_cs_draw *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DRAW; op->primitive_type = primitive_type; op->patch_vertex_count = patch_vertex_count; @@ -911,10 +1003,10 @@ void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type, op->parameters.u.indirect.offset = offset; op->parameters.indexed = indexed; - acquire_graphics_pipeline_resources(state, indexed, gl_info); + acquire_graphics_pipeline_resources(state, indexed, d3d_info); wined3d_resource_acquire(&buffer->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_flush(struct wined3d_cs *cs, const void *data) @@ -922,8 +1014,7 @@ static void wined3d_cs_exec_flush(struct wined3d_cs *cs, const void *data) struct wined3d_context *context; context = context_acquire(cs->device, NULL, 0); - if (context->valid) - context->gl_info->gl_ops.gl.p_glFlush(); + cs->device->adapter->adapter_ops->adapter_flush_context(context); context_release(context); } @@ -931,10 +1022,10 @@ void wined3d_cs_emit_flush(struct wined3d_cs *cs) { struct wined3d_cs_flush *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_FLUSH; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); cs->queries_flushed = TRUE; } @@ -950,58 +1041,79 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query { struct wined3d_cs_set_predication *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_PREDICATION; op->predicate = predicate; op->value = value; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_viewport *op = data; + const struct wined3d_cs_set_viewports *op = data; - cs->state.viewport = op->viewport; + if (op->viewport_count) + memcpy(cs->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports)); + else + memset(cs->state.viewports, 0, sizeof(*cs->state.viewports)); + cs->state.viewport_count = op->viewport_count; device_invalidate_state(cs->device, STATE_VIEWPORT); } -void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) +void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count, + const struct wined3d_viewport *viewports) { - struct wined3d_cs_set_viewport *op; + struct wined3d_cs_set_viewports *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_VIEWPORT; - op->viewport = *viewport; + op = wined3d_cs_require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_viewports, viewports[viewport_count]), + WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_VIEWPORTS; + memcpy(op->viewports, viewports, viewport_count * sizeof(*viewports)); + op->viewport_count = viewport_count; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_scissor_rects(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_scissor_rect *op = data; + const struct wined3d_cs_set_scissor_rects *op = data; - cs->state.scissor_rect = op->rect; + if (op->rect_count) + memcpy(cs->state.scissor_rects, op->rects, op->rect_count * sizeof(*op->rects)); + else + SetRectEmpty(cs->state.scissor_rects); + cs->state.scissor_rect_count = op->rect_count; device_invalidate_state(cs->device, STATE_SCISSORRECT); } -void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) +void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects) { - struct wined3d_cs_set_scissor_rect *op; + struct wined3d_cs_set_scissor_rects *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; - op->rect = *rect; + op = wined3d_cs_require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_scissor_rects, rects[rect_count]), + WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECTS; + memcpy(op->rects, rects, rect_count * sizeof(*rects)); + op->rect_count = rect_count; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_rendertarget_view *op = data; + BOOL prev_alpha_swizzle, curr_alpha_swizzle; + struct wined3d_rendertarget_view *prev; + prev = cs->state.fb->render_targets[op->view_idx]; cs->fb.render_targets[op->view_idx] = op->view; device_invalidate_state(cs->device, STATE_FRAMEBUFFER); + + prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; + curr_alpha_swizzle = op->view && op->view->format->id == WINED3DFMT_A8_UNORM; + if (prev_alpha_swizzle != curr_alpha_swizzle) + device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); } void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, @@ -1009,12 +1121,12 @@ void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int v { struct wined3d_cs_set_rendertarget_view *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; op->view_idx = view_idx; op->view = view; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) @@ -1023,16 +1135,14 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const struct wined3d_device *device = cs->device; struct wined3d_rendertarget_view *prev; - if ((prev = cs->state.fb->depth_stencil)) + if ((prev = cs->state.fb->depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER) { - struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); + struct wined3d_texture *prev_texture = texture_from_resource(prev->resource); - if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL - || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD)) - { - wined3d_texture_validate_location(prev_surface->container, + if (device->swapchains[0]->state.desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL + || prev_texture->flags & WINED3D_TEXTURE_DISCARD) + wined3d_texture_validate_location(prev_texture, prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED); - } } cs->fb.depth_stencil = op->view; @@ -1046,9 +1156,12 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIASCLAMP)); } - else if (prev && prev->format->depth_bias_scale != op->view->format->depth_bias_scale) + else if (prev) { - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + if (prev->format->depth_bias_scale != op->view->format->depth_bias_scale) + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + if (prev->format->stencil_size != op->view->format->stencil_size) + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILREF)); } device_invalidate_state(device, STATE_FRAMEBUFFER); @@ -1058,11 +1171,11 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3 { struct wined3d_cs_set_depth_stencil_view *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; op->view = view; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) @@ -1077,11 +1190,11 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3 { struct wined3d_cs_set_vertex_declaration *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; op->declaration = declaration; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) @@ -1109,14 +1222,14 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, { struct wined3d_cs_set_stream_source *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; op->stream_idx = stream_idx; op->buffer = buffer; op->offset = offset; op->stride = stride; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) @@ -1135,13 +1248,13 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i { struct wined3d_cs_set_stream_source_freq *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; op->stream_idx = stream_idx; op->frequency = frequency; op->flags = flags; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) @@ -1168,13 +1281,13 @@ void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, { struct wined3d_cs_set_stream_output *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; op->stream_idx = stream_idx; op->buffer = buffer; op->offset = offset; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) @@ -1200,13 +1313,13 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff { struct wined3d_cs_set_index_buffer *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; op->buffer = buffer; op->format_id = format_id; op->offset = offset; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) @@ -1230,18 +1343,17 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha { struct wined3d_cs_set_constant_buffer *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; op->type = type; op->cb_idx = cb_idx; op->buffer = buffer; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) { - const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; const struct wined3d_cs_set_texture *op = data; struct wined3d_texture *prev; @@ -1260,9 +1372,9 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) if (InterlockedIncrement(&op->texture->resource.bind_count) == 1) op->texture->sampler = op->stage; - if (!prev || op->texture->target != prev->target + if (!prev || wined3d_texture_gl(op->texture)->target != wined3d_texture_gl(prev)->target || (!is_same_fixup(new_format->color_fixup, old_format->color_fixup) - && !(can_use_texture_swizzle(gl_info, new_format) && can_use_texture_swizzle(gl_info, old_format))) + && !(can_use_texture_swizzle(d3d_info, new_format) && can_use_texture_swizzle(d3d_info, old_format))) || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW)) device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); @@ -1288,7 +1400,7 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) /* Search for other stages the texture is bound to. Shouldn't * happen if applications bind textures to a single stage only. */ TRACE("Searching for other stages the texture is bound to.\n"); - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { if (cs->state.textures[i] == prev) { @@ -1322,12 +1434,12 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined { struct wined3d_cs_set_texture *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_TEXTURE; op->stage = stage; op->texture = texture; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) @@ -1354,13 +1466,13 @@ void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3 { struct wined3d_cs_set_shader_resource_view *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; op->type = type; op->view_idx = view_idx; op->view = view; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, const void *data) @@ -1387,14 +1499,14 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined { struct wined3d_cs_set_unordered_access_view *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW; op->pipeline = pipeline; op->view_idx = view_idx; op->view = view; op->initial_count = initial_count; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) @@ -1413,13 +1525,13 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type { struct wined3d_cs_set_sampler *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SAMPLER; op->type = type; op->sampler_idx = sampler_idx; op->sampler = sampler; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) @@ -1438,31 +1550,39 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type { struct wined3d_cs_set_shader *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER; op->type = type; op->shader = shader; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_blend_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_blend_state *op = data; + struct wined3d_state *state = &cs->state; - cs->state.blend_state = op->state; - device_invalidate_state(cs->device, STATE_BLEND); + if (state->blend_state != op->state) + { + state->blend_state = op->state; + device_invalidate_state(cs->device, STATE_BLEND); + } + state->blend_factor = op->factor; + device_invalidate_state(cs->device, STATE_BLEND_FACTOR); } -void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) +void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state, + const struct wined3d_color *blend_factor) { struct wined3d_cs_set_blend_state *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_BLEND_STATE; op->state = state; + op->factor = *blend_factor; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data) @@ -1470,7 +1590,7 @@ static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const vo const struct wined3d_cs_set_rasterizer_state *op = data; cs->state.rasterizer_state = op->state; - device_invalidate_state(cs->device, STATE_FRONTFACE); + device_invalidate_state(cs->device, STATE_RASTERIZER); } void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, @@ -1478,11 +1598,11 @@ void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, { struct wined3d_cs_set_rasterizer_state *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_RASTERIZER_STATE; op->state = rasterizer_state; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) @@ -1497,12 +1617,12 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render { struct wined3d_cs_set_render_state *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_RENDER_STATE; op->state = state; op->value = value; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) @@ -1518,13 +1638,13 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, { struct wined3d_cs_set_texture_state *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE; op->stage = stage; op->state = state; op->value = value; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) @@ -1540,13 +1660,13 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, { struct wined3d_cs_set_sampler_state *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; op->sampler_idx = sampler_idx; op->state = state; op->value = value; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) @@ -1554,7 +1674,8 @@ static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *dat const struct wined3d_cs_set_transform *op = data; cs->state.transforms[op->state] = op->matrix; - if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) + if (op->state < WINED3D_TS_WORLD_MATRIX(max(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices, + cs->device->adapter->d3d_info.limits.ffp_max_vertex_blend_matrix_index + 1))) device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); } @@ -1563,12 +1684,12 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform { struct wined3d_cs_set_transform *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_TRANSFORM; op->state = state; op->matrix = *matrix; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) @@ -1583,12 +1704,12 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const { struct wined3d_cs_set_clip_plane *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; op->plane_idx = plane_idx; op->plane = *plane; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) @@ -1659,7 +1780,7 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture { struct wined3d_cs_set_color_key *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_COLOR_KEY; op->texture = texture; op->flags = flags; @@ -1671,7 +1792,7 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture else op->set = 0; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) @@ -1686,11 +1807,11 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma { struct wined3d_cs_set_material *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_MATERIAL; op->material = *material; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) @@ -1701,7 +1822,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) light_idx = op->light.OriginalIndex; - if (!(light_info = wined3d_state_get_light(&cs->state, light_idx))) + if (!(light_info = wined3d_light_state_get_light(&cs->state.light_state, light_idx))) { TRACE("Adding new light.\n"); if (!(light_info = heap_alloc_zero(sizeof(*light_info)))) @@ -1711,7 +1832,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) } hash_idx = LIGHTMAP_HASHFUNC(light_idx); - list_add_head(&cs->state.light_map[hash_idx], &light_info->entry); + list_add_head(&cs->state.light_state.light_map[hash_idx], &light_info->entry); light_info->glIndex = -1; light_info->OriginalIndex = light_idx; } @@ -1734,11 +1855,11 @@ void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light { struct wined3d_cs_set_light *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_LIGHT; op->light = *light; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) @@ -1748,14 +1869,14 @@ static void wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void * struct wined3d_light_info *light_info; int prev_idx; - if (!(light_info = wined3d_state_get_light(&cs->state, op->idx))) + if (!(light_info = wined3d_light_state_get_light(&cs->state.light_state, op->idx))) { ERR("Light doesn't exist.\n"); return; } prev_idx = light_info->glIndex; - wined3d_state_enable_light(&cs->state, &device->adapter->d3d_info, light_info, op->enable); + wined3d_light_state_enable_light(&cs->state.light_state, &device->adapter->d3d_info, light_info, op->enable); if (light_info->glIndex != prev_idx) { device_invalidate_state(device, STATE_LIGHT_TYPE); @@ -1767,12 +1888,12 @@ void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, unsigned int idx, B { struct wined3d_cs_set_light_enable *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_LIGHT_ENABLE; op->idx = idx; op->enable = enable; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static const struct @@ -1832,7 +1953,7 @@ static void wined3d_cs_mt_push_constants(struct wined3d_cs *cs, enum wined3d_pus size_t size; size = count * wined3d_cs_push_constant_info[p].size; - op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_push_constants, constants[size]), + op = wined3d_cs_require_space(cs, FIELD_OFFSET(struct wined3d_cs_push_constants, constants[size]), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_PUSH_CONSTANTS; op->type = p; @@ -1840,7 +1961,7 @@ static void wined3d_cs_mt_push_constants(struct wined3d_cs *cs, enum wined3d_pus op->count = count; memcpy(op->constants, constants, size); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) @@ -1849,18 +1970,17 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) state_cleanup(&cs->state); memset(&cs->state, 0, sizeof(cs->state)); - state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + state_init(&cs->state, &cs->fb, &adapter->d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); } void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) { struct wined3d_cs_reset_state *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_RESET_STATE; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_callback(struct wined3d_cs *cs, const void *data) @@ -1874,12 +1994,12 @@ static void wined3d_cs_emit_callback(struct wined3d_cs *cs, void (*callback)(voi { struct wined3d_cs_callback *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_CALLBACK; op->callback = callback; op->object = object; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } void wined3d_cs_destroy_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) @@ -1905,7 +2025,10 @@ static void wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) if (poll && list_empty(&query->poll_list_entry)) { - list_add_tail(&cs->query_poll_list, &query->poll_list_entry); + if (query->buffer_object) + InterlockedIncrement(&query->counter_retrieved); + else + list_add_tail(&cs->query_poll_list, &query->poll_list_entry); return; } @@ -1935,12 +2058,12 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu { struct wined3d_cs_query_issue *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_QUERY_ISSUE; op->query = query; op->flags = flags; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); cs->queries_flushed = FALSE; } @@ -1957,13 +2080,13 @@ void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_reso { struct wined3d_cs_preload_resource *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_PRELOAD_RESOURCE; op->resource = resource; wined3d_resource_acquire(resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_unload_resource(struct wined3d_cs *cs, const void *data) @@ -1979,13 +2102,13 @@ void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resou { struct wined3d_cs_unload_resource *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_UNLOAD_RESOURCE; op->resource = resource; wined3d_resource_acquire(resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_map(struct wined3d_cs *cs, const void *data) @@ -2007,7 +2130,7 @@ HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, * increasing the map count would be visible to applications. */ wined3d_not_from_cs(cs); - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); op->opcode = WINED3D_CS_OP_MAP; op->resource = resource; op->sub_resource_idx = sub_resource_idx; @@ -2016,8 +2139,8 @@ HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, op->flags = flags; op->hr = &hr; - cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); - cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_MAP); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_MAP); return hr; } @@ -2037,14 +2160,14 @@ HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resourc wined3d_not_from_cs(cs); - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); op->opcode = WINED3D_CS_OP_UNMAP; op->resource = resource; op->sub_resource_idx = sub_resource_idx; op->hr = &hr; - cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); - cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_MAP); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_MAP); return hr; } @@ -2059,23 +2182,6 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * buffer_from_resource(op->src_resource), op->src_box.left, op->src_box.right - op->src_box.left); } - else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D) - { - struct wined3d_surface *dst_surface, *src_surface; - struct wined3d_texture *dst_texture, *src_texture; - RECT dst_rect, src_rect; - - dst_texture = texture_from_resource(op->dst_resource); - src_texture = texture_from_resource(op->src_resource); - dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface; - src_surface = src_texture->sub_resources[op->src_sub_resource_idx].u.surface; - SetRect(&dst_rect, op->dst_box.left, op->dst_box.top, op->dst_box.right, op->dst_box.bottom); - SetRect(&src_rect, op->src_box.left, op->src_box.top, op->src_box.right, op->src_box.bottom); - - if (FAILED(wined3d_surface_blt(dst_surface, &dst_rect, src_surface, - &src_rect, op->flags, &op->fx, op->filter))) - FIXME("Blit failed.\n"); - } else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D) { struct wined3d_texture *src_texture, *dst_texture; @@ -2110,13 +2216,6 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * goto error; } - if (op->src_box.left || op->src_box.top || op->src_box.front) - { - FIXME("Source box %s not supported for %s resources.\n", - debug_box(&op->src_box), debug_d3dresourcetype(op->dst_resource->type)); - goto error; - } - dst_texture = texture_from_resource(op->dst_resource); src_texture = texture_from_resource(op->src_resource); @@ -2136,7 +2235,8 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * && update_h == wined3d_texture_get_level_height(dst_texture, level) && update_d == wined3d_texture_get_level_depth(dst_texture, level)) { - wined3d_texture_prepare_texture(dst_texture, context, FALSE); + wined3d_texture_prepare_location(dst_texture, op->dst_sub_resource_idx, + context, WINED3D_LOCATION_TEXTURE_RGB); } else if (!wined3d_texture_load_location(dst_texture, op->dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB)) @@ -2150,9 +2250,10 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * wined3d_texture_get_pitch(src_texture, op->src_sub_resource_idx % src_texture->level_count, &row_pitch, &slice_pitch); - wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context, &op->dst_box, - wined3d_const_bo_address(&addr), row_pitch, slice_pitch); + dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&addr), + dst_texture->resource.format, &op->src_box, row_pitch, slice_pitch, dst_texture, + op->dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, + op->dst_box.left, op->dst_box.top, op->dst_box.front); wined3d_texture_validate_location(dst_texture, op->dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_invalidate_location(dst_texture, op->dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); @@ -2160,7 +2261,10 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * } else { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type)); + if (FAILED(texture2d_blt(texture_from_resource(op->dst_resource), op->dst_sub_resource_idx, + &op->dst_box, texture_from_resource(op->src_resource), op->src_sub_resource_idx, + &op->src_box, op->flags, &op->fx, op->filter))) + FIXME("Blit failed.\n"); } error: @@ -2176,7 +2280,7 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso { struct wined3d_cs_blt_sub_resource *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_BLT_SUB_RESOURCE; op->dst_resource = dst_resource; op->dst_sub_resource_idx = dst_sub_resource_idx; @@ -2195,9 +2299,9 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso if (src_resource) wined3d_resource_acquire(src_resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); if (flags & WINED3D_BLT_SYNCHRONOUS) - cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data) @@ -2209,6 +2313,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi struct wined3d_const_bo_address addr; struct wined3d_context *context; struct wined3d_texture *texture; + struct wined3d_box src_box; context = context_acquire(cs->device, NULL, 0); @@ -2240,13 +2345,14 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi /* Only load the sub-resource for partial updates. */ if (!box->left && !box->top && !box->front && box->right == width && box->bottom == height && box->back == depth) - wined3d_texture_prepare_texture(texture, context, FALSE); + wined3d_texture_prepare_location(texture, op->sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); else wined3d_texture_load_location(texture, op->sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - wined3d_texture_upload_data(texture, op->sub_resource_idx, context, - box, &addr, op->data.row_pitch, op->data.slice_pitch); + wined3d_box_set(&src_box, 0, 0, box->right - box->left, box->bottom - box->top, 0, box->back - box->front); + texture->texture_ops->texture_upload_data(context, &addr, texture->resource.format, &src_box, + op->data.row_pitch, op->data.slice_pitch, texture, op->sub_resource_idx, + WINED3D_LOCATION_TEXTURE_RGB, box->left, box->top, box->front); wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); @@ -2310,7 +2416,7 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r wined3d_resource_wait_idle(resource); #endif /* STAGING_CSMT */ - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; op->resource = resource; op->sub_resource_idx = sub_resource_idx; @@ -2321,12 +2427,11 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r wined3d_resource_acquire(resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); -#if !defined(STAGING_CSMT) + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_MAP); + /* The data pointer may go away, so we need to wait until it is read. * Copying the data may be faster if it's small. */ -#endif /* STAGING_CSMT */ - cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_MAP); } static void wined3d_cs_exec_add_dirty_texture_region(struct wined3d_cs *cs, const void *data) @@ -2355,14 +2460,14 @@ void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs, { struct wined3d_cs_add_dirty_texture_region *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION; op->texture = texture; op->layer = layer; wined3d_resource_acquire(&texture->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_clear_unordered_access_view(struct wined3d_cs *cs, const void *data) @@ -2372,7 +2477,7 @@ static void wined3d_cs_exec_clear_unordered_access_view(struct wined3d_cs *cs, c struct wined3d_context *context; context = context_acquire(cs->device, NULL, 0); - wined3d_unordered_access_view_clear_uint(view, &op->clear_value, context); + cs->device->adapter->adapter_ops->adapter_clear_uav(context, view, &op->clear_value); context_release(context); wined3d_resource_release(view->resource); @@ -2383,14 +2488,14 @@ void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs, { struct wined3d_cs_clear_unordered_access_view *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW; op->view = view; op->clear_value = *clear_value; wined3d_resource_acquire(view->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void *data) @@ -2412,7 +2517,7 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff { struct wined3d_cs_copy_uav_counter *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_COPY_UAV_COUNTER; op->buffer = dst_buffer; op->offset = offset; @@ -2421,7 +2526,7 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff wined3d_resource_acquire(&dst_buffer->resource); wined3d_resource_acquire(uav->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_generate_mipmaps(struct wined3d_cs *cs, const void *data) @@ -2437,24 +2542,24 @@ void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shad { struct wined3d_cs_generate_mipmaps *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_GENERATE_MIPMAPS; op->view = view; wined3d_resource_acquire(view->resource); - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_emit_stop(struct wined3d_cs *cs) { struct wined3d_cs_stop *op; - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_STOP; - cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); - cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); } static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = @@ -2466,8 +2571,8 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, /* WINED3D_CS_OP_FLUSH */ wined3d_cs_exec_flush, /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, - /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, - /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, + /* WINED3D_CS_OP_SET_VIEWPORTS */ wined3d_cs_exec_set_viewports, + /* WINED3D_CS_OP_SET_SCISSOR_RECTS */ wined3d_cs_exec_set_scissor_rects, /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, @@ -2804,6 +2909,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx) { opcode = *(const enum wined3d_cs_op *)packet->data; + TRACE("Executing %s.\n", debug_cs_op(opcode)); if (opcode >= WINED3D_CS_OP_STOP) { if (opcode > WINED3D_CS_OP_STOP) @@ -2812,6 +2918,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx) } wined3d_cs_op_handlers[opcode](cs, packet->data); + TRACE("%s executed.\n", debug_cs_op(opcode)); } tail += FIELD_OFFSET(struct wined3d_cs_packet, data[packet->size]); @@ -2827,7 +2934,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx) struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_cs *cs; if (!(cs = heap_alloc_zero(sizeof(*cs)))) @@ -2836,8 +2943,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) cs->ops = &wined3d_cs_st_ops; cs->device = device; - state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + state_init(&cs->state, &cs->fb, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); cs->data_size = WINED3D_INITIAL_CS_SIZE; if (!(cs->data = heap_alloc(cs->data_size))) diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c index e2b27e0cf43..77f2f709485 100644 --- a/dll/directx/wine/wined3d/device.c +++ b/dll/directx/wine/wined3d/device.c @@ -37,6 +37,44 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(winediag); +struct wined3d_matrix_3x3 +{ + float _11, _12, _13; + float _21, _22, _23; + float _31, _32, _33; +}; + +struct light_transformed +{ + struct wined3d_color diffuse, specular, ambient; + struct wined3d_vec4 position; + struct wined3d_vec3 direction; + float range, falloff, c_att, l_att, q_att, cos_htheta, cos_hphi; +}; + +struct lights_settings +{ + struct light_transformed lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; + struct wined3d_color ambient_light; + struct wined3d_matrix modelview_matrix; + struct wined3d_matrix_3x3 normal_matrix; + struct wined3d_vec4 position_transformed; + + float fog_start, fog_end, fog_density; + + uint32_t point_light_count : 8; + uint32_t spot_light_count : 8; + uint32_t directional_light_count : 8; + uint32_t parallel_point_light_count : 8; + uint32_t lighting : 1; + uint32_t legacy_lighting : 1; + uint32_t normalise : 1; + uint32_t localviewer : 1; + uint32_t fog_coord_mode : 2; + uint32_t fog_mode : 2; + uint32_t padding : 24; +}; + /* Define the default light parameters as specified by MSDN. */ const struct wined3d_light WINED3D_default_light = { @@ -99,7 +137,7 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) } } -static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) +enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) { switch (primitive_type) { @@ -149,14 +187,31 @@ BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *c TRACE("Adding context %p.\n", context); + if (!device->shader_backend->shader_allocate_context_data(context)) + { + ERR("Failed to allocate shader backend context data.\n"); + return FALSE; + } + device->shader_backend->shader_init_context_state(context); + + if (!device->adapter->fragment_pipe->allocate_context_data(context)) + { + ERR("Failed to allocate fragment pipeline context data.\n"); + device->shader_backend->shader_free_context_data(context); + return FALSE; + } + if (!(new_array = heap_realloc(device->contexts, sizeof(*new_array) * (device->context_count + 1)))) { ERR("Failed to grow the context array.\n"); + device->adapter->fragment_pipe->free_context_data(context); + device->shader_backend->shader_free_context_data(context); return FALSE; } new_array[device->context_count++] = context; device->contexts = new_array; + return TRUE; } @@ -168,6 +223,9 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context TRACE("Removing context %p.\n", context); + device->adapter->fragment_pipe->free_context_data(context); + device->shader_backend->shader_free_context_data(context); + for (i = 0; i < device->context_count; ++i) { if (device->contexts[i] == context) @@ -226,29 +284,40 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c float depth, DWORD stencil) { struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL; - struct wined3d_surface *target = rtv ? wined3d_rendertarget_view_get_surface(rtv) : NULL; struct wined3d_rendertarget_view *dsv = fb->depth_stencil; - struct wined3d_surface *depth_stencil = dsv ? wined3d_rendertarget_view_get_surface(dsv) : NULL; const struct wined3d_state *state = &device->cs->state; + struct wined3d_texture *depth_stencil = NULL; const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; + struct wined3d_texture *target = NULL; UINT drawable_width, drawable_height; - struct wined3d_color corrected_color; + struct wined3d_color colour_srgb; struct wined3d_context *context; GLbitfield clear_mask = 0; BOOL render_offscreen; unsigned int i; - if (target) - context = context_acquire(device, target->container, rtv->sub_resource_idx); + if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER) + { + target = texture_from_resource(rtv->resource); + context = context_acquire(device, target, rtv->sub_resource_idx); + } else + { context = context_acquire(device, NULL, 0); - if (!context->valid) + } + context_gl = wined3d_context_gl(context); + + if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER) + depth_stencil = texture_from_resource(dsv->resource); + + if (!context_gl->valid) { context_release(context); WARN("Invalid context, skipping clear.\n"); return; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true @@ -281,11 +350,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c } else { - unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->container->level_count; + unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->level_count; render_offscreen = TRUE; - drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container, ds_level); - drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container, ds_level); + drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level); + drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil, ds_level); } if (depth_stencil) @@ -306,7 +375,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c } } - if (!context_apply_clear_state(context, state, rt_count, fb)) + if (!wined3d_context_gl_apply_clear_state(context_gl, state, rt_count, fb)) { context_release(context); WARN("Failed to apply clear state, skipping clear.\n"); @@ -361,25 +430,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, fb)) { if (rt_count > 1) - WARN("Clearing multiple sRGB render targets with no GL_ARB_framebuffer_sRGB " + WARN("Clearing multiple sRGB render targets without GL_ARB_framebuffer_sRGB " "support, this might cause graphical issues.\n"); - corrected_color.r = color->r < wined3d_srgb_const1[0] - ? color->r * wined3d_srgb_const0[3] - : pow(color->r, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1] - - wined3d_srgb_const0[2]; - corrected_color.r = min(max(corrected_color.r, 0.0f), 1.0f); - corrected_color.g = color->g < wined3d_srgb_const1[0] - ? color->g * wined3d_srgb_const0[3] - : pow(color->g, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1] - - wined3d_srgb_const0[2]; - corrected_color.g = min(max(corrected_color.g, 0.0f), 1.0f); - corrected_color.b = color->b < wined3d_srgb_const1[0] - ? color->b * wined3d_srgb_const0[3] - : pow(color->b, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1] - - wined3d_srgb_const0[2]; - corrected_color.b = min(max(corrected_color.b, 0.0f), 1.0f); - color = &corrected_color; + wined3d_colour_srgb_from_linear(&colour_srgb, color); + color = &colour_srgb; } gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -402,9 +457,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom, draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top); } - checkGLcall("glScissor"); gl_info->gl_ops.gl.p_glClear(clear_mask); - checkGLcall("glClear"); } else { @@ -439,16 +492,14 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom, current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); } - checkGLcall("glScissor"); - gl_info->gl_ops.gl.p_glClear(clear_mask); - checkGLcall("glClear"); } } + context->scissor_rect_count = WINED3D_MAX_VIEWPORTS; + checkGLcall("clear"); - if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET - && target->container->swapchain && target->container->swapchain->front_buffer == target->container)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + if (flags & WINED3DCLEAR_TARGET && target->swapchain && target->swapchain->front_buffer == target) + gl_info->gl_ops.gl.p_glFlush(); context_release(context); } @@ -469,55 +520,62 @@ static void device_leftover_sampler(struct wine_rb_entry *entry, void *context) ERR("Leftover sampler %p.\n", sampler); } -ULONG CDECL wined3d_device_decref(struct wined3d_device *device) +void wined3d_device_cleanup(struct wined3d_device *device) { - ULONG refcount = InterlockedDecrement(&device->ref); + unsigned int i; - TRACE("%p decreasing refcount to %u.\n", device, refcount); + if (device->swapchain_count) + wined3d_device_uninit_3d(device); - if (!refcount) - { - UINT i; + wined3d_stateblock_state_cleanup(&device->stateblock_state); - wined3d_cs_destroy(device->cs); + wined3d_cs_destroy(device->cs); - if (device->recording && wined3d_stateblock_decref(device->recording)) - ERR("Something's still holding the recording stateblock.\n"); - device->recording = NULL; + if (device->recording && wined3d_stateblock_decref(device->recording)) + ERR("Something's still holding the recording stateblock.\n"); + device->recording = NULL; - state_cleanup(&device->state); + for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i) + { + heap_free(device->multistate_funcs[i]); + device->multistate_funcs[i] = NULL; + } + + if (!list_empty(&device->resources)) + { + struct wined3d_resource *resource; + + ERR("Device released with resources still bound.\n"); - for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i) + LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry) { - heap_free(device->multistate_funcs[i]); - device->multistate_funcs[i] = NULL; + ERR("Leftover resource %p with type %s (%#x).\n", + resource, debug_d3dresourcetype(resource->type), resource->type); } + } - if (!list_empty(&device->resources)) - { - struct wined3d_resource *resource; + if (device->contexts) + ERR("Context array not freed!\n"); + if (device->hardwareCursor) + DestroyCursor(device->hardwareCursor); + device->hardwareCursor = 0; - ERR("Device released with resources still bound.\n"); + wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL); - LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry) - { - ERR("Leftover resource %p with type %s (%#x).\n", - resource, debug_d3dresourcetype(resource->type), resource->type); - } - } + wined3d_decref(device->wined3d); + device->wined3d = NULL; +} - if (device->contexts) - ERR("Context array not freed!\n"); - if (device->hardwareCursor) - DestroyCursor(device->hardwareCursor); - device->hardwareCursor = 0; +ULONG CDECL wined3d_device_decref(struct wined3d_device *device) +{ + ULONG refcount = InterlockedDecrement(&device->ref); - wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL); + TRACE("%p decreasing refcount to %u.\n", device, refcount); - wined3d_decref(device->wined3d); - device->wined3d = NULL; - heap_free(device); - TRACE("Freed device %p.\n", device); + if (!refcount) + { + device->adapter->adapter_ops->adapter_destroy_device(device); + TRACE("Destroyed device %p.\n", device); } return refcount; @@ -569,13 +627,13 @@ static void device_load_logo(struct wined3d_device *device, const char *filename desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = WINED3DUSAGE_DYNAMIC; + desc.bind_flags = 0; desc.access = WINED3D_RESOURCE_ACCESS_GPU; desc.width = bm.bmWidth; desc.height = bm.bmHeight; desc.depth = 1; desc.size = 0; - if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, - WINED3D_TEXTURE_CREATE_MAPPABLE | WINED3D_TEXTURE_CREATE_GET_DC, + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, WINED3D_TEXTURE_CREATE_GET_DC, NULL, NULL, &wined3d_null_parent_ops, &device->logo_texture))) { ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr); @@ -601,11 +659,12 @@ static void device_load_logo(struct wined3d_device *device, const char *filename } /* Context activation is done by the caller. */ -static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) +static void wined3d_device_gl_create_dummy_textures(struct wined3d_device_gl *device_gl, + struct wined3d_context_gl *context_gl) { - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_dummy_textures *textures = &device->dummy_textures; + struct wined3d_dummy_textures *textures = &device_gl->dummy_textures; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int i; DWORD color; @@ -618,7 +677,7 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ * OpenGL will only allow that when a valid texture is bound. * We emulate this by creating dummy textures and binding them * to each texture stage when the currently set D3D texture is NULL. */ - context_active_texture(context, gl_info, 0); + wined3d_context_gl_active_texture(context_gl, gl_info, 0); gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d); TRACE("Dummy 1D texture given name %u.\n", textures->tex_1d); @@ -732,14 +791,15 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ checkGLcall("create dummy textures"); - context_bind_dummy_textures(device, context); + wined3d_context_gl_bind_dummy_textures(context_gl); } /* Context activation is done by the caller. */ -static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) +static void wined3d_device_gl_destroy_dummy_textures(struct wined3d_device_gl *device_gl, + struct wined3d_context_gl *context_gl) { - struct wined3d_dummy_textures *dummy_textures = &device->dummy_textures; - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_dummy_textures *dummy_textures = &device_gl->dummy_textures; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) { @@ -777,7 +837,7 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d } /* Context activation is done by the caller. */ -static void create_default_samplers(struct wined3d_device *device, struct wined3d_context *context) +void wined3d_device_create_default_samplers(struct wined3d_device *device, struct wined3d_context *context) { struct wined3d_sampler_desc desc; HRESULT hr; @@ -825,7 +885,7 @@ static void create_default_samplers(struct wined3d_device *device, struct wined3 } /* Context activation is done by the caller. */ -static void destroy_default_samplers(struct wined3d_device *device, struct wined3d_context *context) +void wined3d_device_destroy_default_samplers(struct wined3d_device *device, struct wined3d_context *context) { wined3d_sampler_decref(device->default_sampler); device->default_sampler = NULL; @@ -833,113 +893,13 @@ static void destroy_default_samplers(struct wined3d_device *device, struct wined device->null_sampler = NULL; } -static LONG fullscreen_style(LONG style) -{ - /* Make sure the window is managed, otherwise we won't get keyboard input. */ - style |= WS_POPUP | WS_SYSMENU; - style &= ~(WS_CAPTION | WS_THICKFRAME); - - return style; -} - -static LONG fullscreen_exstyle(LONG exstyle) -{ - /* Filter out window decorations. */ - exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); - - return exstyle; -} - -void CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, UINT w, UINT h) -{ - BOOL filter_messages; - LONG style, exstyle; - - TRACE("Setting up window %p for fullscreen mode.\n", window); - - if (device->style || device->exStyle) - { - ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", - window, device->style, device->exStyle); - } - - device->style = GetWindowLongW(window, GWL_STYLE); - device->exStyle = GetWindowLongW(window, GWL_EXSTYLE); - - style = fullscreen_style(device->style); - exstyle = fullscreen_exstyle(device->exStyle); - - TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", - device->style, device->exStyle, style, exstyle); - - filter_messages = device->filter_messages; - device->filter_messages = TRUE; - - SetWindowLongW(window, GWL_STYLE, style); - SetWindowLongW(window, GWL_EXSTYLE, exstyle); - SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); - - device->filter_messages = filter_messages; -} - -void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, - const RECT *window_rect) -{ - unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE; - BOOL filter_messages; - LONG style, exstyle; - RECT rect = {0}; - - if (!device->style && !device->exStyle) - return; - - style = GetWindowLongW(window, GWL_STYLE); - exstyle = GetWindowLongW(window, GWL_EXSTYLE); - - /* These flags are set by wined3d_device_setup_fullscreen_window, not the - * application, and we want to ignore them in the test below, since it's - * not the application's fault that they changed. Additionally, we want to - * preserve the current status of these flags (i.e. don't restore them) to - * more closely emulate the behavior of Direct3D, which leaves these flags - * alone when returning to windowed mode. */ - device->style ^= (device->style ^ style) & WS_VISIBLE; - device->exStyle ^= (device->exStyle ^ exstyle) & WS_EX_TOPMOST; - - TRACE("Restoring window style of window %p to %08x, %08x.\n", - window, device->style, device->exStyle); - - filter_messages = device->filter_messages; - device->filter_messages = TRUE; - - /* Only restore the style if the application didn't modify it during the - * fullscreen phase. Some applications change it before calling Reset() - * when switching between windowed and fullscreen modes (HL2), some - * depend on the original style (Eve Online). */ - if (style == fullscreen_style(device->style) && exstyle == fullscreen_exstyle(device->exStyle)) - { - SetWindowLongW(window, GWL_STYLE, device->style); - SetWindowLongW(window, GWL_EXSTYLE, device->exStyle); - } - - if (window_rect) - rect = *window_rect; - else - window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(window, 0, rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); - - device->filter_messages = filter_messages; - - /* Delete the old values. */ - device->style = 0; - device->exStyle = 0; -} - HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window) { + unsigned int screensaver_active; + TRACE("device %p, window %p.\n", device, window); - if (!wined3d_register_window(window, device)) + if (!wined3d_register_window(NULL, window, device, 0)) { ERR("Failed to register window %p.\n", window); return E_FAIL; @@ -947,6 +907,9 @@ HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, InterlockedExchangePointer((void **)&device->focus_window, window); SetWindowPos(window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SystemParametersInfoW(SPI_GETSCREENSAVEACTIVE, 0, &screensaver_active, 0); + if ((device->restore_screensaver = !!screensaver_active)) + SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0); return WINED3D_OK; } @@ -957,14 +920,19 @@ void CDECL wined3d_device_release_focus_window(struct wined3d_device *device) if (device->focus_window) wined3d_unregister_window(device->focus_window); InterlockedExchangePointer((void **)&device->focus_window, NULL); + if (device->restore_screensaver) + { + SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, TRUE, NULL, 0); + device->restore_screensaver = FALSE; + } } static void device_init_swapchain_state(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { - BOOL ds_enable = swapchain->desc.enable_auto_depth_stencil; + BOOL ds_enable = swapchain->state.desc.enable_auto_depth_stencil; unsigned int i; - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) { wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); } @@ -974,13 +942,18 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi wined3d_device_set_depth_stencil_view(device, ds_enable ? device->auto_depth_stencil_view : NULL); } -static void wined3d_device_delete_opengl_contexts_cs(void *object) +void wined3d_device_delete_opengl_contexts_cs(void *object) { struct wined3d_resource *resource, *cursor; + struct wined3d_swapchain_gl *swapchain_gl; struct wined3d_device *device = object; + struct wined3d_context_gl *context_gl; + struct wined3d_device_gl *device_gl; struct wined3d_context *context; struct wined3d_shader *shader; + device_gl = wined3d_device_gl(device); + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) { TRACE("Unloading resource %p.\n", resource); @@ -993,98 +966,80 @@ static void wined3d_device_delete_opengl_contexts_cs(void *object) } context = context_acquire(device, NULL, 0); + context_gl = wined3d_context_gl(context); device->blitter->ops->blitter_destroy(device->blitter, context); - device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, context); - destroy_default_samplers(device, context); + device->shader_backend->shader_free_private(device, context); + wined3d_device_gl_destroy_dummy_textures(device_gl, context_gl); + wined3d_device_destroy_default_samplers(device, context); context_release(context); while (device->context_count) { - if (device->contexts[0]->swapchain) - swapchain_destroy_contexts(device->contexts[0]->swapchain); + if ((swapchain_gl = wined3d_swapchain_gl(device->contexts[0]->swapchain))) + wined3d_swapchain_gl_destroy_contexts(swapchain_gl); else - context_destroy(device, device->contexts[0]); + wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); } } -static void wined3d_device_delete_opengl_contexts(struct wined3d_device *device) -{ - wined3d_cs_destroy_object(device->cs, wined3d_device_delete_opengl_contexts_cs, device); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); -} - -static void wined3d_device_create_primary_opengl_context_cs(void *object) +void wined3d_device_create_primary_opengl_context_cs(void *object) { struct wined3d_device *device = object; + struct wined3d_context_gl *context_gl; struct wined3d_swapchain *swapchain; struct wined3d_context *context; struct wined3d_texture *target; HRESULT hr; + swapchain = device->swapchains[0]; + target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer; + if (!(context = context_acquire(device, target, 0))) + { + WARN("Failed to acquire context.\n"); + return; + } + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, device->adapter->vertex_pipe, device->adapter->fragment_pipe))) { ERR("Failed to allocate shader private data, hr %#x.\n", hr); + context_release(context); return; } if (!(device->blitter = wined3d_cpu_blitter_create())) { ERR("Failed to create CPU blitter.\n"); - device->shader_backend->shader_free_private(device); + device->shader_backend->shader_free_private(device, NULL); + context_release(context); return; } wined3d_ffp_blitter_create(&device->blitter, &device->adapter->gl_info); - wined3d_arbfp_blitter_create(&device->blitter, device); + if (!wined3d_glsl_blitter_create(&device->blitter, device)) + wined3d_arbfp_blitter_create(&device->blitter, device); wined3d_fbo_blitter_create(&device->blitter, &device->adapter->gl_info); wined3d_raw_blitter_create(&device->blitter, &device->adapter->gl_info); - swapchain = device->swapchains[0]; - target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer; - context = context_acquire(device, target, 0); - create_dummy_textures(device, context); - create_default_samplers(device, context); + context_gl = wined3d_context_gl(context); + wined3d_device_gl_create_dummy_textures(wined3d_device_gl(device), context_gl); + wined3d_device_create_default_samplers(device, context); context_release(context); } -static HRESULT wined3d_device_create_primary_opengl_context(struct wined3d_device *device) -{ - wined3d_cs_init_object(device->cs, wined3d_device_create_primary_opengl_context_cs, device); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (!device->swapchains[0]->num_contexts) - return E_FAIL; - - return WINED3D_OK; -} - -HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - struct wined3d_swapchain_desc *swapchain_desc) +HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; - struct wined3d_swapchain *swapchain = NULL; + const struct wined3d_swapchain_desc *swapchain_desc; DWORD clear_flags = 0; HRESULT hr; - TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc); + TRACE("device %p, swapchain %p.\n", device, swapchain); if (device->d3d_initialized) return WINED3DERR_INVALIDCALL; - if (device->wined3d->flags & WINED3D_NO3D) - return WINED3DERR_INVALIDCALL; - - memset(device->fb.render_targets, 0, sizeof(device->fb.render_targets)); - - /* Setup the implicit swapchain. This also initializes a context. */ - TRACE("Creating implicit swapchain.\n"); - if (FAILED(hr = device->device_parent->ops->create_swapchain(device->device_parent, - swapchain_desc, &swapchain))) - { - WARN("Failed to create implicit swapchain.\n"); - goto err_out; - } - if (swapchain_desc->backbuffer_count) + swapchain_desc = &swapchain->state.desc; + if (swapchain_desc->backbuffer_count && swapchain_desc->backbuffer_bind_flags & WINED3D_BIND_RENDER_TARGET) { struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; struct wined3d_view_desc view_desc; @@ -1099,89 +1054,50 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); - goto err_out; + return hr; } } device->swapchain_count = 1; if (!(device->swapchains = heap_calloc(device->swapchain_count, sizeof(*device->swapchains)))) { - ERR("Out of memory!\n"); + ERR("Failed to allocate swapchain array.\n"); + hr = E_OUTOFMEMORY; goto err_out; } device->swapchains[0] = swapchain; - if (FAILED(hr = wined3d_device_create_primary_opengl_context(device))) + memset(device->fb.render_targets, 0, sizeof(device->fb.render_targets)); + if (FAILED(hr = device->adapter->adapter_ops->adapter_init_3d(device))) goto err_out; - device_init_swapchain_state(device, swapchain); - device->contexts[0]->last_was_rhw = 0; + device_init_swapchain_state(device, swapchain); TRACE("All defaults now set up.\n"); - /* Clear the screen */ - if (swapchain->back_buffers && swapchain->back_buffers[0]) + /* Clear the screen. */ + if (device->back_buffer_view) clear_flags |= WINED3DCLEAR_TARGET; if (swapchain_desc->enable_auto_depth_stencil) clear_flags |= WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL; if (clear_flags) wined3d_device_clear(device, 0, NULL, clear_flags, &black, 1.0f, 0); - device->d3d_initialized = TRUE; - if (wined3d_settings.logo) device_load_logo(device, wined3d_settings.logo); + return WINED3D_OK; err_out: heap_free(device->swapchains); + device->swapchains = NULL; device->swapchain_count = 0; if (device->back_buffer_view) - wined3d_rendertarget_view_decref(device->back_buffer_view); - if (swapchain) - wined3d_swapchain_decref(swapchain); - - return hr; -} - -HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device, - struct wined3d_swapchain_desc *swapchain_desc) -{ - struct wined3d_swapchain *swapchain = NULL; - HRESULT hr; - - TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc); - - /* Setup the implicit swapchain */ - TRACE("Creating implicit swapchain\n"); - hr = device->device_parent->ops->create_swapchain(device->device_parent, - swapchain_desc, &swapchain); - if (FAILED(hr)) - { - WARN("Failed to create implicit swapchain\n"); - goto err_out; - } - - device->swapchain_count = 1; - if (!(device->swapchains = heap_calloc(device->swapchain_count, sizeof(*device->swapchains)))) { - ERR("Out of memory!\n"); - goto err_out; - } - device->swapchains[0] = swapchain; - - if (!(device->blitter = wined3d_cpu_blitter_create())) - { - ERR("Failed to create CPU blitter.\n"); - heap_free(device->swapchains); - device->swapchain_count = 0; - goto err_out; + wined3d_rendertarget_view_decref(device->back_buffer_view); + device->back_buffer_view = NULL; } - return WINED3D_OK; - -err_out: - wined3d_swapchain_decref(swapchain); return hr; } @@ -1192,93 +1108,76 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context) wined3d_sampler_decref(sampler); } -HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) +void wined3d_device_uninit_3d(struct wined3d_device *device) { + BOOL no3d = device->wined3d->flags & WINED3D_NO3D; + struct wined3d_rendertarget_view *view; + struct wined3d_texture *texture; unsigned int i; TRACE("device %p.\n", device); - if (!device->d3d_initialized) - return WINED3DERR_INVALIDCALL; + if (!device->d3d_initialized && !no3d) + { + ERR("Called while 3D support was not initialised.\n"); + return; + } - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (device->logo_texture) - wined3d_texture_decref(device->logo_texture); - if (device->cursor_texture) - wined3d_texture_decref(device->cursor_texture); + device->swapchain_count = 0; + + if ((texture = device->logo_texture)) + { + device->logo_texture = NULL; + wined3d_texture_decref(texture); + } + + if ((texture = device->cursor_texture)) + { + device->cursor_texture = NULL; + wined3d_texture_decref(texture); + } - state_unbind_resources(&device->state); + wined3d_cs_emit_reset_state(device->cs); + state_cleanup(&device->state); + for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) + { + wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); + } wine_rb_clear(&device->samplers, device_free_sampler, NULL); #if defined(STAGING_CSMT) context_set_current(NULL); #endif /* STAGING_CSMT */ - wined3d_device_delete_opengl_contexts(device); + device->adapter->adapter_ops->adapter_uninit_3d(device); - if (device->fb.depth_stencil) + if ((view = device->fb.depth_stencil)) { - struct wined3d_rendertarget_view *view = device->fb.depth_stencil; - TRACE("Releasing depth/stencil view %p.\n", view); device->fb.depth_stencil = NULL; wined3d_rendertarget_view_decref(view); } - if (device->auto_depth_stencil_view) + if ((view = device->auto_depth_stencil_view)) { - struct wined3d_rendertarget_view *view = device->auto_depth_stencil_view; - device->auto_depth_stencil_view = NULL; if (wined3d_rendertarget_view_decref(view)) ERR("Something's still holding the auto depth/stencil view (%p).\n", view); } - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { - wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); - } - if (device->back_buffer_view) + if ((view = device->back_buffer_view)) { - wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; - } - - for (i = 0; i < device->swapchain_count; ++i) - { - TRACE("Releasing the implicit swapchain %u.\n", i); - if (wined3d_swapchain_decref(device->swapchains[i])) - FIXME("Something's still holding the implicit swapchain.\n"); + wined3d_rendertarget_view_decref(view); } heap_free(device->swapchains); device->swapchains = NULL; - device->swapchain_count = 0; device->d3d_initialized = FALSE; - - return WINED3D_OK; -} - -HRESULT CDECL wined3d_device_uninit_gdi(struct wined3d_device *device) -{ - unsigned int i; - - device->blitter->ops->blitter_destroy(device->blitter, NULL); - - for (i = 0; i < device->swapchain_count; ++i) - { - TRACE("Releasing the implicit swapchain %u.\n", i); - if (wined3d_swapchain_decref(device->swapchains[i])) - FIXME("Something's still holding the implicit swapchain.\n"); - } - - heap_free(device->swapchains); - device->swapchains = NULL; - device->swapchain_count = 0; - return WINED3D_OK; } /* Enables thread safety in the wined3d device and its resources. Called by DirectDraw @@ -1297,10 +1196,12 @@ void CDECL wined3d_device_set_multithreaded(struct wined3d_device *device) UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device *device) { - /* const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; */ + const struct wined3d_driver_info *driver_info; TRACE("device %p.\n", device); + driver_info = &device->adapter->driver_info; + /* We can not acquire the context unless there is a swapchain. */ /* if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO] && @@ -1325,11 +1226,11 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device */ TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n", - wine_dbgstr_longlong(device->adapter->vram_bytes), + wine_dbgstr_longlong(driver_info->vram_bytes), wine_dbgstr_longlong(device->adapter->vram_bytes_used), - wine_dbgstr_longlong(device->adapter->vram_bytes - device->adapter->vram_bytes_used)); + wine_dbgstr_longlong(driver_info->vram_bytes - device->adapter->vram_bytes_used)); - return min(UINT_MAX, device->adapter->vram_bytes - device->adapter->vram_bytes_used); + return min(UINT_MAX, driver_info->vram_bytes - device->adapter->vram_bytes_used); } void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx, @@ -1346,15 +1247,14 @@ void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT return; } - stream = &device->update_state->stream_output[idx]; + stream = &device->state.stream_output[idx]; prev_buffer = stream->buffer; if (buffer) wined3d_buffer_incref(buffer); stream->buffer = buffer; stream->offset = offset; - if (!device->recording) - wined3d_cs_emit_set_stream_output(device->cs, idx, buffer, offset); + wined3d_cs_emit_set_stream_output(device->cs, idx, buffer, offset); if (prev_buffer) wined3d_buffer_decref(prev_buffer); } @@ -1384,7 +1284,7 @@ HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UI TRACE("device %p, stream_idx %u, buffer %p, offset %u, stride %u.\n", device, stream_idx, buffer, offset, stride); - if (stream_idx >= MAX_STREAMS) + if (stream_idx >= WINED3D_MAX_STREAMS) { WARN("Stream index %u out of range.\n", stream_idx); return WINED3DERR_INVALIDCALL; @@ -1395,11 +1295,22 @@ HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UI return WINED3DERR_INVALIDCALL; } - stream = &device->update_state->streams[stream_idx]; + stream = &device->state.streams[stream_idx]; prev_buffer = stream->buffer; + if (buffer) + wined3d_buffer_incref(buffer); + if (device->update_stateblock_state->streams[stream_idx].buffer) + wined3d_buffer_decref(device->update_stateblock_state->streams[stream_idx].buffer); + device->update_stateblock_state->streams[stream_idx].buffer = buffer; + device->update_stateblock_state->streams[stream_idx].stride = stride; + device->update_stateblock_state->streams[stream_idx].offset = offset; + if (device->recording) + { device->recording->changed.streamSource |= 1u << stream_idx; + return WINED3D_OK; + } if (prev_buffer == buffer && stream->stride == stride @@ -1410,15 +1321,11 @@ HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UI } stream->buffer = buffer; + stream->stride = stride; + stream->offset = offset; if (buffer) - { - stream->stride = stride; - stream->offset = offset; wined3d_buffer_incref(buffer); - } - - if (!device->recording) - wined3d_cs_emit_set_stream_source(device->cs, stream_idx, buffer, offset, stride); + wined3d_cs_emit_set_stream_source(device->cs, stream_idx, buffer, offset, stride); if (prev_buffer) wined3d_buffer_decref(prev_buffer); @@ -1433,7 +1340,7 @@ HRESULT CDECL wined3d_device_get_stream_source(const struct wined3d_device *devi TRACE("device %p, stream_idx %u, buffer %p, offset %p, stride %p.\n", device, stream_idx, buffer, offset, stride); - if (stream_idx >= MAX_STREAMS) + if (stream_idx >= WINED3D_MAX_STREAMS) { WARN("Stream index %u out of range.\n", stream_idx); return WINED3DERR_INVALIDCALL; @@ -1450,8 +1357,8 @@ HRESULT CDECL wined3d_device_get_stream_source(const struct wined3d_device *devi HRESULT CDECL wined3d_device_set_stream_source_freq(struct wined3d_device *device, UINT stream_idx, UINT divider) { + UINT old_flags, old_freq, flags, freq; struct wined3d_stream_state *stream; - UINT old_flags, old_freq; TRACE("device %p, stream_idx %u, divider %#x.\n", device, stream_idx, divider); @@ -1472,16 +1379,24 @@ HRESULT CDECL wined3d_device_set_stream_source_freq(struct wined3d_device *devic return WINED3DERR_INVALIDCALL; } - stream = &device->update_state->streams[stream_idx]; + stream = &device->state.streams[stream_idx]; old_flags = stream->flags; old_freq = stream->frequency; - stream->flags = divider & (WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA); - stream->frequency = divider & 0x7fffff; + flags = divider & (WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA); + freq = divider & 0x7fffff; + device->update_stateblock_state->streams[stream_idx].flags = flags; + device->update_stateblock_state->streams[stream_idx].frequency = freq; if (device->recording) + { device->recording->changed.streamFreq |= 1u << stream_idx; - else if (stream->frequency != old_freq || stream->flags != old_flags) + return WINED3D_OK; + } + + stream->flags = flags; + stream->frequency = freq; + if (stream->frequency != old_freq || stream->flags != old_flags) wined3d_cs_emit_set_stream_source_freq(device->cs, stream_idx, stream->frequency, stream->flags); return WINED3D_OK; @@ -1513,11 +1428,11 @@ void CDECL wined3d_device_set_transform(struct wined3d_device *device, TRACE("%.8e %.8e %.8e %.8e\n", matrix->_41, matrix->_42, matrix->_43, matrix->_44); /* Handle recording of state blocks. */ + device->update_stateblock_state->transforms[d3dts] = *matrix; if (device->recording) { TRACE("Recording... not performing anything.\n"); device->recording->changed.transform[d3dts >> 5] |= 1u << (d3dts & 0x1f); - device->update_state->transforms[d3dts] = *matrix; return; } @@ -1548,26 +1463,21 @@ void CDECL wined3d_device_get_transform(const struct wined3d_device *device, void CDECL wined3d_device_multiply_transform(struct wined3d_device *device, enum wined3d_transform_state state, const struct wined3d_matrix *matrix) { - const struct wined3d_matrix *mat; - struct wined3d_matrix temp; + struct wined3d_matrix *mat; TRACE("device %p, state %s, matrix %p.\n", device, debug_d3dtstype(state), matrix); - /* Note: Using 'updateStateBlock' rather than 'stateblock' in the code - * below means it will be recorded in a state block change, but it - * works regardless where it is recorded. - * If this is found to be wrong, change to StateBlock. */ - if (state > HIGHEST_TRANSFORMSTATE) + if (state > WINED3D_HIGHEST_TRANSFORM_STATE) { WARN("Unhandled transform state %#x.\n", state); return; } - mat = &device->update_state->transforms[state]; - multiply_matrix(&temp, mat, matrix); - - /* Apply change via set transform - will reapply to eg. lights this way. */ - wined3d_device_set_transform(device, state, &temp); + /* Tests show that stateblock recording is ignored; the change goes directly + * into the primary stateblock. */ + mat = &device->state.transforms[state]; + multiply_matrix(mat, mat, matrix); + wined3d_cs_emit_set_transform(device->cs, state, mat); } /* Note lights are real special cases. Although the device caps state only @@ -1580,8 +1490,8 @@ void CDECL wined3d_device_multiply_transform(struct wined3d_device *device, HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, UINT light_idx, const struct wined3d_light *light) { - UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx); struct wined3d_light_info *object = NULL; + HRESULT hr; float rho; TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light); @@ -1615,16 +1525,13 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; } - if (!(object = wined3d_state_get_light(device->update_state, light_idx))) - { - TRACE("Adding new light\n"); - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; + if (FAILED(hr = wined3d_light_state_set_light(&device->update_stateblock_state->light_state, light_idx, light, &object))) + return hr; + if (device->recording) + return WINED3D_OK; - list_add_head(&device->update_state->light_map[hash_idx], &object->entry); - object->glIndex = -1; - object->OriginalIndex = light_idx; - } + if (FAILED(hr = wined3d_light_state_set_light(&device->state.light_state, light_idx, light, &object))) + return hr; /* Initialize the object. */ TRACE("Light %u setting to type %#x, diffuse %s, specular %s, ambient %s, " @@ -1636,9 +1543,6 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, light->direction.x, light->direction.y, light->direction.z, light->range, light->falloff, light->theta, light->phi); - /* Save away the information. */ - object->OriginalParms = *light; - switch (light->type) { case WINED3D_LIGHT_POINT: @@ -1715,8 +1619,7 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, FIXME("Unrecognized light type %#x.\n", light->type); } - if (!device->recording) - wined3d_cs_emit_set_light(device->cs, object); + wined3d_cs_emit_set_light(device->cs, object); return WINED3D_OK; } @@ -1728,7 +1631,7 @@ HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device, TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light); - if (!(light_info = wined3d_state_get_light(&device->state, light_idx))) + if (!(light_info = wined3d_light_state_get_light(&device->state.light_state, light_idx))) { TRACE("Light information requested but light not defined\n"); return WINED3DERR_INVALIDCALL; @@ -1741,25 +1644,37 @@ HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device, HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable) { struct wined3d_light_info *light_info; + HRESULT hr; TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable); + if (!(light_info = wined3d_light_state_get_light(&device->update_stateblock_state->light_state, light_idx))) + { + if (FAILED(hr = wined3d_light_state_set_light(&device->update_stateblock_state->light_state, light_idx, + &WINED3D_default_light, &light_info))) + return hr; + } + wined3d_light_state_enable_light(&device->update_stateblock_state->light_state, + &device->adapter->d3d_info, light_info, enable); + + if (device->recording) + return WINED3D_OK; + /* Special case - enabling an undefined light creates one with a strict set of parameters. */ - if (!(light_info = wined3d_state_get_light(device->update_state, light_idx))) + if (!(light_info = wined3d_light_state_get_light(&device->state.light_state, light_idx))) { TRACE("Light enabled requested but light not defined, so defining one!\n"); wined3d_device_set_light(device, light_idx, &WINED3D_default_light); - if (!(light_info = wined3d_state_get_light(device->update_state, light_idx))) + if (!(light_info = wined3d_light_state_get_light(&device->state.light_state, light_idx))) { FIXME("Adding default lights has failed dismally\n"); return WINED3DERR_INVALIDCALL; } } - wined3d_state_enable_light(device->update_state, &device->adapter->d3d_info, light_info, enable); - if (!device->recording) - wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); + wined3d_light_state_enable_light(&device->state.light_state, &device->adapter->d3d_info, light_info, enable); + wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); return WINED3D_OK; } @@ -1770,7 +1685,7 @@ HRESULT CDECL wined3d_device_get_light_enable(const struct wined3d_device *devic TRACE("device %p, light_idx %u, enable %p.\n", device, light_idx, enable); - if (!(light_info = wined3d_state_get_light(&device->state, light_idx))) + if (!(light_info = wined3d_light_state_get_light(&device->state.light_state, light_idx))) { TRACE("Light enabled state requested but light not defined.\n"); return WINED3DERR_INVALIDCALL; @@ -1785,25 +1700,29 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device, { TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane); - if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) + if (plane_idx >= device->adapter->d3d_info.limits.max_clip_distances) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; } + device->update_stateblock_state->clip_planes[plane_idx] = *plane; + if (device->recording) + { device->recording->changed.clipplane |= 1u << plane_idx; + return WINED3D_OK; + } - if (!memcmp(&device->update_state->clip_planes[plane_idx], plane, sizeof(*plane))) + if (!memcmp(&device->state.clip_planes[plane_idx], plane, sizeof(*plane))) { TRACE("Application is setting old values over, nothing to do.\n"); return WINED3D_OK; } - device->update_state->clip_planes[plane_idx] = *plane; + device->state.clip_planes[plane_idx] = *plane; - if (!device->recording) - wined3d_cs_emit_set_clip_plane(device->cs, plane_idx, plane); + wined3d_cs_emit_set_clip_plane(device->cs, plane_idx, plane); return WINED3D_OK; } @@ -1813,7 +1732,7 @@ HRESULT CDECL wined3d_device_get_clip_plane(const struct wined3d_device *device, { TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane); - if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) + if (plane_idx >= device->adapter->d3d_info.limits.max_clip_distances) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; @@ -1850,12 +1769,15 @@ void CDECL wined3d_device_set_material(struct wined3d_device *device, const stru { TRACE("device %p, material %p.\n", device, material); - device->update_state->material = *material; - + device->update_stateblock_state->material = *material; if (device->recording) + { device->recording->changed.material = TRUE; - else - wined3d_cs_emit_set_material(device->cs, material); + return; + } + + device->state.material = *material; + wined3d_cs_emit_set_material(device->cs, material); } void CDECL wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material) @@ -1881,24 +1803,32 @@ void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device, TRACE("device %p, buffer %p, format %s, offset %u.\n", device, buffer, debug_d3dformat(format_id), offset); - prev_buffer = device->update_state->index_buffer; - prev_format = device->update_state->index_format; - prev_offset = device->update_state->index_offset; + prev_buffer = device->state.index_buffer; + prev_format = device->state.index_format; + prev_offset = device->state.index_offset; - device->update_state->index_buffer = buffer; - device->update_state->index_format = format_id; - device->update_state->index_offset = offset; + if (buffer) + wined3d_buffer_incref(buffer); + if (device->update_stateblock_state->index_buffer) + wined3d_buffer_decref(device->update_stateblock_state->index_buffer); + device->update_stateblock_state->index_buffer = buffer; + device->update_stateblock_state->index_format = format_id; if (device->recording) + { device->recording->changed.indices = TRUE; + return; + } if (prev_buffer == buffer && prev_format == format_id && prev_offset == offset) return; if (buffer) wined3d_buffer_incref(buffer); - if (!device->recording) - wined3d_cs_emit_set_index_buffer(device->cs, buffer, format_id, offset); + device->state.index_buffer = buffer; + device->state.index_format = format_id; + device->state.index_offset = offset; + wined3d_cs_emit_set_index_buffer(device->cs, buffer, format_id, offset); if (prev_buffer) wined3d_buffer_decref(prev_buffer); } @@ -1918,7 +1848,9 @@ void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, I { TRACE("device %p, base_index %d.\n", device, base_index); - device->update_state->base_vertex_index = base_index; + device->update_stateblock_state->base_vertex_index = base_index; + if (!device->recording) + device->state.base_vertex_index = base_index; } INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device) @@ -1928,13 +1860,21 @@ INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *devi return device->state.base_vertex_index; } -void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport) +void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count, + const struct wined3d_viewport *viewports) { - TRACE("device %p, viewport %p.\n", device, viewport); - TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", - viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z); + unsigned int i; + + TRACE("device %p, viewport_count %u, viewports %p.\n", device, viewport_count, viewports); + + for (i = 0; i < viewport_count; ++i) + { + TRACE("%u: x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", i, viewports[i].x, viewports[i].y, + viewports[i].width, viewports[i].height, viewports[i].min_z, viewports[i].max_z); + } - device->update_state->viewport = *viewport; + if (viewport_count) + device->update_stateblock_state->viewport = viewports[0]; /* Handle recording of state blocks */ if (device->recording) @@ -1944,14 +1884,27 @@ void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const stru return; } - wined3d_cs_emit_set_viewport(device->cs, viewport); + if (viewport_count) + memcpy(device->state.viewports, viewports, viewport_count * sizeof(*viewports)); + else + memset(device->state.viewports, 0, sizeof(device->state.viewports)); + device->state.viewport_count = viewport_count; + + wined3d_cs_emit_set_viewports(device->cs, viewport_count, viewports); } -void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport) +void CDECL wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count, + struct wined3d_viewport *viewports) { - TRACE("device %p, viewport %p.\n", device, viewport); + unsigned int count; - *viewport = device->state.viewport; + TRACE("device %p, viewport_count %p, viewports %p.\n", device, viewport_count, viewports); + + count = viewport_count ? min(*viewport_count, device->state.viewport_count) : 1; + if (count && viewports) + memcpy(viewports, device->state.viewports, count * sizeof(*viewports)); + if (viewport_count) + *viewport_count = device->state.viewport_count; } static void resolve_depth_buffer(struct wined3d_device *device) @@ -1973,29 +1926,43 @@ static void resolve_depth_buffer(struct wined3d_device *device) src_view->resource, src_view->sub_resource_idx, dst_resource->format->id); } -void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state) +void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, + struct wined3d_blend_state *blend_state, const struct wined3d_color *blend_factor) { + struct wined3d_state *state = &device->state; struct wined3d_blend_state *prev; - TRACE("device %p, blend_state %p.\n", device, blend_state); + TRACE("device %p, blend_state %p, blend_factor %s.\n", device, blend_state, debug_color(blend_factor)); - prev = device->update_state->blend_state; - if (prev == blend_state) + device->update_stateblock_state->blend_factor = *blend_factor; + if (device->recording) + { + device->recording->changed.blend_state = TRUE; + return; + } + + prev = state->blend_state; + if (prev == blend_state && !memcmp(blend_factor, &state->blend_factor, sizeof(*blend_factor))) return; if (blend_state) wined3d_blend_state_incref(blend_state); - device->update_state->blend_state = blend_state; - wined3d_cs_emit_set_blend_state(device->cs, blend_state); + state->blend_state = blend_state; + state->blend_factor = *blend_factor; + wined3d_cs_emit_set_blend_state(device->cs, blend_state, blend_factor); if (prev) wined3d_blend_state_decref(prev); } -struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct wined3d_device *device) +struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct wined3d_device *device, + struct wined3d_color *blend_factor) { - TRACE("device %p.\n", device); + const struct wined3d_state *state = &device->state; - return device->state.blend_state; + TRACE("device %p, blend_factor %p.\n", device, blend_factor); + + *blend_factor = state->blend_factor; + return state->blend_state; } void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, @@ -2005,13 +1972,13 @@ void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, TRACE("device %p, rasterizer_state %p.\n", device, rasterizer_state); - prev = device->update_state->rasterizer_state; + prev = device->state.rasterizer_state; if (prev == rasterizer_state) return; if (rasterizer_state) wined3d_rasterizer_state_incref(rasterizer_state); - device->update_state->rasterizer_state = rasterizer_state; + device->state.rasterizer_state = rasterizer_state; wined3d_cs_emit_set_rasterizer_state(device->cs, rasterizer_state); if (prev) wined3d_rasterizer_state_decref(prev); @@ -2027,8 +1994,6 @@ struct wined3d_rasterizer_state * CDECL wined3d_device_get_rasterizer_state(stru void CDECL wined3d_device_set_render_state(struct wined3d_device *device, enum wined3d_render_state state, DWORD value) { - DWORD old_value; - TRACE("device %p, state %s (%#x), value %#x.\n", device, debug_d3drenderstate(state), state, value); if (state > WINEHIGHEST_RENDER_STATE) @@ -2037,8 +2002,7 @@ void CDECL wined3d_device_set_render_state(struct wined3d_device *device, return; } - old_value = device->state.render_states[state]; - device->update_state->render_states[state] = value; + device->update_stateblock_state->rs[state] = value; /* Handle recording of state blocks. */ if (device->recording) @@ -2048,11 +2012,13 @@ void CDECL wined3d_device_set_render_state(struct wined3d_device *device, return; } - /* Compared here and not before the assignment to allow proper stateblock recording. */ - if (value == old_value) + if (value == device->state.render_states[state]) TRACE("Application is setting the old value over, nothing to do.\n"); else + { + device->state.render_states[state] = value; wined3d_cs_emit_set_render_state(device->cs, state, value); + } if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE) { @@ -2071,13 +2037,11 @@ DWORD CDECL wined3d_device_get_render_state(const struct wined3d_device *device, void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value) { - DWORD old_value; - TRACE("device %p, sampler_idx %u, state %s, value %#x.\n", device, sampler_idx, debug_d3dsamplerstate(state), value); if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3) - sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS); + sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - WINED3D_MAX_FRAGMENT_SAMPLERS); if (sampler_idx >= ARRAY_SIZE(device->state.sampler_states)) { @@ -2085,8 +2049,7 @@ void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device, return; /* Windows accepts overflowing this array ... we do not. */ } - old_value = device->state.sampler_states[sampler_idx][state]; - device->update_state->sampler_states[sampler_idx][state] = value; + device->update_stateblock_state->sampler_states[sampler_idx][state] = value; /* Handle recording of state blocks. */ if (device->recording) @@ -2096,12 +2059,13 @@ void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device, return; } - if (old_value == value) + if (value == device->state.sampler_states[sampler_idx][state]) { TRACE("Application is setting the old value over, nothing to do.\n"); return; } + device->state.sampler_states[sampler_idx][state] = value; wined3d_cs_emit_set_sampler_state(device->cs, sampler_idx, state, value); } @@ -2112,7 +2076,7 @@ DWORD CDECL wined3d_device_get_sampler_state(const struct wined3d_device *device device, sampler_idx, debug_d3dsamplerstate(state)); if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3) - sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS); + sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - WINED3D_MAX_FRAGMENT_SAMPLERS); if (sampler_idx >= ARRAY_SIZE(device->state.sampler_states)) { @@ -2123,55 +2087,82 @@ DWORD CDECL wined3d_device_get_sampler_state(const struct wined3d_device *device return device->state.sampler_states[sampler_idx][state]; } -void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect) +void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsigned int rect_count, + const RECT *rects) { - TRACE("device %p, rect %s.\n", device, wine_dbgstr_rect(rect)); + unsigned int i; - if (device->recording) - device->recording->changed.scissorRect = TRUE; + TRACE("device %p, rect_count %u, rects %p.\n", device, rect_count, rects); - if (EqualRect(&device->update_state->scissor_rect, rect)) + for (i = 0; i < rect_count; ++i) { - TRACE("App is setting the old scissor rectangle over, nothing to do.\n"); - return; + TRACE("%u: %s\n", i, wine_dbgstr_rect(&rects[i])); } - CopyRect(&device->update_state->scissor_rect, rect); + + if (rect_count) + device->update_stateblock_state->scissor_rect = rects[0]; if (device->recording) { - TRACE("Recording... not performing anything.\n"); + device->recording->changed.scissorRect = TRUE; return; } - wined3d_cs_emit_set_scissor_rect(device->cs, rect); + if (device->state.scissor_rect_count == rect_count + && !memcmp(device->state.scissor_rects, rects, rect_count * sizeof(*rects))) + { + TRACE("App is setting the old scissor rectangles over, nothing to do.\n"); + return; + } + + if (rect_count) + memcpy(device->state.scissor_rects, rects, rect_count * sizeof(*rects)); + else + memset(device->state.scissor_rects, 0, sizeof(device->state.scissor_rects)); + device->state.scissor_rect_count = rect_count; + + wined3d_cs_emit_set_scissor_rects(device->cs, rect_count, rects); } -void CDECL wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect) +void CDECL wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, RECT *rects) { - TRACE("device %p, rect %p.\n", device, rect); + unsigned int count; + + TRACE("device %p, rect_count %p, rects %p.\n", device, rect_count, rects); - *rect = device->state.scissor_rect; - TRACE("Returning rect %s.\n", wine_dbgstr_rect(rect)); + count = rect_count ? min(*rect_count, device->state.scissor_rect_count) : 1; + if (count && rects) + memcpy(rects, device->state.scissor_rects, count * sizeof(*rects)); + if (rect_count) + *rect_count = device->state.scissor_rect_count; } void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device, struct wined3d_vertex_declaration *declaration) { - struct wined3d_vertex_declaration *prev = device->update_state->vertex_declaration; + struct wined3d_vertex_declaration *prev = device->state.vertex_declaration; TRACE("device %p, declaration %p.\n", device, declaration); + if (declaration) + wined3d_vertex_declaration_incref(declaration); + if (device->update_stateblock_state->vertex_declaration) + wined3d_vertex_declaration_decref(device->update_stateblock_state->vertex_declaration); + device->update_stateblock_state->vertex_declaration = declaration; + if (device->recording) + { device->recording->changed.vertexDecl = TRUE; + return; + } if (declaration == prev) return; if (declaration) wined3d_vertex_declaration_incref(declaration); - device->update_state->vertex_declaration = declaration; - if (!device->recording) - wined3d_cs_emit_set_vertex_declaration(device->cs, declaration); + device->state.vertex_declaration = declaration; + wined3d_cs_emit_set_vertex_declaration(device->cs, declaration); if (prev) wined3d_vertex_declaration_decref(prev); } @@ -2185,21 +2176,29 @@ struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration( void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX]; + struct wined3d_shader *prev = device->state.shader[WINED3D_SHADER_TYPE_VERTEX]; TRACE("device %p, shader %p.\n", device, shader); + if (shader) + wined3d_shader_incref(shader); + if (device->update_stateblock_state->vs) + wined3d_shader_decref(device->update_stateblock_state->vs); + device->update_stateblock_state->vs = shader; + if (device->recording) + { device->recording->changed.vertexShader = TRUE; + return; + } if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX] = shader; - if (!device->recording) - wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader); + device->state.shader[WINED3D_SHADER_TYPE_VERTEX] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader); if (prev) wined3d_shader_decref(prev); } @@ -2211,40 +2210,36 @@ struct wined3d_shader * CDECL wined3d_device_get_vertex_shader(const struct wine return device->state.shader[WINED3D_SHADER_TYPE_VERTEX]; } -static void wined3d_device_set_constant_buffer(struct wined3d_device *device, +void CDECL wined3d_device_set_constant_buffer(struct wined3d_device *device, enum wined3d_shader_type type, UINT idx, struct wined3d_buffer *buffer) { struct wined3d_buffer *prev; + TRACE("device %p, type %#x, idx %u, buffer %p.\n", device, type, idx, buffer); + if (idx >= MAX_CONSTANT_BUFFERS) { WARN("Invalid constant buffer index %u.\n", idx); return; } - prev = device->update_state->cb[type][idx]; + prev = device->state.cb[type][idx]; if (buffer == prev) return; if (buffer) wined3d_buffer_incref(buffer); - device->update_state->cb[type][idx] = buffer; - if (!device->recording) - wined3d_cs_emit_set_constant_buffer(device->cs, type, idx, buffer); + device->state.cb[type][idx] = buffer; + wined3d_cs_emit_set_constant_buffer(device->cs, type, idx, buffer); if (prev) wined3d_buffer_decref(prev); } -void CDECL wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) -{ - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - - wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_VERTEX, idx, buffer); -} - -static struct wined3d_buffer *wined3d_device_get_constant_buffer(const struct wined3d_device *device, +struct wined3d_buffer * CDECL wined3d_device_get_constant_buffer(const struct wined3d_device *device, enum wined3d_shader_type shader_type, unsigned int idx) { + TRACE("device %p, shader_type %#x, idx %u.\n", device, shader_type, idx); + if (idx >= MAX_CONSTANT_BUFFERS) { WARN("Invalid constant buffer index %u.\n", idx); @@ -2254,13 +2249,6 @@ static struct wined3d_buffer *wined3d_device_get_constant_buffer(const struct wi return device->state.cb[shader_type][idx]; } -struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx) -{ - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_VERTEX, idx); -} - static void wined3d_device_set_shader_resource_view(struct wined3d_device *device, enum wined3d_shader_type type, UINT idx, struct wined3d_shader_resource_view *view) { @@ -2272,15 +2260,14 @@ static void wined3d_device_set_shader_resource_view(struct wined3d_device *devic return; } - prev = device->update_state->shader_resource_view[type][idx]; + prev = device->state.shader_resource_view[type][idx]; if (view == prev) return; if (view) wined3d_shader_resource_view_incref(view); - device->update_state->shader_resource_view[type][idx] = view; - if (!device->recording) - wined3d_cs_emit_set_shader_resource_view(device->cs, type, idx, view); + device->state.shader_resource_view[type][idx] = view; + wined3d_cs_emit_set_shader_resource_view(device->cs, type, idx, view); if (prev) wined3d_shader_resource_view_decref(prev); } @@ -2324,15 +2311,14 @@ static void wined3d_device_set_sampler(struct wined3d_device *device, return; } - prev = device->update_state->sampler[type][idx]; + prev = device->state.sampler[type][idx]; if (sampler == prev) return; if (sampler) wined3d_sampler_incref(sampler); - device->update_state->sampler[type][idx] = sampler; - if (!device->recording) - wined3d_cs_emit_set_sampler(device->cs, type, idx, sampler); + device->state.sampler[type][idx] = sampler; + wined3d_cs_emit_set_sampler(device->cs, type, idx, sampler); if (prev) wined3d_sampler_decref(prev); } @@ -2376,23 +2362,24 @@ HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device, if (count > WINED3D_MAX_CONSTS_B - start_idx) count = WINED3D_MAX_CONSTS_B - start_idx; - memcpy(&device->update_state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); - if (TRACE_ON(d3d)) - { - for (i = 0; i < count; ++i) - TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); - } + memcpy(&device->update_stateblock_state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); if (device->recording) { for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.vertexShaderConstantsB |= (1u << i); + return WINED3D_OK; } - else + + memcpy(&device->state.vs_consts_b[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) { - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants); + for (i = 0; i < count; ++i) + TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); } + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants); + return WINED3D_OK; } @@ -2425,23 +2412,24 @@ HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device, if (count > WINED3D_MAX_CONSTS_I - start_idx) count = WINED3D_MAX_CONSTS_I - start_idx; - memcpy(&device->update_state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); - if (TRACE_ON(d3d)) - { - for (i = 0; i < count; ++i) - TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); - } + memcpy(&device->update_stateblock_state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); if (device->recording) { for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.vertexShaderConstantsI |= (1u << i); + return WINED3D_OK; } - else + + memcpy(&device->state.vs_consts_i[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) { - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants); + for (i = 0; i < count; ++i) + TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); } + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants); + return WINED3D_OK; } @@ -2464,27 +2452,35 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device, unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + unsigned int constants_count; unsigned int i; TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants); - if (!constants || start_idx >= d3d_info->limits.vs_uniform_count - || count > d3d_info->limits.vs_uniform_count - start_idx) + constants_count = device->create_parms.flags + & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) + ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count; + if (!constants || start_idx >= constants_count + || count > constants_count - start_idx) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->update_stateblock_state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); + if (device->recording) + { + memset(&device->recording->changed.vs_consts_f[start_idx], 1, + count * sizeof(*device->recording->changed.vs_consts_f)); + return WINED3D_OK; + } + + memcpy(&device->state.vs_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); } - if (device->recording) - memset(&device->recording->changed.vs_consts_f[start_idx], 1, - count * sizeof(*device->recording->changed.vs_consts_f)); - else - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants); + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants); return WINED3D_OK; } @@ -2493,12 +2489,16 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + unsigned int constants_count; TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants); - if (!constants || start_idx >= d3d_info->limits.vs_uniform_count - || count > d3d_info->limits.vs_uniform_count - start_idx) + constants_count = device->create_parms.flags + & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) + ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count; + if (!constants || start_idx >= constants_count + || count > constants_count - start_idx) return WINED3DERR_INVALIDCALL; memcpy(constants, &device->state.vs_consts_f[start_idx], count * sizeof(*constants)); @@ -2508,21 +2508,28 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_PIXEL]; + struct wined3d_shader *prev = device->state.shader[WINED3D_SHADER_TYPE_PIXEL]; TRACE("device %p, shader %p.\n", device, shader); + if (shader) + wined3d_shader_incref(shader); + if (device->update_stateblock_state->ps) + wined3d_shader_decref(device->update_stateblock_state->ps); + device->update_stateblock_state->ps = shader; if (device->recording) + { device->recording->changed.pixelShader = TRUE; + return; + } if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_PIXEL] = shader; - if (!device->recording) - wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_PIXEL, shader); + device->state.shader[WINED3D_SHADER_TYPE_PIXEL] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_PIXEL, shader); if (prev) wined3d_shader_decref(prev); } @@ -2534,20 +2541,6 @@ struct wined3d_shader * CDECL wined3d_device_get_pixel_shader(const struct wined return device->state.shader[WINED3D_SHADER_TYPE_PIXEL]; } -void CDECL wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) -{ - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - - wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_PIXEL, idx, buffer); -} - -struct wined3d_buffer * CDECL wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx) -{ - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_PIXEL, idx); -} - void CDECL wined3d_device_set_ps_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view) { @@ -2591,23 +2584,24 @@ HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device, if (count > WINED3D_MAX_CONSTS_B - start_idx) count = WINED3D_MAX_CONSTS_B - start_idx; - memcpy(&device->update_state->ps_consts_b[start_idx], constants, count * sizeof(*constants)); - if (TRACE_ON(d3d)) - { - for (i = 0; i < count; ++i) - TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); - } + memcpy(&device->update_stateblock_state->ps_consts_b[start_idx], constants, count * sizeof(*constants)); if (device->recording) { for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.pixelShaderConstantsB |= (1u << i); + return WINED3D_OK; } - else + + memcpy(&device->state.ps_consts_b[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) { - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_B, start_idx, count, constants); + for (i = 0; i < count; ++i) + TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); } + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_B, start_idx, count, constants); + return WINED3D_OK; } @@ -2640,23 +2634,24 @@ HRESULT CDECL wined3d_device_set_ps_consts_i(struct wined3d_device *device, if (count > WINED3D_MAX_CONSTS_I - start_idx) count = WINED3D_MAX_CONSTS_I - start_idx; - memcpy(&device->update_state->ps_consts_i[start_idx], constants, count * sizeof(*constants)); - if (TRACE_ON(d3d)) - { - for (i = 0; i < count; ++i) - TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); - } + memcpy(&device->update_stateblock_state->ps_consts_i[start_idx], constants, count * sizeof(*constants)); if (device->recording) { for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.pixelShaderConstantsI |= (1u << i); + return WINED3D_OK; } - else + + memcpy(&device->state.ps_consts_i[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) { - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_I, start_idx, count, constants); + for (i = 0; i < count; ++i) + TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); } + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_I, start_idx, count, constants); + return WINED3D_OK; } @@ -2689,18 +2684,22 @@ HRESULT CDECL wined3d_device_set_ps_consts_f(struct wined3d_device *device, || count > d3d_info->limits.ps_uniform_count - start_idx) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->ps_consts_f[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->update_stateblock_state->ps_consts_f[start_idx], constants, count * sizeof(*constants)); + if (device->recording) + { + memset(&device->recording->changed.ps_consts_f[start_idx], 1, + count * sizeof(*device->recording->changed.ps_consts_f)); + return WINED3D_OK; + } + + memcpy(&device->state.ps_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); } - if (device->recording) - memset(&device->recording->changed.ps_consts_f[start_idx], 1, - count * sizeof(*device->recording->changed.ps_consts_f)); - else - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_F, start_idx, count, constants); + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_F, start_idx, count, constants); return WINED3D_OK; } @@ -2728,12 +2727,12 @@ void CDECL wined3d_device_set_hull_shader(struct wined3d_device *device, struct TRACE("device %p, shader %p.\n", device, shader); - prev = device->update_state->shader[WINED3D_SHADER_TYPE_HULL]; + prev = device->state.shader[WINED3D_SHADER_TYPE_HULL]; if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_HULL] = shader; + device->state.shader[WINED3D_SHADER_TYPE_HULL] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_HULL, shader); if (prev) wined3d_shader_decref(prev); @@ -2746,20 +2745,6 @@ struct wined3d_shader * CDECL wined3d_device_get_hull_shader(const struct wined3 return device->state.shader[WINED3D_SHADER_TYPE_HULL]; } -void CDECL wined3d_device_set_hs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer) -{ - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - - wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_HULL, idx, buffer); -} - -struct wined3d_buffer * CDECL wined3d_device_get_hs_cb(const struct wined3d_device *device, unsigned int idx) -{ - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_HULL, idx); -} - void CDECL wined3d_device_set_hs_resource_view(struct wined3d_device *device, unsigned int idx, struct wined3d_shader_resource_view *view) { @@ -2797,12 +2782,12 @@ void CDECL wined3d_device_set_domain_shader(struct wined3d_device *device, struc TRACE("device %p, shader %p.\n", device, shader); - prev = device->update_state->shader[WINED3D_SHADER_TYPE_DOMAIN]; + prev = device->state.shader[WINED3D_SHADER_TYPE_DOMAIN]; if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_DOMAIN] = shader; + device->state.shader[WINED3D_SHADER_TYPE_DOMAIN] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_DOMAIN, shader); if (prev) wined3d_shader_decref(prev); @@ -2815,20 +2800,6 @@ struct wined3d_shader * CDECL wined3d_device_get_domain_shader(const struct wine return device->state.shader[WINED3D_SHADER_TYPE_DOMAIN]; } -void CDECL wined3d_device_set_ds_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer) -{ - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - - wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_DOMAIN, idx, buffer); -} - -struct wined3d_buffer * CDECL wined3d_device_get_ds_cb(const struct wined3d_device *device, unsigned int idx) -{ - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_DOMAIN, idx); -} - void CDECL wined3d_device_set_ds_resource_view(struct wined3d_device *device, unsigned int idx, struct wined3d_shader_resource_view *view) { @@ -2862,15 +2833,15 @@ struct wined3d_sampler * CDECL wined3d_device_get_ds_sampler(const struct wined3 void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; + struct wined3d_shader *prev = device->state.shader[WINED3D_SHADER_TYPE_GEOMETRY]; TRACE("device %p, shader %p.\n", device, shader); - if (device->recording || shader == prev) + if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_GEOMETRY] = shader; + device->state.shader[WINED3D_SHADER_TYPE_GEOMETRY] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_GEOMETRY, shader); if (prev) wined3d_shader_decref(prev); @@ -2883,20 +2854,6 @@ struct wined3d_shader * CDECL wined3d_device_get_geometry_shader(const struct wi return device->state.shader[WINED3D_SHADER_TYPE_GEOMETRY]; } -void CDECL wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer) -{ - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - - wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_GEOMETRY, idx, buffer); -} - -struct wined3d_buffer * CDECL wined3d_device_get_gs_cb(const struct wined3d_device *device, UINT idx) -{ - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_GEOMETRY, idx); -} - void CDECL wined3d_device_set_gs_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view) { @@ -2933,12 +2890,12 @@ void CDECL wined3d_device_set_compute_shader(struct wined3d_device *device, stru TRACE("device %p, shader %p.\n", device, shader); - prev = device->update_state->shader[WINED3D_SHADER_TYPE_COMPUTE]; - if (device->recording || shader == prev) + prev = device->state.shader[WINED3D_SHADER_TYPE_COMPUTE]; + if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_COMPUTE] = shader; + device->state.shader[WINED3D_SHADER_TYPE_COMPUTE] = shader; wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_COMPUTE, shader); if (prev) wined3d_shader_decref(prev); @@ -2951,20 +2908,6 @@ struct wined3d_shader * CDECL wined3d_device_get_compute_shader(const struct win return device->state.shader[WINED3D_SHADER_TYPE_COMPUTE]; } -void CDECL wined3d_device_set_cs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer) -{ - TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); - - wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_COMPUTE, idx, buffer); -} - -struct wined3d_buffer * CDECL wined3d_device_get_cs_cb(const struct wined3d_device *device, unsigned int idx) -{ - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_COMPUTE, idx); -} - void CDECL wined3d_device_set_cs_resource_view(struct wined3d_device *device, unsigned int idx, struct wined3d_shader_resource_view *view) { @@ -2986,114 +2929,671 @@ void CDECL wined3d_device_set_cs_sampler(struct wined3d_device *device, { TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); - wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_COMPUTE, idx, sampler); -} + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_COMPUTE, idx, sampler); +} + +struct wined3d_sampler * CDECL wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_COMPUTE, idx); +} + +static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_device *device, + enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav, + unsigned int initial_count) +{ + struct wined3d_unordered_access_view *prev; + + if (idx >= MAX_UNORDERED_ACCESS_VIEWS) + { + WARN("Invalid UAV index %u.\n", idx); + return; + } + + prev = device->state.unordered_access_view[pipeline][idx]; + if (uav == prev && initial_count == ~0u) + return; + + if (uav) + wined3d_unordered_access_view_incref(uav); + device->state.unordered_access_view[pipeline][idx] = uav; + wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav, initial_count); + if (prev) + wined3d_unordered_access_view_decref(prev); +} + +static struct wined3d_unordered_access_view *wined3d_device_get_pipeline_unordered_access_view( + const struct wined3d_device *device, enum wined3d_pipeline pipeline, unsigned int idx) +{ + if (idx >= MAX_UNORDERED_ACCESS_VIEWS) + { + WARN("Invalid UAV index %u.\n", idx); + return NULL; + } + + return device->state.unordered_access_view[pipeline][idx]; +} + +void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx, + struct wined3d_unordered_access_view *uav, unsigned int initial_count) +{ + TRACE("device %p, idx %u, uav %p, initial_count %#x.\n", device, idx, uav, initial_count); + + wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav, initial_count); +} + +struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const struct wined3d_device *device, + unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx); +} + +void CDECL wined3d_device_set_unordered_access_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count) +{ + TRACE("device %p, idx %u, uav %p, initial_count %#x.\n", device, idx, uav, initial_count); + + wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav, initial_count); +} + +struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access_view( + const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx); +} + +void CDECL wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int latency) +{ + unsigned int i; + + if (!latency) + latency = 3; + + device->max_frame_latency = latency; + for (i = 0; i < device->swapchain_count; ++i) + swapchain_set_max_frame_latency(device->swapchains[i], device); +} + +unsigned int CDECL wined3d_device_get_max_frame_latency(const struct wined3d_device *device) +{ + return device->max_frame_latency; +} + +static unsigned int wined3d_get_flexible_vertex_size(DWORD fvf) +{ + unsigned int texcoord_count = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; + unsigned int i, size = 0; + + if (fvf & WINED3DFVF_NORMAL) size += 3 * sizeof(float); + if (fvf & WINED3DFVF_DIFFUSE) size += sizeof(DWORD); + if (fvf & WINED3DFVF_SPECULAR) size += sizeof(DWORD); + if (fvf & WINED3DFVF_PSIZE) size += sizeof(DWORD); + switch (fvf & WINED3DFVF_POSITION_MASK) + { + case WINED3DFVF_XYZ: size += 3 * sizeof(float); break; + case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break; + case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break; + case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break; + case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break; + case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break; + case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break; + case WINED3DFVF_XYZW: size += 4 * sizeof(float); break; + default: FIXME("Unexpected position mask %#x.\n", fvf & WINED3DFVF_POSITION_MASK); + } + for (i = 0; i < texcoord_count; ++i) + { + size += GET_TEXCOORD_SIZE_FROM_FVF(fvf, i) * sizeof(float); + } + + return size; +} + +static void wined3d_format_get_colour(const struct wined3d_format *format, + const void *data, struct wined3d_color *colour) +{ + float *output = &colour->r; + const uint32_t *u32_data; + const uint16_t *u16_data; + const float *f32_data; + unsigned int i; + + static const struct wined3d_color default_colour = {0.0f, 0.0f, 0.0f, 1.0f}; + static unsigned int warned; + + switch (format->id) + { + case WINED3DFMT_B8G8R8A8_UNORM: + u32_data = data; + wined3d_color_from_d3dcolor(colour, *u32_data); + break; + + case WINED3DFMT_R8G8B8A8_UNORM: + u32_data = data; + colour->r = (*u32_data & 0xffu) / 255.0f; + colour->g = ((*u32_data >> 8) & 0xffu) / 255.0f; + colour->b = ((*u32_data >> 16) & 0xffu) / 255.0f; + colour->a = ((*u32_data >> 24) & 0xffu) / 255.0f; + break; + + case WINED3DFMT_R16G16_UNORM: + case WINED3DFMT_R16G16B16A16_UNORM: + u16_data = data; + *colour = default_colour; + for (i = 0; i < format->component_count; ++i) + output[i] = u16_data[i] / 65535.0f; + break; + + case WINED3DFMT_R32_FLOAT: + case WINED3DFMT_R32G32_FLOAT: + case WINED3DFMT_R32G32B32_FLOAT: + case WINED3DFMT_R32G32B32A32_FLOAT: + f32_data = data; + *colour = default_colour; + for (i = 0; i < format->component_count; ++i) + output[i] = f32_data[i]; + break; + + default: + *colour = default_colour; + if (!warned++) + FIXME("Unhandled colour format conversion, format %s.\n", debug_d3dformat(format->id)); + break; + } +} + +static void wined3d_colour_from_mcs(struct wined3d_color *colour, enum wined3d_material_color_source mcs, + const struct wined3d_color *material_colour, unsigned int index, + const struct wined3d_stream_info *stream_info) +{ + const struct wined3d_stream_info_element *element = NULL; + + switch (mcs) + { + case WINED3D_MCS_MATERIAL: + *colour = *material_colour; + return; + + case WINED3D_MCS_COLOR1: + if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE))) + { + colour->r = colour->g = colour->b = colour->a = 1.0f; + return; + } + element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; + break; + + case WINED3D_MCS_COLOR2: + if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR))) + { + colour->r = colour->g = colour->b = colour->a = 0.0f; + return; + } + element = &stream_info->elements[WINED3D_FFP_SPECULAR]; + break; + + default: + colour->r = colour->g = colour->b = colour->a = 0.0f; + ERR("Invalid material colour source %#x.\n", mcs); + return; + } + + wined3d_format_get_colour(element->format, &element->data.addr[index * element->stride], colour); +} + +static float wined3d_clamp(float value, float min_value, float max_value) +{ + return value < min_value ? min_value : value > max_value ? max_value : value; +} + +static float wined3d_vec3_dot(const struct wined3d_vec3 *v0, const struct wined3d_vec3 *v1) +{ + return v0->x * v1->x + v0->y * v1->y + v0->z * v1->z; +} + +static void wined3d_vec3_subtract(struct wined3d_vec3 *v0, const struct wined3d_vec3 *v1) +{ + v0->x -= v1->x; + v0->y -= v1->y; + v0->z -= v1->z; +} + +static void wined3d_vec3_scale(struct wined3d_vec3 *v, float s) +{ + v->x *= s; + v->y *= s; + v->z *= s; +} + +static void wined3d_vec3_normalise(struct wined3d_vec3 *v) +{ + float rnorm = 1.0f / sqrtf(wined3d_vec3_dot(v, v)); + + if (isfinite(rnorm)) + wined3d_vec3_scale(v, rnorm); +} + +static void wined3d_vec3_transform(struct wined3d_vec3 *dst, + const struct wined3d_vec3 *v, const struct wined3d_matrix_3x3 *m) +{ + struct wined3d_vec3 tmp; + + tmp.x = v->x * m->_11 + v->y * m->_21 + v->z * m->_31; + tmp.y = v->x * m->_12 + v->y * m->_22 + v->z * m->_32; + tmp.z = v->x * m->_13 + v->y * m->_23 + v->z * m->_33; + + *dst = tmp; +} + +static void wined3d_color_clamp(struct wined3d_color *dst, const struct wined3d_color *src, + float min_value, float max_value) +{ + dst->r = wined3d_clamp(src->r, min_value, max_value); + dst->g = wined3d_clamp(src->g, min_value, max_value); + dst->b = wined3d_clamp(src->b, min_value, max_value); + dst->a = wined3d_clamp(src->a, min_value, max_value); +} + +static void wined3d_color_rgb_mul_add(struct wined3d_color *dst, const struct wined3d_color *src, float c) +{ + dst->r += src->r * c; + dst->g += src->g * c; + dst->b += src->b * c; +} + +static void init_transformed_lights(struct lights_settings *ls, + const struct wined3d_state *state, BOOL legacy_lighting, BOOL compute_lighting) +{ + const struct wined3d_light_info *lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; + const struct wined3d_light_info *light_info; + struct light_transformed *light; + struct wined3d_vec4 vec4; + unsigned int light_count; + unsigned int i, index; + + memset(ls, 0, sizeof(*ls)); + + ls->lighting = !!compute_lighting; + ls->fog_mode = state->render_states[WINED3D_RS_FOGVERTEXMODE]; + ls->fog_coord_mode = state->render_states[WINED3D_RS_RANGEFOGENABLE] + ? WINED3D_FFP_VS_FOG_RANGE : WINED3D_FFP_VS_FOG_DEPTH; + ls->fog_start = wined3d_get_float_state(state, WINED3D_RS_FOGSTART); + ls->fog_end = wined3d_get_float_state(state, WINED3D_RS_FOGEND); + ls->fog_density = wined3d_get_float_state(state, WINED3D_RS_FOGDENSITY); + + if (ls->fog_mode == WINED3D_FOG_NONE && !compute_lighting) + return; + + multiply_matrix(&ls->modelview_matrix, &state->transforms[WINED3D_TS_VIEW], + &state->transforms[WINED3D_TS_WORLD_MATRIX(0)]); + + if (!compute_lighting) + return; + + compute_normal_matrix(&ls->normal_matrix._11, legacy_lighting, &ls->modelview_matrix); + + wined3d_color_from_d3dcolor(&ls->ambient_light, state->render_states[WINED3D_RS_AMBIENT]); + ls->legacy_lighting = !!legacy_lighting; + ls->normalise = !!state->render_states[WINED3D_RS_NORMALIZENORMALS]; + ls->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; + + for (i = 0, index = 0; i < LIGHTMAP_SIZE && index < ARRAY_SIZE(lights); ++i) + { + LIST_FOR_EACH_ENTRY(light_info, &state->light_state.light_map[i], struct wined3d_light_info, entry) + { + if (!light_info->enabled) + continue; + + switch (light_info->OriginalParms.type) + { + case WINED3D_LIGHT_DIRECTIONAL: + ++ls->directional_light_count; + break; + + case WINED3D_LIGHT_POINT: + ++ls->point_light_count; + break; + + case WINED3D_LIGHT_SPOT: + ++ls->spot_light_count; + break; + + case WINED3D_LIGHT_PARALLELPOINT: + ++ls->parallel_point_light_count; + break; + + default: + FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); + continue; + } + lights[index++] = light_info; + if (index == WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS) + break; + } + } + + light_count = index; + for (i = 0, index = 0; i < light_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_DIRECTIONAL) + continue; + + light = &ls->lights[index]; + wined3d_vec4_transform(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]); + light->direction = *(struct wined3d_vec3 *)&vec4; + wined3d_vec3_normalise(&light->direction); + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } + + for (i = 0; i < light_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_POINT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_transform(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + light->range = light_info->OriginalParms.range; + light->c_att = light_info->OriginalParms.attenuation0; + light->l_att = light_info->OriginalParms.attenuation1; + light->q_att = light_info->OriginalParms.attenuation2; + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } + + for (i = 0; i < light_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_SPOT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_transform(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + wined3d_vec4_transform(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]); + light->direction = *(struct wined3d_vec3 *)&vec4; + wined3d_vec3_normalise(&light->direction); + light->range = light_info->OriginalParms.range; + light->falloff = light_info->OriginalParms.falloff; + light->c_att = light_info->OriginalParms.attenuation0; + light->l_att = light_info->OriginalParms.attenuation1; + light->q_att = light_info->OriginalParms.attenuation2; + light->cos_htheta = cosf(light_info->OriginalParms.theta / 2.0f); + light->cos_hphi = cosf(light_info->OriginalParms.phi / 2.0f); + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } + + for (i = 0; i < light_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_PARALLELPOINT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_transform(&vec4, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + *(struct wined3d_vec3 *)&light->position = *(struct wined3d_vec3 *)&vec4; + wined3d_vec3_normalise((struct wined3d_vec3 *)&light->position); + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } +} + +static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, + const struct wined3d_vec3 *dir, float att, float material_shininess, + const struct wined3d_vec3 *normal_transformed, + const struct wined3d_vec3 *position_transformed_normalised, + const struct light_transformed *light, const struct lights_settings *ls) +{ + struct wined3d_vec3 vec3; + float t, c; + + c = wined3d_clamp(wined3d_vec3_dot(dir, normal_transformed), 0.0f, 1.0f); + wined3d_color_rgb_mul_add(diffuse, &light->diffuse, c * att); + + vec3 = *dir; + if (ls->localviewer) + wined3d_vec3_subtract(&vec3, position_transformed_normalised); + else + vec3.z -= 1.0f; + wined3d_vec3_normalise(&vec3); + t = wined3d_vec3_dot(normal_transformed, &vec3); + if (t > 0.0f && (!ls->legacy_lighting || material_shininess > 0.0f) + && wined3d_vec3_dot(dir, normal_transformed) > 0.0f) + wined3d_color_rgb_mul_add(specular, &light->specular, att * powf(t, material_shininess)); +} + +static void light_set_vertex_data(struct lights_settings *ls, + const struct wined3d_vec4 *position) +{ + if (ls->fog_mode == WINED3D_FOG_NONE && !ls->lighting) + return; + + wined3d_vec4_transform(&ls->position_transformed, position, &ls->modelview_matrix); + wined3d_vec3_scale((struct wined3d_vec3 *)&ls->position_transformed, 1.0f / ls->position_transformed.w); +} + +static void compute_light(struct wined3d_color *ambient, struct wined3d_color *diffuse, + struct wined3d_color *specular, struct lights_settings *ls, const struct wined3d_vec3 *normal, + float material_shininess) +{ + struct wined3d_vec3 position_transformed_normalised; + struct wined3d_vec3 normal_transformed = {0.0f}; + const struct light_transformed *light; + struct wined3d_vec3 dir, dst; + unsigned int i, index; + float att; + + position_transformed_normalised = *(const struct wined3d_vec3 *)&ls->position_transformed; + wined3d_vec3_normalise(&position_transformed_normalised); + + if (normal) + { + wined3d_vec3_transform(&normal_transformed, normal, &ls->normal_matrix); + if (ls->normalise) + wined3d_vec3_normalise(&normal_transformed); + } + + diffuse->r = diffuse->g = diffuse->b = diffuse->a = 0.0f; + *specular = *diffuse; + *ambient = ls->ambient_light; + + index = 0; + for (i = 0; i < ls->directional_light_count; ++i, ++index) + { + light = &ls->lights[index]; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, 1.0f); + if (normal) + update_light_diffuse_specular(diffuse, specular, &light->direction, 1.0f, material_shininess, + &normal_transformed, &position_transformed_normalised, light, ls); + } + + for (i = 0; i < ls->point_light_count; ++i, ++index) + { + light = &ls->lights[index]; + dir.x = light->position.x - ls->position_transformed.x; + dir.y = light->position.y - ls->position_transformed.y; + dir.z = light->position.z - ls->position_transformed.z; + + dst.z = wined3d_vec3_dot(&dir, &dir); + dst.y = sqrtf(dst.z); + dst.x = 1.0f; + if (ls->legacy_lighting) + { + dst.y = (light->range - dst.y) / light->range; + if (!(dst.y > 0.0f)) + continue; + dst.z = dst.y * dst.y; + } + else + { + if (!(dst.y <= light->range)) + continue; + } + att = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att; + if (!ls->legacy_lighting) + att = 1.0f / att; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, att); + if (normal) + { + wined3d_vec3_normalise(&dir); + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalised, light, ls); + } + } + + for (i = 0; i < ls->spot_light_count; ++i, ++index) + { + float t; + + light = &ls->lights[index]; + + dir.x = light->position.x - ls->position_transformed.x; + dir.y = light->position.y - ls->position_transformed.y; + dir.z = light->position.z - ls->position_transformed.z; + + dst.z = wined3d_vec3_dot(&dir, &dir); + dst.y = sqrtf(dst.z); + dst.x = 1.0f; -struct wined3d_sampler * CDECL wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx) -{ - TRACE("device %p, idx %u.\n", device, idx); + if (ls->legacy_lighting) + { + dst.y = (light->range - dst.y) / light->range; + if (!(dst.y > 0.0f)) + continue; + dst.z = dst.y * dst.y; + } + else + { + if (!(dst.y <= light->range)) + continue; + } + wined3d_vec3_normalise(&dir); + t = -wined3d_vec3_dot(&dir, &light->direction); + if (t > light->cos_htheta) + att = 1.0f; + else if (t <= light->cos_hphi) + att = 0.0f; + else + att = powf((t - light->cos_hphi) / (light->cos_htheta - light->cos_hphi), light->falloff); - return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_COMPUTE, idx); -} + t = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att; + if (ls->legacy_lighting) + att *= t; + else + att /= t; -static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_device *device, - enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav, - unsigned int initial_count) -{ - struct wined3d_unordered_access_view *prev; + wined3d_color_rgb_mul_add(ambient, &light->ambient, att); - if (idx >= MAX_UNORDERED_ACCESS_VIEWS) - { - WARN("Invalid UAV index %u.\n", idx); - return; + if (normal) + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalised, light, ls); } - prev = device->update_state->unordered_access_view[pipeline][idx]; - if (uav == prev && initial_count == ~0u) - return; + for (i = 0; i < ls->parallel_point_light_count; ++i, ++index) + { + light = &ls->lights[index]; - if (uav) - wined3d_unordered_access_view_incref(uav); - device->update_state->unordered_access_view[pipeline][idx] = uav; - if (!device->recording) - wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav, initial_count); - if (prev) - wined3d_unordered_access_view_decref(prev); + wined3d_color_rgb_mul_add(ambient, &light->ambient, 1.0f); + if (normal) + update_light_diffuse_specular(diffuse, specular, (const struct wined3d_vec3 *)&light->position, + 1.0f, material_shininess, &normal_transformed, &position_transformed_normalised, light, ls); + } } -static struct wined3d_unordered_access_view *wined3d_device_get_pipeline_unordered_access_view( - const struct wined3d_device *device, enum wined3d_pipeline pipeline, unsigned int idx) +static float wined3d_calculate_fog_factor(float fog_coord, const struct lights_settings *ls) { - if (idx >= MAX_UNORDERED_ACCESS_VIEWS) + switch (ls->fog_mode) { - WARN("Invalid UAV index %u.\n", idx); - return NULL; + case WINED3D_FOG_NONE: + return fog_coord; + case WINED3D_FOG_LINEAR: + return (ls->fog_end - fog_coord) / (ls->fog_end - ls->fog_start); + case WINED3D_FOG_EXP: + return expf(-fog_coord * ls->fog_density); + case WINED3D_FOG_EXP2: + return expf(-fog_coord * fog_coord * ls->fog_density * ls->fog_density); + default: + ERR("Unhandled fog mode %#x.\n", ls->fog_mode); + return 0.0f; } - - return device->state.unordered_access_view[pipeline][idx]; -} - -void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx, - struct wined3d_unordered_access_view *uav, unsigned int initial_count) -{ - TRACE("device %p, idx %u, uav %p, initial_count %#x.\n", device, idx, uav, initial_count); - - wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav, initial_count); } -struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const struct wined3d_device *device, - unsigned int idx) +static void update_fog_factor(float *fog_factor, struct lights_settings *ls) { - TRACE("device %p, idx %u.\n", device, idx); - - return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx); -} + float fog_coord; -void CDECL wined3d_device_set_unordered_access_view(struct wined3d_device *device, - unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count) -{ - TRACE("device %p, idx %u, uav %p, initial_count %#x.\n", device, idx, uav, initial_count); + if (ls->fog_mode == WINED3D_FOG_NONE) + return; - wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav, initial_count); -} + switch (ls->fog_coord_mode) + { + case WINED3D_FFP_VS_FOG_RANGE: + fog_coord = sqrtf(wined3d_vec3_dot((const struct wined3d_vec3 *)&ls->position_transformed, + (const struct wined3d_vec3 *)&ls->position_transformed)); + break; -struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access_view( - const struct wined3d_device *device, unsigned int idx) -{ - TRACE("device %p, idx %u.\n", device, idx); + case WINED3D_FFP_VS_FOG_DEPTH: + fog_coord = fabsf(ls->position_transformed.z); + break; - return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx); + default: + ERR("Unhandled fog coordinate mode %#x.\n", ls->fog_coord_mode); + return; + } + *fog_factor = wined3d_calculate_fog_factor(fog_coord, ls); } /* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, - const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags, - DWORD DestFVF) + const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags, DWORD dst_fvf) { + enum wined3d_material_color_source diffuse_source, specular_source, ambient_source, emissive_source; + const struct wined3d_color *material_specular_state_colour; struct wined3d_matrix mat, proj_mat, view_mat, world_mat; + const struct wined3d_state *state = &device->state; + const struct wined3d_format *output_colour_format; + static const struct wined3d_color black; struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; struct wined3d_viewport vp; - UINT vertex_size; + unsigned int texture_count; + struct lights_settings ls; + unsigned int vertex_size; + BOOL do_clip, lighting; unsigned int i; BYTE *dest_ptr; - BOOL doClip; - DWORD numTextures; HRESULT hr; - if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) - { - WARN(" lighting state not saved yet... Some strange stuff may happen !\n"); - } - if (!(stream_info->use_map & (1u << WINED3D_FFP_POSITION))) { - ERR("Source has no position mask\n"); + ERR("Source has no position mask.\n"); return WINED3DERR_INVALIDCALL; } - if (device->state.render_states[WINED3D_RS_CLIPPING]) + if (state->render_states[WINED3D_RS_CLIPPING]) { static BOOL warned = FALSE; /* @@ -3102,18 +3602,19 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO * so disable clipping for now. * (The graphics in Half-Life are broken, and my processvertices * test crashes with IDirect3DDevice3) - doClip = TRUE; + do_clip = TRUE; */ - doClip = FALSE; - if(!warned) { + do_clip = FALSE; + if (!warned) + { warned = TRUE; FIXME("Clipping is broken and disabled for now\n"); } } else - doClip = FALSE; + do_clip = FALSE; - vertex_size = get_flexible_vertex_size(DestFVF); + vertex_size = wined3d_get_flexible_vertex_size(dst_fvf); box.left = dwDestIndex * vertex_size; box.right = box.left + dwCount * vertex_size; if (FAILED(hr = wined3d_resource_map(&dest->resource, 0, &map_desc, &box, WINED3D_MAP_WRITE))) @@ -3146,23 +3647,43 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO TRACE("%.8e %.8e %.8e %.8e\n", world_mat._41, world_mat._42, world_mat._43, world_mat._44); /* Get the viewport */ - wined3d_device_get_viewport(device, &vp); - TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", + wined3d_device_get_viewports(device, NULL, &vp); + TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z); multiply_matrix(&mat,&view_mat,&world_mat); multiply_matrix(&mat,&proj_mat,&mat); - numTextures = (DestFVF & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; + texture_count = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; - for (i = 0; i < dwCount; i+= 1) { + lighting = state->render_states[WINED3D_RS_LIGHTING] + && (dst_fvf & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR)); + wined3d_get_material_colour_source(&diffuse_source, &emissive_source, + &ambient_source, &specular_source, state, stream_info); + output_colour_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0); + material_specular_state_colour = state->render_states[WINED3D_RS_SPECULARENABLE] + ? &state->material.specular : &black; + init_transformed_lights(&ls, state, device->adapter->d3d_info.wined3d_creation_flags + & WINED3D_LEGACY_FFP_LIGHTING, lighting); + + for (i = 0; i < dwCount; ++i) + { + const struct wined3d_stream_info_element *position_element = &stream_info->elements[WINED3D_FFP_POSITION]; + const float *p = (const float *)&position_element->data.addr[i * position_element->stride]; + struct wined3d_color ambient, diffuse, specular; + struct wined3d_vec4 position; unsigned int tex_index; - if ( ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) || - ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) { + position.x = p[0]; + position.y = p[1]; + position.z = p[2]; + position.w = 1.0f; + + light_set_vertex_data(&ls, &position); + + if ( ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) || + ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) { /* The position first */ - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_POSITION]; - const float *p = (const float *)(element->data.addr + i * element->stride); float x, y, z, rhw; TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]); @@ -3191,11 +3712,9 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO * */ - if( !doClip || - ( (-rhw -eps < x) && (-rhw -eps < y) && ( -eps < z) && - (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) && - ( rhw > eps ) ) ) { - + if (!do_clip || (-rhw - eps < x && -rhw - eps < y && -eps < z && x <= rhw + eps + && y <= rhw + eps && z <= rhw + eps && rhw > eps)) + { /* "Normal" viewport transformation (not clipped) * 1) The values are divided by rhw * 2) The y axis is negative, so multiply it with -1 @@ -3254,14 +3773,14 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO dest_ptr += 3 * sizeof(float); - if ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW) + if ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW) dest_ptr += sizeof(float); } - if (DestFVF & WINED3DFVF_PSIZE) + if (dst_fvf & WINED3DFVF_PSIZE) dest_ptr += sizeof(DWORD); - if (DestFVF & WINED3DFVF_NORMAL) + if (dst_fvf & WINED3DFVF_NORMAL) { const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_NORMAL]; const float *normal = (const float *)(element->data.addr + i * element->stride); @@ -3270,63 +3789,91 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO copy_and_next(dest_ptr, normal, 3 * sizeof(float)); } - if (DestFVF & WINED3DFVF_DIFFUSE) + if (lighting) { - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; - const DWORD *color_d = (const DWORD *)(element->data.addr + i * element->stride); - if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE))) + const struct wined3d_stream_info_element *element; + struct wined3d_vec3 *normal; + + if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) { - static BOOL warned = FALSE; + element = &stream_info->elements[WINED3D_FFP_NORMAL]; + normal = (struct wined3d_vec3 *)&element->data.addr[i * element->stride]; + } + else + { + normal = NULL; + } + compute_light(&ambient, &diffuse, &specular, &ls, normal, + state->render_states[WINED3D_RS_SPECULARENABLE] ? state->material.power : 0.0f); + } - if(!warned) { - ERR("No diffuse color in source, but destination has one\n"); - warned = TRUE; - } + if (dst_fvf & WINED3DFVF_DIFFUSE) + { + struct wined3d_color material_diffuse, material_ambient, material_emissive, diffuse_colour; + + wined3d_colour_from_mcs(&material_diffuse, diffuse_source, + &state->material.diffuse, i, stream_info); - *( (DWORD *) dest_ptr) = 0xffffffff; - dest_ptr += sizeof(DWORD); + if (lighting) + { + wined3d_colour_from_mcs(&material_ambient, ambient_source, + &state->material.ambient, i, stream_info); + wined3d_colour_from_mcs(&material_emissive, emissive_source, + &state->material.emissive, i, stream_info); + + diffuse_colour.r = ambient.r * material_ambient.r + + diffuse.r * material_diffuse.r + material_emissive.r; + diffuse_colour.g = ambient.g * material_ambient.g + + diffuse.g * material_diffuse.g + material_emissive.g; + diffuse_colour.b = ambient.b * material_ambient.b + + diffuse.b * material_diffuse.b + material_emissive.b; + diffuse_colour.a = material_diffuse.a; } else { - copy_and_next(dest_ptr, color_d, sizeof(DWORD)); + diffuse_colour = material_diffuse; } + wined3d_color_clamp(&diffuse_colour, &diffuse_colour, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &diffuse_colour); + dest_ptr += sizeof(DWORD); } - if (DestFVF & WINED3DFVF_SPECULAR) + if (dst_fvf & WINED3DFVF_SPECULAR) { - /* What's the color value in the feedback buffer? */ - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR]; - const DWORD *color_s = (const DWORD *)(element->data.addr + i * element->stride); - if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR))) - { - static BOOL warned = FALSE; + struct wined3d_color material_specular, specular_colour; - if(!warned) { - ERR("No specular color in source, but destination has one\n"); - warned = TRUE; - } + wined3d_colour_from_mcs(&material_specular, specular_source, + material_specular_state_colour, i, stream_info); - *(DWORD *)dest_ptr = 0xff000000; - dest_ptr += sizeof(DWORD); + if (lighting) + { + specular_colour.r = specular.r * material_specular.r; + specular_colour.g = specular.g * material_specular.g; + specular_colour.b = specular.b * material_specular.b; + specular_colour.a = ls.legacy_lighting ? 0.0f : material_specular.a; } else { - copy_and_next(dest_ptr, color_s, sizeof(DWORD)); + specular_colour = material_specular; } + update_fog_factor(&specular_colour.a, &ls); + wined3d_color_clamp(&specular_colour, &specular_colour, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &specular_colour); + dest_ptr += sizeof(DWORD); } - for (tex_index = 0; tex_index < numTextures; ++tex_index) + for (tex_index = 0; tex_index < texture_count; ++tex_index) { const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index]; const float *tex_coord = (const float *)(element->data.addr + i * element->stride); if (!(stream_info->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + tex_index)))) { ERR("No source texture, but destination requests one\n"); - dest_ptr += GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float); + dest_ptr += GET_TEXCOORD_SIZE_FROM_FVF(dst_fvf, tex_index) * sizeof(float); } else { - copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float)); + copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(dst_fvf, tex_index) * sizeof(float)); } } } @@ -3346,7 +3893,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, struct wined3d_resource *resource; struct wined3d_box box = {0}; struct wined3d_shader *vs; - unsigned int i; + unsigned int i, j; HRESULT hr; WORD map; @@ -3360,7 +3907,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; - wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->gl_info, &device->adapter->d3d_info); + wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->d3d_info); state->shader[WINED3D_SHADER_TYPE_VERTEX] = vs; /* We can't convert FROM a VBO, and vertex buffers used to source into @@ -3381,7 +3928,20 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, box.left = src_start_idx * e->stride; box.right = box.left + vertex_count * e->stride; if (FAILED(wined3d_resource_map(resource, 0, &map_desc, &box, WINED3D_MAP_READ))) + { ERR("Failed to map resource.\n"); + for (j = 0, map = stream_info.use_map; map && j < i; map >>= 1, ++j) + { + if (!(map & 1)) + continue; + + e = &stream_info.elements[j]; + resource = &state->streams[e->stream_idx].buffer->resource; + if (FAILED(wined3d_resource_unmap(resource, 0))) + ERR("Failed to unmap resource.\n"); + } + return WINED3DERR_INVALIDCALL; + } e->data.buffer_object = 0; e->data.addr += (ULONG_PTR)map_desc.data; } @@ -3406,7 +3966,6 @@ void CDECL wined3d_device_set_texture_stage_state(struct wined3d_device *device, UINT stage, enum wined3d_texture_stage_state state, DWORD value) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - DWORD old_value; TRACE("device %p, stage %u, state %s, value %#x.\n", device, stage, debug_d3dtexturestate(state), value); @@ -3424,8 +3983,7 @@ void CDECL wined3d_device_set_texture_stage_state(struct wined3d_device *device, return; } - old_value = device->update_state->texture_states[stage][state]; - device->update_state->texture_states[stage][state] = value; + device->update_stateblock_state->texture_states[stage][state] = value; if (device->recording) { @@ -3434,13 +3992,14 @@ void CDECL wined3d_device_set_texture_stage_state(struct wined3d_device *device, return; } - /* Checked after the assignments to allow proper stateblock recording. */ - if (old_value == value) + if (value == device->state.texture_states[stage][state]) { TRACE("Application is setting the old value over, nothing to do.\n"); return; } + device->state.texture_states[stage][state] = value; + wined3d_cs_emit_set_texture_state(device->cs, stage, state, value); } @@ -3459,7 +4018,7 @@ DWORD CDECL wined3d_device_get_texture_stage_state(const struct wined3d_device * return device->state.texture_states[stage][state]; } -HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, +void CDECL wined3d_device_set_texture(struct wined3d_device *device, UINT stage, struct wined3d_texture *texture) { struct wined3d_texture *prev; @@ -3467,44 +4026,46 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, TRACE("device %p, stage %u, texture %p.\n", device, stage, texture); if (stage >= WINED3DVERTEXTEXTURESAMPLER0 && stage <= WINED3DVERTEXTEXTURESAMPLER3) - stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS); + stage -= (WINED3DVERTEXTEXTURESAMPLER0 - WINED3D_MAX_FRAGMENT_SAMPLERS); /* Windows accepts overflowing this array... we do not. */ if (stage >= ARRAY_SIZE(device->state.textures)) { WARN("Ignoring invalid stage %u.\n", stage); - return WINED3D_OK; + return; } - if (texture && texture->resource.usage & WINED3DUSAGE_SCRATCH) - { - WARN("Rejecting attempt to set scratch texture.\n"); - return WINED3DERR_INVALIDCALL; - } + if (texture) + wined3d_texture_incref(texture); + if (device->update_stateblock_state->textures[stage]) + wined3d_texture_decref(device->update_stateblock_state->textures[stage]); + device->update_stateblock_state->textures[stage] = texture; if (device->recording) + { device->recording->changed.textures |= 1u << stage; + return; + } - prev = device->update_state->textures[stage]; + prev = device->state.textures[stage]; TRACE("Previous texture %p.\n", prev); if (texture == prev) { TRACE("App is setting the same texture again, nothing to do.\n"); - return WINED3D_OK; + return; } TRACE("Setting new texture to %p.\n", texture); - device->update_state->textures[stage] = texture; + device->state.textures[stage] = texture; if (texture) wined3d_texture_incref(texture); - if (!device->recording) - wined3d_cs_emit_set_texture(device->cs, stage, texture); + wined3d_cs_emit_set_texture(device->cs, stage, texture); if (prev) wined3d_texture_decref(prev); - return WINED3D_OK; + return; } struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_device *device, UINT stage) @@ -3512,7 +4073,7 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d TRACE("device %p, stage %u.\n", device, stage); if (stage >= WINED3DVERTEXTEXTURESAMPLER0 && stage <= WINED3DVERTEXTEXTURESAMPLER3) - stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS); + stage -= (WINED3DVERTEXTEXTURESAMPLER0 - WINED3D_MAX_FRAGMENT_SAMPLERS); if (stage >= ARRAY_SIZE(device->state.textures)) { @@ -3523,19 +4084,33 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d return device->state.textures[stage]; } -HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps) +HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps) { +#if defined(STAGING_CSMT) + const struct wined3d_adapter *adapter = device->wined3d->adapters[device->adapter->ordinal]; + struct wined3d_vertex_caps vertex_caps; HRESULT hr; - TRACE("device %p, caps %p.\n", device, caps); + TRACE("device %p, caps %p.\n", device, caps); hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, - device->create_parms.device_type, caps); - - if (SUCCEEDED(hr) && use_software_vertex_processing(device)) - caps->MaxVertexBlendMatrixIndex = 255; + device->create_parms.device_type, caps); + if (FAILED(hr)) + return hr; + adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); + if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; + caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; + if (!((device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) + && device->softwareVertexProcessing))) + caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); return hr; +#else + return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, + device->create_parms.device_type, caps); +#endif } HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, @@ -3552,49 +4127,53 @@ HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *devic return wined3d_swapchain_get_display_mode(swapchain, mode, rotation); } -HRESULT CDECL wined3d_device_begin_stateblock(struct wined3d_device *device) +HRESULT CDECL wined3d_device_begin_stateblock(struct wined3d_device *device, + struct wined3d_stateblock **stateblock) { - struct wined3d_stateblock *stateblock; + struct wined3d_stateblock *object; HRESULT hr; TRACE("device %p.\n", device); if (device->recording) + { + *stateblock = NULL; return WINED3DERR_INVALIDCALL; + } - hr = wined3d_stateblock_create(device, WINED3D_SBT_RECORDED, &stateblock); + hr = wined3d_stateblock_create(device, WINED3D_SBT_RECORDED, &object); if (FAILED(hr)) return hr; - device->recording = stateblock; - device->update_state = &stateblock->state; + device->recording = object; + device->update_stateblock_state = &object->stateblock_state; + wined3d_stateblock_incref(object); + *stateblock = object; - TRACE("Recording stateblock %p.\n", stateblock); + TRACE("Recording stateblock %p.\n", *stateblock); return WINED3D_OK; } -HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device, - struct wined3d_stateblock **stateblock) +HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device) { - struct wined3d_stateblock *object = device->recording; + struct wined3d_stateblock *stateblock = device->recording; - TRACE("device %p, stateblock %p.\n", device, stateblock); + TRACE("device %p.\n", device); if (!device->recording) { WARN("Not recording.\n"); - *stateblock = NULL; return WINED3DERR_INVALIDCALL; } - stateblock_init_contained_states(object); + stateblock_init_contained_states(stateblock); - *stateblock = object; + wined3d_stateblock_decref(device->recording); device->recording = NULL; - device->update_state = &device->state; + device->update_stateblock_state = &device->stateblock_state; - TRACE("Returning stateblock %p.\n", *stateblock); + TRACE("Ending stateblock %p.\n", stateblock); return WINED3D_OK; } @@ -3624,8 +4203,6 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) return WINED3DERR_INVALIDCALL; } - wined3d_cs_emit_flush(device->cs); - device->inScene = FALSE; return WINED3D_OK; } @@ -3674,16 +4251,15 @@ void CDECL wined3d_device_set_predication(struct wined3d_device *device, TRACE("device %p, predicate %p, value %#x.\n", device, predicate, value); - prev = device->update_state->predicate; + prev = device->state.predicate; if (predicate) { FIXME("Predicated rendering not implemented.\n"); wined3d_query_incref(predicate); } - device->update_state->predicate = predicate; - device->update_state->predicate_value = value; - if (!device->recording) - wined3d_cs_emit_set_predication(device->cs, predicate, value); + device->state.predicate = predicate; + device->state.predicate_value = value; + wined3d_cs_emit_set_predication(device->cs, predicate, value); if (prev) wined3d_query_decref(prev); } @@ -3811,7 +4387,6 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, unsigned int src_size, dst_size, src_skip_levels = 0; unsigned int src_level_count, dst_level_count; unsigned int layer_count, level_count, i, j; - unsigned int width, height, depth; enum wined3d_resource_type type; struct wined3d_box box; @@ -3862,12 +4437,9 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, level_count = min(src_level_count, dst_level_count); src_size = max(src_texture->resource.width, src_texture->resource.height); + src_size = max(src_size, src_texture->resource.depth); dst_size = max(dst_texture->resource.width, dst_texture->resource.height); - if (type == WINED3D_RTYPE_TEXTURE_3D) - { - src_size = max(src_size, src_texture->resource.depth); - dst_size = max(dst_size, dst_texture->resource.depth); - } + dst_size = max(dst_size, dst_texture->resource.depth); while (src_size > dst_size) { src_size >>= 1; @@ -3885,11 +4457,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, /* Update every surface level of the texture. */ for (i = 0; i < level_count; ++i) { - width = wined3d_texture_get_level_width(dst_texture, i); - height = wined3d_texture_get_level_height(dst_texture, i); - depth = wined3d_texture_get_level_depth(dst_texture, i); - wined3d_box_set(&box, 0, 0, width, height, 0, depth); - + wined3d_texture_get_level_box(dst_texture, i, &box); for (j = 0; j < layer_count; ++j) { wined3d_cs_emit_blt_sub_resource(device->cs, @@ -3910,7 +4478,7 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device TRACE("device %p, num_passes %p.\n", device, num_passes); - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { if (state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] == WINED3D_TEXF_NONE) { @@ -3967,7 +4535,14 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software) { TRACE("device %p, software %#x.\n", device, software); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!device->softwareVertexProcessing != !software) + { + unsigned int i; + for (i = 0; i < device->context_count; ++i) + device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; + } device->softwareVertexProcessing = software; } @@ -4104,10 +4679,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, for (i = 0; i < dst_texture->level_count; ++i) { - wined3d_box_set(&box, 0, 0, - wined3d_texture_get_level_width(dst_texture, i), - wined3d_texture_get_level_height(dst_texture, i), - 0, wined3d_texture_get_level_depth(dst_texture, i)); + wined3d_texture_get_level_box(dst_texture, i, &box); for (j = 0; j < dst_texture->layer_count; ++j) { unsigned int idx = j * dst_texture->level_count + i; @@ -4121,14 +4693,17 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *device, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags) { struct wined3d_box dst_box, b; TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " - "src_resource %p, src_sub_resource_idx %u, src_box %s.\n", + "src_resource %p, src_sub_resource_idx %u, src_box %s, flags %#x.\n", device, dst_resource, dst_sub_resource_idx, dst_x, dst_y, dst_z, - src_resource, src_sub_resource_idx, debug_box(src_box)); + src_resource, src_sub_resource_idx, debug_box(src_box), flags); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); if (src_resource == dst_resource && src_sub_resource_idx == dst_sub_resource_idx) { @@ -4136,14 +4711,6 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } - if (src_resource->type != dst_resource->type) - { - WARN("Resource types (%s / %s) don't match.\n", - debug_d3dresourcetype(dst_resource->type), - debug_d3dresourcetype(src_resource->type)); - return WINED3DERR_INVALIDCALL; - } - if (src_resource->format->typeless_id != dst_resource->format->typeless_id || (!src_resource->format->typeless_id && src_resource->format->id != dst_resource->format->id)) { @@ -4155,6 +4722,14 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev if (dst_resource->type == WINED3D_RTYPE_BUFFER) { + if (src_resource->type != WINED3D_RTYPE_BUFFER) + { + WARN("Resource types (%s / %s) don't match.\n", + debug_d3dresourcetype(dst_resource->type), + debug_d3dresourcetype(src_resource->type)); + return WINED3DERR_INVALIDCALL; + } + if (dst_sub_resource_idx) { WARN("Invalid dst_sub_resource_idx %u.\n", dst_sub_resource_idx); @@ -4193,7 +4768,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev wined3d_box_set(&dst_box, dst_x, 0, dst_x + (src_box->right - src_box->left), 1, 0, 1); } - else if (dst_resource->type == WINED3D_RTYPE_TEXTURE_2D) + else { struct wined3d_texture *dst_texture = texture_from_resource(dst_resource); struct wined3d_texture *src_texture = texture_from_resource(src_resource); @@ -4239,16 +4814,18 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev if (!src_box) { - unsigned int src_w, src_h, dst_w, dst_h, dst_level; + unsigned int src_w, src_h, src_d, dst_w, dst_h, dst_d, dst_level; src_w = wined3d_texture_get_level_width(src_texture, src_level); src_h = wined3d_texture_get_level_height(src_texture, src_level); + src_d = wined3d_texture_get_level_depth(src_texture, src_level); dst_level = dst_sub_resource_idx % dst_texture->level_count; dst_w = wined3d_texture_get_level_width(dst_texture, dst_level) - dst_x; dst_h = wined3d_texture_get_level_height(dst_texture, dst_level) - dst_y; + dst_d = wined3d_texture_get_level_depth(dst_texture, dst_level) - dst_z; - wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, 1); + wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, min(src_d, dst_d)); src_box = &b; } else if (FAILED(wined3d_texture_check_box_dimensions(src_texture, src_level, src_box))) @@ -4258,7 +4835,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev } wined3d_box_set(&dst_box, dst_x, dst_y, dst_x + (src_box->right - src_box->left), - dst_y + (src_box->bottom - src_box->top), 0, 1); + dst_y + (src_box->bottom - src_box->top), dst_z, dst_z + (src_box->back - src_box->front)); if (FAILED(wined3d_texture_check_box_dimensions(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_box))) { @@ -4266,11 +4843,6 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } } - else - { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); - return WINED3DERR_INVALIDCALL; - } wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box, src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT); @@ -4280,13 +4852,23 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch) + unsigned int depth_pitch, unsigned int flags) { unsigned int width, height, depth; struct wined3d_box b; - TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n", - device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch); + TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u, " + "flags %#x.\n", + device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch, flags); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + if (!(resource->access & WINED3D_RESOURCE_ACCESS_GPU)) + { + WARN("Resource %p is not GPU accessible.\n", resource); + return; + } if (resource->type == WINED3D_RTYPE_BUFFER) { @@ -4300,8 +4882,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str height = 1; depth = 1; } - else if (resource->type == WINED3D_RTYPE_TEXTURE_1D || - resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D) + else { struct wined3d_texture *texture = texture_from_resource(resource); unsigned int level; @@ -4317,11 +4898,6 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str height = wined3d_texture_get_level_height(texture, level); depth = wined3d_texture_get_level_depth(texture, level); } - else - { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); - return; - } if (!box) { @@ -4360,10 +4936,10 @@ void CDECL wined3d_device_resolve_sub_resource(struct wined3d_device *device, if (wined3d_format_is_typeless(dst_resource->format) || wined3d_format_is_typeless(src_resource->format)) { - FIXME("Unhandled multisample resolve, dst_format %s, src_format %s, format %s.\n", + FIXME("Multisample resolve is not fully supported for typeless formats " + "(dst_format %s, src_format %s, format %s).\n", debug_d3dformat(dst_resource->format->id), debug_d3dformat(src_resource->format->id), debug_d3dformat(format_id)); - return; } if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D) { @@ -4403,13 +4979,13 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi return WINED3D_OK; resource = view->resource; - if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + if (resource->type == WINED3D_RTYPE_BUFFER) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); return WINED3DERR_INVALIDCALL; } - if (view->layer_count > 1) + if (view->layer_count != max(1, resource->depth >> view->desc.u.texture.level_idx)) { FIXME("Layered clears not implemented.\n"); return WINED3DERR_INVALIDCALL; @@ -4447,11 +5023,14 @@ void CDECL wined3d_device_clear_unordered_access_view_uint(struct wined3d_device struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device, unsigned int view_idx) { + unsigned int max_rt_count; + TRACE("device %p, view_idx %u.\n", device, view_idx); - if (view_idx >= device->adapter->gl_info.limits.buffers) + max_rt_count = device->adapter->d3d_info.limits.max_rt_count; + if (view_idx >= max_rt_count) { - WARN("Only %u render targets are supported.\n", device->adapter->gl_info.limits.buffers); + WARN("Only %u render targets are supported.\n", max_rt_count); return NULL; } @@ -4469,19 +5048,21 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) { struct wined3d_rendertarget_view *prev; + unsigned int max_rt_count; TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", device, view_idx, view, set_viewport); - if (view_idx >= device->adapter->gl_info.limits.buffers) + max_rt_count = device->adapter->d3d_info.limits.max_rt_count; + if (view_idx >= max_rt_count) { - WARN("Only %u render targets are supported.\n", device->adapter->gl_info.limits.buffers); + WARN("Only %u render targets are supported.\n", max_rt_count); return WINED3DERR_INVALIDCALL; } - if (view && !(view->resource->usage & WINED3DUSAGE_RENDERTARGET)) + if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) { - WARN("View resource %p doesn't have render target usage.\n", view->resource); + WARN("View resource %p doesn't have render target bind flags.\n", view->resource); return WINED3DERR_INVALIDCALL; } @@ -4492,19 +5073,22 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device { struct wined3d_state *state = &device->state; - state->viewport.x = 0; - state->viewport.y = 0; - state->viewport.width = view->width; - state->viewport.height = view->height; - state->viewport.min_z = 0.0f; - state->viewport.max_z = 1.0f; - wined3d_cs_emit_set_viewport(device->cs, &state->viewport); + state->viewports[0].x = 0; + state->viewports[0].y = 0; + state->viewports[0].width = view->width; + state->viewports[0].height = view->height; + state->viewports[0].min_z = 0.0f; + state->viewports[0].max_z = 1.0f; + state->viewport_count = 1; + wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports); + device->stateblock_state.viewport = state->viewports[0]; - SetRect(&state->scissor_rect, 0, 0, view->width, view->height); - wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); + SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); + state->scissor_rect_count = 1; + wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects); + device->stateblock_state.scissor_rect = state->scissor_rects[0]; } - prev = device->fb.render_targets[view_idx]; if (view == prev) return WINED3D_OK; @@ -4521,17 +5105,25 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device return WINED3D_OK; } -void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) +HRESULT CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, + struct wined3d_rendertarget_view *view) { struct wined3d_rendertarget_view *prev; TRACE("device %p, view %p.\n", device, view); + if (view && !(view->resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL)) + { + WARN("View resource %p has incompatible %s bind flags.\n", + view->resource, wined3d_debug_bind_flags(view->resource->bind_flags)); + return WINED3DERR_INVALIDCALL; + } + prev = device->fb.depth_stencil; if (prev == view) { TRACE("Trying to do a NOP SetRenderTarget operation.\n"); - return; + return WINED3D_OK; } if ((device->fb.depth_stencil = view)) @@ -4539,6 +5131,8 @@ void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, wined3d_cs_emit_set_depth_stencil_view(device->cs, view); if (prev) wined3d_rendertarget_view_decref(prev); + + return WINED3D_OK; } static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, @@ -4566,14 +5160,14 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = WINED3DUSAGE_DYNAMIC; + desc.bind_flags = 0; desc.access = WINED3D_RESOURCE_ACCESS_GPU; desc.width = wined3d_texture_get_level_width(cursor_image, texture_level); desc.height = wined3d_texture_get_level_height(cursor_image, texture_level); desc.depth = 1; desc.size = 0; - hr = wined3d_texture_create(device, &desc, 1, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, - &data, NULL, &wined3d_null_parent_ops, &texture); + hr = wined3d_texture_create(device, &desc, 1, 1, 0, &data, NULL, &wined3d_null_parent_ops, &texture); wined3d_resource_unmap(&cursor_image->resource, sub_resource_idx); if (FAILED(hr)) { @@ -4768,27 +5362,48 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) } } +static void update_swapchain_flags(struct wined3d_texture *texture) +{ + unsigned int flags = texture->swapchain->state.desc.flags; + + if (flags & WINED3D_SWAPCHAIN_LOCKABLE_BACKBUFFER) + texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + else + texture->resource.access &= ~(WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W); + + if (flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + texture->flags |= WINED3D_TEXTURE_GET_DC; + else + texture->flags &= ~WINED3D_TEXTURE_GET_DC; +} + HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state) { + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + struct wined3d_swapchain_state *swapchain_state; + struct wined3d_swapchain_desc *current_desc; struct wined3d_resource *resource, *cursor; + struct wined3d_rendertarget_view *view; struct wined3d_swapchain *swapchain; struct wined3d_view_desc view_desc; - BOOL backbuffer_resized; + BOOL backbuffer_resized, windowed; HRESULT hr = WINED3D_OK; unsigned int i; TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", device, swapchain_desc, mode, callback, reset_state); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); if (!(swapchain = wined3d_device_get_swapchain(device, 0))) { ERR("Failed to get the first implicit swapchain.\n"); return WINED3DERR_INVALIDCALL; } + swapchain_state = &swapchain->state; + current_desc = &swapchain_state->desc; if (reset_state) { @@ -4802,10 +5417,11 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_texture_decref(device->cursor_texture); device->cursor_texture = NULL; } + wined3d_stateblock_state_cleanup(&device->stateblock_state); state_unbind_resources(&device->state); } - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + for (i = 0; i < d3d_info->limits.max_rt_count; ++i) { wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); } @@ -4836,11 +5452,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, TRACE("auto_depth_stencil_format %s\n", debug_d3dformat(swapchain_desc->auto_depth_stencil_format)); TRACE("flags %#x\n", swapchain_desc->flags); TRACE("refresh_rate %u\n", swapchain_desc->refresh_rate); - TRACE("swap_interval %u\n", swapchain_desc->swap_interval); TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode); - if (swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET) - FIXME("Got unexpected backbuffer usage %#x.\n", swapchain_desc->backbuffer_usage); + if (swapchain_desc->backbuffer_bind_flags && swapchain_desc->backbuffer_bind_flags != WINED3D_BIND_RENDER_TARGET) + FIXME("Got unexpected backbuffer bind flags %#x.\n", swapchain_desc->backbuffer_bind_flags); if (swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_DISCARD && swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_SEQUENTIAL @@ -4848,49 +5463,63 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, FIXME("Unimplemented swap effect %#x.\n", swapchain_desc->swap_effect); /* No special treatment of these parameters. Just store them */ - swapchain->desc.swap_effect = swapchain_desc->swap_effect; - swapchain->desc.enable_auto_depth_stencil = swapchain_desc->enable_auto_depth_stencil; - swapchain->desc.auto_depth_stencil_format = swapchain_desc->auto_depth_stencil_format; - swapchain->desc.flags = swapchain_desc->flags; - swapchain->desc.refresh_rate = swapchain_desc->refresh_rate; - swapchain->desc.swap_interval = swapchain_desc->swap_interval; - swapchain->desc.auto_restore_display_mode = swapchain_desc->auto_restore_display_mode; + current_desc->swap_effect = swapchain_desc->swap_effect; + current_desc->enable_auto_depth_stencil = swapchain_desc->enable_auto_depth_stencil; + current_desc->auto_depth_stencil_format = swapchain_desc->auto_depth_stencil_format; + current_desc->refresh_rate = swapchain_desc->refresh_rate; + current_desc->auto_restore_display_mode = swapchain_desc->auto_restore_display_mode; - if (swapchain_desc->device_window - && swapchain_desc->device_window != swapchain->desc.device_window) + if (swapchain_desc->device_window && swapchain_desc->device_window != current_desc->device_window) { TRACE("Changing the device window from %p to %p.\n", - swapchain->desc.device_window, swapchain_desc->device_window); - swapchain->desc.device_window = swapchain_desc->device_window; - swapchain->device_window = swapchain_desc->device_window; + current_desc->device_window, swapchain_desc->device_window); + current_desc->device_window = swapchain_desc->device_window; + swapchain_state->device_window = swapchain_desc->device_window; wined3d_swapchain_set_window(swapchain, NULL); } - backbuffer_resized = swapchain_desc->backbuffer_width != swapchain->desc.backbuffer_width - || swapchain_desc->backbuffer_height != swapchain->desc.backbuffer_height; + backbuffer_resized = swapchain_desc->backbuffer_width != current_desc->backbuffer_width + || swapchain_desc->backbuffer_height != current_desc->backbuffer_height; + windowed = current_desc->windowed; - if (!swapchain_desc->windowed != !swapchain->desc.windowed - || swapchain->reapply_mode || mode - || (!swapchain_desc->windowed && backbuffer_resized)) + if (!swapchain_desc->windowed != !windowed || swapchain->reapply_mode + || mode || (!swapchain_desc->windowed && backbuffer_resized)) { - if (FAILED(hr = wined3d_swapchain_set_fullscreen(swapchain, swapchain_desc, mode))) + /* Switch from windowed to fullscreen. */ + if (windowed && !swapchain_desc->windowed) + { + HWND focus_window = device->create_parms.focus_window; + + if (!focus_window) + focus_window = swapchain->state.device_window; + if (FAILED(hr = wined3d_device_acquire_focus_window(device, focus_window))) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + return hr; + } + } + if (FAILED(hr = wined3d_swapchain_state_set_fullscreen(&swapchain->state, + swapchain_desc, device->wined3d, device->adapter->ordinal, mode))) return hr; + + /* Switch from fullscreen to windowed. */ + if (!windowed && swapchain_desc->windowed) + wined3d_device_release_focus_window(device); } else if (!swapchain_desc->windowed) { - DWORD style = device->style; - DWORD exStyle = device->exStyle; - /* If we're in fullscreen, and the mode wasn't changed, we have to get the window back into - * the right position. Some applications(Battlefield 2, Guild Wars) move it and then call - * Reset to clear up their mess. Guild Wars also loses the device during that. - */ - device->style = 0; - device->exStyle = 0; - wined3d_device_setup_fullscreen_window(device, swapchain->device_window, - swapchain_desc->backbuffer_width, - swapchain_desc->backbuffer_height); - device->style = style; - device->exStyle = exStyle; + DWORD style = swapchain_state->style; + DWORD exstyle = swapchain_state->exstyle; + /* If we're in fullscreen, and the mode wasn't changed, we have to get + * the window back into the right position. Some applications + * (Battlefield 2, Guild Wars) move it and then call Reset() to clean + * up their mess. Guild Wars also loses the device during that. */ + swapchain_state->style = 0; + swapchain_state->exstyle = 0; + wined3d_swapchain_state_setup_fullscreen(swapchain_state, swapchain_state->device_window, + swapchain_desc->backbuffer_width, swapchain_desc->backbuffer_height); + swapchain_state->style = style; + swapchain_state->exstyle = exstyle; } if (FAILED(hr = wined3d_swapchain_resize_buffers(swapchain, swapchain_desc->backbuffer_count, @@ -4898,35 +5527,43 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, swapchain_desc->multisample_type, swapchain_desc->multisample_quality))) return hr; - if (device->auto_depth_stencil_view) + if (swapchain_desc->flags != current_desc->flags) + { + current_desc->flags = swapchain_desc->flags; + + update_swapchain_flags(swapchain->front_buffer); + for (i = 0; i < current_desc->backbuffer_count; ++i) + { + update_swapchain_flags(swapchain->back_buffers[i]); + } + } + + if ((view = device->auto_depth_stencil_view)) { - wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); device->auto_depth_stencil_view = NULL; + wined3d_rendertarget_view_decref(view); } - if (swapchain->desc.enable_auto_depth_stencil) + if (current_desc->enable_auto_depth_stencil) { struct wined3d_resource_desc texture_desc; struct wined3d_texture *texture; - DWORD flags = 0; TRACE("Creating the depth stencil buffer.\n"); texture_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - texture_desc.format = swapchain->desc.auto_depth_stencil_format; - texture_desc.multisample_type = swapchain->desc.multisample_type; - texture_desc.multisample_quality = swapchain->desc.multisample_quality; - texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL; + texture_desc.format = current_desc->auto_depth_stencil_format; + texture_desc.multisample_type = current_desc->multisample_type; + texture_desc.multisample_quality = current_desc->multisample_quality; + texture_desc.usage = 0; + texture_desc.bind_flags = WINED3D_BIND_DEPTH_STENCIL; texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU; - texture_desc.width = swapchain->desc.backbuffer_width; - texture_desc.height = swapchain->desc.backbuffer_height; + texture_desc.width = current_desc->backbuffer_width; + texture_desc.height = current_desc->backbuffer_height; texture_desc.depth = 1; texture_desc.size = 0; - if (swapchain_desc->flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) - flags |= WINED3D_TEXTURE_CREATE_GET_DC; - if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, - device->device_parent, &texture_desc, flags, &texture))) + device->device_parent, &texture_desc, 0, &texture))) { ERR("Failed to create the auto depth/stencil surface, hr %#x.\n", hr); return WINED3DERR_INVALIDCALL; @@ -4950,12 +5587,12 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); } - if (device->back_buffer_view) + if ((view = device->back_buffer_view)) { - wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; + wined3d_rendertarget_view_decref(view); } - if (swapchain->desc.backbuffer_count) + if (current_desc->backbuffer_count && current_desc->backbuffer_bind_flags & WINED3D_BIND_RENDER_TARGET) { struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; @@ -4987,41 +5624,39 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, state_cleanup(&device->state); if (device->d3d_initialized) - wined3d_device_delete_opengl_contexts(device); + device->adapter->adapter_ops->adapter_uninit_3d(device); memset(&device->state, 0, sizeof(device->state)); - state_init(&device->state, &device->fb, &device->adapter->gl_info, - &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); - device->update_state = &device->state; + state_init(&device->state, &device->fb, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); + memset(&device->stateblock_state, 0, sizeof(device->stateblock_state)); + wined3d_stateblock_state_init(&device->stateblock_state, device, WINED3D_STATE_INIT_DEFAULT); + device->update_stateblock_state = &device->stateblock_state; device_init_swapchain_state(device, swapchain); if (wined3d_settings.logo) device_load_logo(device, wined3d_settings.logo); } - else if (device->back_buffer_view) + else if ((view = device->back_buffer_view)) { - struct wined3d_rendertarget_view *view = device->back_buffer_view; struct wined3d_state *state = &device->state; wined3d_device_set_rendertarget_view(device, 0, view, FALSE); /* Note the min_z / max_z is not reset. */ - state->viewport.x = 0; - state->viewport.y = 0; - state->viewport.width = view->width; - state->viewport.height = view->height; - wined3d_cs_emit_set_viewport(device->cs, &state->viewport); + state->viewports[0].x = 0; + state->viewports[0].y = 0; + state->viewports[0].width = view->width; + state->viewports[0].height = view->height; + state->viewport_count = 1; + wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports); - SetRect(&state->scissor_rect, 0, 0, view->width, view->height); - wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); + SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); + state->scissor_rect_count = 1; + wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects); } - if (device->d3d_initialized) - { - if (reset_state) - hr = wined3d_device_create_primary_opengl_context(device); - swapchain_update_swap_interval(swapchain); - } + if (device->d3d_initialized && reset_state) + hr = device->adapter->adapter_ops->adapter_init_3d(device); /* All done. There is no need to reload resources or shaders, this will happen automatically on the * first use @@ -5054,6 +5689,13 @@ struct wined3d * CDECL wined3d_device_get_wined3d(const struct wined3d_device *d return device->wined3d; } +enum wined3d_feature_level CDECL wined3d_device_get_feature_level(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->feature_level; +} + void CDECL wined3d_device_set_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp) { @@ -5106,7 +5748,7 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso if (device->d3d_initialized) { - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + for (i = 0; i < ARRAY_SIZE(device->fb.render_targets); ++i) { if ((rtv = device->fb.render_targets[i]) && rtv->resource == resource) ERR("Resource %p is still in use as render target %u.\n", resource, i); @@ -5121,57 +5763,51 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso case WINED3D_RTYPE_TEXTURE_1D: case WINED3D_RTYPE_TEXTURE_2D: case WINED3D_RTYPE_TEXTURE_3D: - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { - struct wined3d_texture *texture = texture_from_resource(resource); - - if (device->state.textures[i] == texture) + if (&device->state.textures[i]->resource == resource) { - ERR("Texture %p is still in use, stage %u.\n", texture, i); + ERR("Texture resource %p is still in use, stage %u.\n", resource, i); device->state.textures[i] = NULL; } - if (device->recording && device->update_state->textures[i] == texture) + if (device->recording && &device->update_stateblock_state->textures[i]->resource == resource) { - ERR("Texture %p is still in use by recording stateblock %p, stage %u.\n", - texture, device->recording, i); - device->update_state->textures[i] = NULL; + ERR("Texture resource %p is still in use by recording stateblock %p, stage %u.\n", + resource, device->recording, i); + device->update_stateblock_state->textures[i] = NULL; } } break; case WINED3D_RTYPE_BUFFER: + for (i = 0; i < WINED3D_MAX_STREAMS; ++i) { - struct wined3d_buffer *buffer = buffer_from_resource(resource); - - for (i = 0; i < MAX_STREAMS; ++i) + if (&device->state.streams[i].buffer->resource == resource) { - if (device->state.streams[i].buffer == buffer) - { - ERR("Buffer %p is still in use, stream %u.\n", buffer, i); - device->state.streams[i].buffer = NULL; - } - - if (device->recording && device->update_state->streams[i].buffer == buffer) - { - ERR("Buffer %p is still in use by stateblock %p, stream %u.\n", - buffer, device->recording, i); - device->update_state->streams[i].buffer = NULL; - } + ERR("Buffer resource %p is still in use, stream %u.\n", resource, i); + device->state.streams[i].buffer = NULL; } - if (device->state.index_buffer == buffer) + if (device->recording && &device->update_stateblock_state->streams[i].buffer->resource == resource) { - ERR("Buffer %p is still in use as index buffer.\n", buffer); - device->state.index_buffer = NULL; + ERR("Buffer resource %p is still in use by stateblock %p, stream %u.\n", + resource, device->recording, i); + device->update_stateblock_state->streams[i].buffer = NULL; } + } - if (device->recording && device->update_state->index_buffer == buffer) - { - ERR("Buffer %p is still in use by stateblock %p as index buffer.\n", - buffer, device->recording); - device->update_state->index_buffer = NULL; - } + if (&device->state.index_buffer->resource == resource) + { + ERR("Buffer resource %p is still in use as index buffer.\n", resource); + device->state.index_buffer = NULL; + } + + if (device->recording && &device->update_stateblock_state->index_buffer->resource == resource) + { + ERR("Buffer resource %p is still in use by stateblock %p as index buffer.\n", + resource, device->recording); + device->update_stateblock_state->index_buffer = NULL; } break; @@ -5192,20 +5828,47 @@ static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry * return memcmp(&sampler->desc, key, sizeof(sampler->desc)); } -HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, - UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags, - BYTE surface_alignment, struct wined3d_device_parent *device_parent) +static BOOL wined3d_select_feature_level(const struct wined3d_adapter *adapter, + const enum wined3d_feature_level *levels, unsigned int level_count, + enum wined3d_feature_level *selected_level) +{ + const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; + unsigned int i; + + for (i = 0; i < level_count; ++i) + { + if (levels[i] && d3d_info->feature_level >= levels[i]) + { + *selected_level = levels[i]; + return TRUE; + } + } + + FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU " + "with the current shader backend.\n"); + return FALSE; +} + +HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined3d, + unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, + BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, + struct wined3d_device_parent *device_parent) { - struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx]; - const struct fragment_pipeline *fragment_pipeline; + struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx]; + const struct wined3d_fragment_pipe_ops *fragment_pipeline; const struct wined3d_vertex_pipe_ops *vertex_pipeline; unsigned int i; HRESULT hr; + if (!wined3d_select_feature_level(adapter, levels, level_count, &device->feature_level)) + return E_FAIL; + + TRACE("Device feature level %s.\n", wined3d_debug_feature_level(device->feature_level)); + device->ref = 1; device->wined3d = wined3d; wined3d_incref(device->wined3d); - device->adapter = wined3d->adapter_count ? adapter : NULL; + device->adapter = adapter; device->device_parent = device_parent; list_init(&device->resources); list_init(&device->shaders); @@ -5226,8 +5889,8 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, wine_rb_init(&device->samplers, wined3d_sampler_compare); if (vertex_pipeline->vp_states && fragment_pipeline->states - && FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs, - &adapter->gl_info, &adapter->d3d_info, vertex_pipeline, + && FAILED(hr = compile_state_table(device->state_table, device->multistate_funcs, + &adapter->d3d_info, adapter->gl_info.supported, vertex_pipeline, fragment_pipeline, misc_state_template))) { ERR("Failed to compile state table, hr %#x.\n", hr); @@ -5236,14 +5899,17 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, return hr; } - state_init(&device->state, &device->fb, &adapter->gl_info, - &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); - device->update_state = &device->state; + state_init(&device->state, &device->fb, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); + wined3d_stateblock_state_init(&device->stateblock_state, device, WINED3D_STATE_INIT_DEFAULT); + device->update_stateblock_state = &device->stateblock_state; + + device->max_frame_latency = 3; if (!(device->cs = wined3d_cs_create(device))) { WARN("Failed to create command stream.\n"); state_cleanup(&device->state); + wined3d_stateblock_state_cleanup(&device->stateblock_state); hr = E_FAIL; goto err; } @@ -5260,48 +5926,32 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, return hr; } -void device_invalidate_state(const struct wined3d_device *device, DWORD state) +void device_invalidate_state(const struct wined3d_device *device, unsigned int state_id) { - DWORD rep = device->StateTable[state].representative; + unsigned int representative, i, idx, shift; struct wined3d_context *context; - DWORD idx; - BYTE shift; - UINT i; wined3d_from_cs(device->cs); - if (STATE_IS_COMPUTE(state)) + if (STATE_IS_COMPUTE(state_id)) { for (i = 0; i < device->context_count; ++i) - context_invalidate_compute_state(device->contexts[i], state); + context_invalidate_compute_state(device->contexts[i], state_id); return; } + representative = device->state_table[state_id].representative; + idx = representative / (sizeof(*context->dirty_graphics_states) * CHAR_BIT); + shift = representative & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1); for (i = 0; i < device->context_count; ++i) { - context = device->contexts[i]; - if(isStateDirty(context, rep)) continue; - - context->dirtyArray[context->numDirtyEntries++] = rep; - idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] |= (1u << shift); + device->contexts[i]->dirty_graphics_states[idx] |= (1u << shift); } } LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode, UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) { - if (device->filter_messages && message != WM_DISPLAYCHANGE) - { - TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n", - window, message, wparam, lparam); - if (unicode) - return DefWindowProcW(window, message, wparam, lparam); - else - return DefWindowProcA(window, message, wparam, lparam); - } - if (message == WM_DESTROY) { TRACE("unregister window %p.\n", window); @@ -5316,12 +5966,14 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL } else if (message == WM_ACTIVATEAPP) { - UINT i; + unsigned int i = device->swapchain_count; - for (i = 0; i < device->swapchain_count; i++) + /* Deactivating the implicit swapchain may cause the application + * (e.g. Deus Ex: GOTY) to destroy the device, so take care to + * deactivate the implicit swapchain last, and to avoid accessing the + * "device" pointer afterwards. */ + while (i--) wined3d_swapchain_activate(device->swapchains[i], wparam); - - device->device_parent->ops->activate(device->device_parent, wparam); } else if (message == WM_SYSCOMMAND) { diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c index d82a6713434..ddab690219c 100644 --- a/dll/directx/wine/wined3d/directx.c +++ b/dll/directx/wine/wined3d/directx.c @@ -24,41 +24,14 @@ #include "config.h" #include "wine/port.h" -#include - #include "wined3d_private.h" -#include "wine/winternl.h" +#include "winternl.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(winediag); #define DEFAULT_REFRESH_RATE 0 -/* The driver names reflect the lowest GPU supported - * by a certain driver, so DRIVER_AMD_R300 supports - * R3xx, R4xx and R5xx GPUs. */ -enum wined3d_display_driver -{ - DRIVER_AMD_RAGE_128PRO, - DRIVER_AMD_R100, - DRIVER_AMD_R300, - DRIVER_AMD_R600, - DRIVER_AMD_RX, - DRIVER_INTEL_GMA800, - DRIVER_INTEL_GMA900, - DRIVER_INTEL_GMA950, - DRIVER_INTEL_GMA3000, - DRIVER_INTEL_HD4000, - DRIVER_NVIDIA_TNT, - DRIVER_NVIDIA_GEFORCE2MX, - DRIVER_NVIDIA_GEFORCEFX, - DRIVER_NVIDIA_GEFORCE6, - DRIVER_NVIDIA_GEFORCE8, - DRIVER_VMWARE, - DRIVER_UNKNOWN -}; - enum wined3d_driver_model { DRIVER_MODEL_GENERIC, @@ -68,222 +41,9 @@ enum wined3d_driver_model DRIVER_MODEL_NT6X }; -enum wined3d_gl_vendor -{ - GL_VENDOR_UNKNOWN, - GL_VENDOR_APPLE, - GL_VENDOR_FGLRX, - GL_VENDOR_MESA, - GL_VENDOR_NVIDIA, -}; - -enum wined3d_d3d_level -{ - WINED3D_D3D_LEVEL_5, - WINED3D_D3D_LEVEL_6, - WINED3D_D3D_LEVEL_7, - WINED3D_D3D_LEVEL_8, - WINED3D_D3D_LEVEL_9_SM2, - WINED3D_D3D_LEVEL_9_SM3, - WINED3D_D3D_LEVEL_10, - WINED3D_D3D_LEVEL_11, - WINED3D_D3D_LEVEL_COUNT -}; - /* The d3d device ID */ static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } }; -/* Extension detection */ -struct wined3d_extension_map -{ - const char *extension_string; - enum wined3d_gl_extension extension; -}; - -static const struct wined3d_extension_map gl_extension_map[] = -{ - /* APPLE */ - {"GL_APPLE_fence", APPLE_FENCE }, - {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS }, - {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE }, - {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422 }, - - /* ARB */ - {"GL_ARB_base_instance", ARB_BASE_INSTANCE }, - {"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED }, - {"GL_ARB_clear_buffer_object", ARB_CLEAR_BUFFER_OBJECT }, - {"GL_ARB_clear_texture", ARB_CLEAR_TEXTURE }, - {"GL_ARB_clip_control", ARB_CLIP_CONTROL }, - {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT }, - {"GL_ARB_compute_shader", ARB_COMPUTE_SHADER }, - {"GL_ARB_conservative_depth", ARB_CONSERVATIVE_DEPTH }, - {"GL_ARB_copy_buffer", ARB_COPY_BUFFER }, - {"GL_ARB_copy_image", ARB_COPY_IMAGE }, - {"GL_ARB_cull_distance", ARB_CULL_DISTANCE }, - {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT }, - {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT }, - {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP }, - {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE }, - {"GL_ARB_derivative_control", ARB_DERIVATIVE_CONTROL }, - {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS }, - {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX }, - {"GL_ARB_draw_indirect", ARB_DRAW_INDIRECT }, - {"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED }, - {"GL_ARB_ES2_compatibility", ARB_ES2_COMPATIBILITY }, - {"GL_ARB_ES3_compatibility", ARB_ES3_COMPATIBILITY }, - {"GL_ARB_explicit_attrib_location", ARB_EXPLICIT_ATTRIB_LOCATION }, - {"GL_ARB_fragment_coord_conventions", ARB_FRAGMENT_COORD_CONVENTIONS}, - {"GL_ARB_fragment_layer_viewport", ARB_FRAGMENT_LAYER_VIEWPORT }, - {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, - {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER }, - {"GL_ARB_framebuffer_no_attachments", ARB_FRAMEBUFFER_NO_ATTACHMENTS}, - {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, - {"GL_ARB_framebuffer_sRGB", ARB_FRAMEBUFFER_SRGB }, - {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4 }, - {"GL_ARB_gpu_shader5", ARB_GPU_SHADER5 }, - {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL }, - {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX }, - {"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS }, - {"GL_ARB_internalformat_query", ARB_INTERNALFORMAT_QUERY }, - {"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2 }, - {"GL_ARB_map_buffer_alignment", ARB_MAP_BUFFER_ALIGNMENT }, - {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE }, - {"GL_ARB_multisample", ARB_MULTISAMPLE }, - {"GL_ARB_multitexture", ARB_MULTITEXTURE }, - {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY }, - {"GL_ARB_pipeline_statistics_query", ARB_PIPELINE_STATISTICS_QUERY }, - {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT }, - {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS }, - {"GL_ARB_point_sprite", ARB_POINT_SPRITE }, - {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX }, - {"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS }, - {"GL_ARB_seamless_cube_map", ARB_SEAMLESS_CUBE_MAP }, - {"GL_ARB_shader_atomic_counters", ARB_SHADER_ATOMIC_COUNTERS }, - {"GL_ARB_shader_bit_encoding", ARB_SHADER_BIT_ENCODING }, - {"GL_ARB_shader_image_load_store", ARB_SHADER_IMAGE_LOAD_STORE }, - {"GL_ARB_shader_image_size", ARB_SHADER_IMAGE_SIZE }, - {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT}, - {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD }, - {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 }, - {"GL_ARB_shading_language_420pack", ARB_SHADING_LANGUAGE_420PACK }, - {"GL_ARB_shading_language_packing", ARB_SHADING_LANGUAGE_PACKING }, - {"GL_ARB_shadow", ARB_SHADOW }, - {"GL_ARB_stencil_texturing", ARB_STENCIL_TEXTURING }, - {"GL_ARB_sync", ARB_SYNC }, - {"GL_ARB_tessellation_shader", ARB_TESSELLATION_SHADER }, - {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP }, - {"GL_ARB_texture_buffer_object", ARB_TEXTURE_BUFFER_OBJECT }, - {"GL_ARB_texture_buffer_range", ARB_TEXTURE_BUFFER_RANGE }, - {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION }, - {"GL_ARB_texture_compression_bptc", ARB_TEXTURE_COMPRESSION_BPTC }, - {"GL_ARB_texture_compression_rgtc", ARB_TEXTURE_COMPRESSION_RGTC }, - {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP }, - {"GL_ARB_texture_cube_map_array", ARB_TEXTURE_CUBE_MAP_ARRAY }, - {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE }, - {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3 }, - {"GL_ARB_texture_filter_anisotropic", ARB_TEXTURE_FILTER_ANISOTROPIC}, - {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT }, - {"GL_ARB_texture_gather", ARB_TEXTURE_GATHER }, - {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT }, - {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE}, - {"GL_ARB_texture_multisample", ARB_TEXTURE_MULTISAMPLE }, - {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO }, - {"GL_ARB_texture_query_levels", ARB_TEXTURE_QUERY_LEVELS }, - {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE }, - {"GL_ARB_texture_rg", ARB_TEXTURE_RG }, - {"GL_ARB_texture_rgb10_a2ui", ARB_TEXTURE_RGB10_A2UI }, - {"GL_ARB_texture_storage", ARB_TEXTURE_STORAGE }, - {"GL_ARB_texture_storage_multisample", ARB_TEXTURE_STORAGE_MULTISAMPLE}, - {"GL_ARB_texture_swizzle", ARB_TEXTURE_SWIZZLE }, - {"GL_ARB_texture_view", ARB_TEXTURE_VIEW }, - {"GL_ARB_timer_query", ARB_TIMER_QUERY }, - {"GL_ARB_transform_feedback2", ARB_TRANSFORM_FEEDBACK2 }, - {"GL_ARB_transform_feedback3", ARB_TRANSFORM_FEEDBACK3 }, - {"GL_ARB_uniform_buffer_object", ARB_UNIFORM_BUFFER_OBJECT }, - {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA }, - {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND }, - {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT }, - {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM }, - {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER }, - {"GL_ARB_vertex_type_2_10_10_10_rev", ARB_VERTEX_TYPE_2_10_10_10_REV}, - {"GL_ARB_viewport_array", ARB_VIEWPORT_ARRAY }, - - /* ATI */ - {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER }, - {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL }, - {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC }, - {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3 }, - {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE }, - - /* EXT */ - {"GL_EXT_blend_color", EXT_BLEND_COLOR }, - {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE }, - {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE }, - {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX }, - {"GL_EXT_blend_subtract", EXT_BLEND_SUBTRACT }, - {"GL_EXT_depth_bounds_test", EXT_DEPTH_BOUNDS_TEST }, - {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2 }, - {"GL_EXT_fog_coord", EXT_FOG_COORD }, - {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT }, - {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE }, - {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT }, - {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS }, - {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4 }, - {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL }, - {"GL_EXT_packed_float", EXT_PACKED_FLOAT }, - {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS }, - {"GL_EXT_polygon_offset_clamp", EXT_POLYGON_OFFSET_CLAMP }, - {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX }, - {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR }, - {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE }, - {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP }, - {"GL_EXT_texture3D", EXT_TEXTURE3D }, - {"GL_EXT_texture_array", EXT_TEXTURE_ARRAY }, - {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC }, - {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC }, - {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE }, - {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3 }, - {"GL_EXT_texture_filter_anisotropic", ARB_TEXTURE_FILTER_ANISOTROPIC}, - {"GL_EXT_texture_integer", EXT_TEXTURE_INTEGER }, - {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS }, - {"GL_EXT_texture_mirror_clamp", EXT_TEXTURE_MIRROR_CLAMP }, - {"GL_EXT_texture_shared_exponent", EXT_TEXTURE_SHARED_EXPONENT }, - {"GL_EXT_texture_snorm", EXT_TEXTURE_SNORM }, - {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB }, - {"GL_EXT_texture_sRGB_decode", EXT_TEXTURE_SRGB_DECODE }, - {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA }, - - /* NV */ - {"GL_NV_fence", NV_FENCE }, - {"GL_NV_fog_distance", NV_FOG_DISTANCE }, - {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM }, - {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2 }, - {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION }, - {"GL_NV_half_float", NV_HALF_FLOAT }, - {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT }, - {"GL_NV_point_sprite", NV_POINT_SPRITE }, - {"GL_NV_register_combiners", NV_REGISTER_COMBINERS }, - {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2 }, - {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION }, - {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4 }, - {"GL_NV_texture_shader", NV_TEXTURE_SHADER }, - {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2 }, - {"GL_NV_vertex_program", NV_VERTEX_PROGRAM }, - {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1 }, - {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 }, - {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION }, - {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 }, - {"GL_NVX_gpu_memory_info", NVX_GPU_MEMORY_INFO }, -}; - -static const struct wined3d_extension_map wgl_extension_map[] = -{ - {"WGL_ARB_pixel_format", WGL_ARB_PIXEL_FORMAT }, - {"WGL_EXT_swap_control", WGL_EXT_SWAP_CONTROL }, - {"WGL_WINE_pixel_format_passthrough", WGL_WINE_PIXEL_FORMAT_PASSTHROUGH}, - {"WGL_WINE_query_renderer", WGL_WINE_QUERY_RENDERER }, -}; - /********************************************************** * Utility functions follow **********************************************************/ @@ -302,141 +62,6 @@ const GLenum magLookup[] = GL_NEAREST, GL_NEAREST, GL_LINEAR, }; -static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx) -{ - const struct wined3d_gl_info *gl_info = ctx->gl_info; - - TRACE("Destroying caps GL context.\n"); - - /* Both glDeleteProgram and glDeleteBuffers silently ignore 0 IDs but - * this function might be called before the relevant function pointers - * in gl_info are initialized. */ - if (ctx->test_program_id || ctx->test_vbo) - { - GL_EXTCALL(glDeleteProgram(ctx->test_program_id)); - GL_EXTCALL(glDeleteBuffers(1, &ctx->test_vbo)); - } - - if (!wglMakeCurrent(NULL, NULL)) - ERR("Failed to disable caps GL context.\n"); - - if (!wglDeleteContext(ctx->gl_ctx)) - { - DWORD err = GetLastError(); - ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err); - } - - wined3d_release_dc(ctx->wnd, ctx->dc); - DestroyWindow(ctx->wnd); - - if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx)) - ERR("Failed to restore previous GL context.\n"); -} - -static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx, - struct wined3d_gl_info *gl_info) -{ - HGLRC new_ctx; - - if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB"))) - return TRUE; - - if (!(new_ctx = context_create_wgl_attribs(gl_info, caps_gl_ctx->dc, NULL))) - { - gl_info->p_wglCreateContextAttribsARB = NULL; - return FALSE; - } - - if (!wglMakeCurrent(caps_gl_ctx->dc, new_ctx)) - { - ERR("Failed to make new context current, last error %#x.\n", GetLastError()); - if (!wglDeleteContext(new_ctx)) - ERR("Failed to delete new context, last error %#x.\n", GetLastError()); - gl_info->p_wglCreateContextAttribsARB = NULL; - return TRUE; - } - - if (!wglDeleteContext(caps_gl_ctx->gl_ctx)) - ERR("Failed to delete old context, last error %#x.\n", GetLastError()); - caps_gl_ctx->gl_ctx = new_ctx; - - return TRUE; -} - -static BOOL wined3d_caps_gl_ctx_create(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) -{ - PIXELFORMATDESCRIPTOR pfd; - int iPixelFormat; - - TRACE("getting context...\n"); - - ctx->restore_dc = wglGetCurrentDC(); - ctx->restore_gl_ctx = wglGetCurrentContext(); - - /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */ - ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", - WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL); - if (!ctx->wnd) - { - ERR("Failed to create a window.\n"); - goto fail; - } - - ctx->dc = GetDC(ctx->wnd); - if (!ctx->dc) - { - ERR("Failed to get a DC.\n"); - goto fail; - } - - /* PixelFormat selection */ - ZeroMemory(&pfd, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */ - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 32; - pfd.iLayerType = PFD_MAIN_PLANE; - - if (!(iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd))) - { - /* If this happens something is very wrong as ChoosePixelFormat barely fails. */ - ERR("Failed to find a suitable pixel format.\n"); - goto fail; - } - DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd); - SetPixelFormat(ctx->dc, iPixelFormat, &pfd); - - /* Create a GL context. */ - if (!(ctx->gl_ctx = wglCreateContext(ctx->dc))) - { - WARN("Failed to create default context for capabilities initialization.\n"); - goto fail; - } - - /* Make it the current GL context. */ - if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx)) - { - ERR("Failed to make caps GL context current.\n"); - goto fail; - } - - ctx->gl_info = &adapter->gl_info; - return TRUE; - -fail: - if (ctx->gl_ctx) wglDeleteContext(ctx->gl_ctx); - ctx->gl_ctx = NULL; - if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc); - ctx->dc = NULL; - if (ctx->wnd) DestroyWindow(ctx->wnd); - ctx->wnd = NULL; - if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx)) - ERR("Failed to restore previous GL context.\n"); - - return FALSE; -} - /* Adjust the amount of used texture memory */ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) { @@ -447,10 +72,9 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) return adapter->vram_bytes_used; } -static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter) +void wined3d_adapter_cleanup(struct wined3d_adapter *adapter) { - heap_free(adapter->gl_info.formats); - heap_free(adapter->cfgs); + heap_free(adapter->formats); } ULONG CDECL wined3d_incref(struct wined3d *wined3d) @@ -474,7 +98,9 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d) for (i = 0; i < wined3d->adapter_count; ++i) { - wined3d_adapter_cleanup(&wined3d->adapters[i]); + struct wined3d_adapter *adapter = wined3d->adapters[i]; + + adapter->adapter_ops->adapter_destroy(adapter); } heap_free(wined3d); } @@ -482,801 +108,102 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d) return refcount; } -/* Context activation is done by the caller. */ -static BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info) -{ - GLuint prog; - BOOL ret = FALSE; - static const char testcode[] = - "!!ARBvp1.0\n" - "PARAM C[66] = { program.env[0..65] };\n" - "ADDRESS A0;" - "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n" - "ARL A0.x, zero.x;\n" - "MOV result.position, C[A0.x + 65];\n" - "END\n"; - - while (gl_info->gl_ops.gl.p_glGetError()); - GL_EXTCALL(glGenProgramsARB(1, &prog)); - if(!prog) { - ERR("Failed to create an ARB offset limit test program\n"); - } - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog)); - GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(testcode), testcode)); - if (gl_info->gl_ops.gl.p_glGetError()) - { - TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n"); - TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB))); - ret = TRUE; - } else TRACE("OpenGL implementation allows offsets > 63\n"); - - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0)); - GL_EXTCALL(glDeleteProgramsARB(1, &prog)); - checkGLcall("ARB vp offset limit test cleanup"); - - return ret; -} - -static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - if (card_vendor != HW_VENDOR_AMD) return FALSE; - if (device == CARD_AMD_RADEON_9500) return TRUE; - if (device == CARD_AMD_RADEON_X700) return TRUE; - if (device == CARD_AMD_RADEON_X1600) return TRUE; - return FALSE; -} - -static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - if (card_vendor == HW_VENDOR_NVIDIA) - { - if (device == CARD_NVIDIA_GEFORCEFX_5200 || - device == CARD_NVIDIA_GEFORCEFX_5600 || - device == CARD_NVIDIA_GEFORCEFX_5800) - { - return TRUE; - } - } - return FALSE; -} - -static BOOL match_apple(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from - * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to - * detect the Apple OpenGL implementation to apply some extension fixups afterwards. - * - * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks - * aren't sufficient either because a Linux binary may display on a macos X server via remote X11. - * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions - * like client storage might be supported on other implementations too, but GL_APPLE_flush_render - * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So - * the chance that other implementations support them is rather small since Win32 QuickTime uses - * DirectDraw, not OpenGL. - * - * This test has been moved into wined3d_guess_gl_vendor() - */ - return gl_vendor == GL_VENDOR_APPLE; -} - -/* Context activation is done by the caller. */ -static void test_pbo_functionality(struct wined3d_gl_info *gl_info) -{ - /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs, - * but glTexSubImage from a PBO fails miserably, with the first line repeated over - * all the texture. This function detects this bug by its symptom and disables PBOs - * if the test fails. - * - * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA, - * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use - * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data - * read back is compared to the original. If they are equal PBOs are assumed to work, - * otherwise the PBO extension is disabled. */ - GLuint texture, pbo; - static const unsigned int pattern[] = - { - 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000, - 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff, - 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff, - 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff - }; - unsigned int check[ARRAY_SIZE(pattern)]; - - /* No PBO -> No point in testing them. */ - if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return; - - while (gl_info->gl_ops.gl.p_glGetError()); - gl_info->gl_ops.gl.p_glGenTextures(1, &texture); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture); - - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); - checkGLcall("Specifying the PBO test texture"); - - GL_EXTCALL(glGenBuffers(1, &pbo)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo)); - GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pattern), pattern, GL_STREAM_DRAW)); - checkGLcall("Specifying the PBO test pbo"); - - gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - checkGLcall("Loading the PBO test texture"); - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - - gl_info->gl_ops.gl.p_glFinish(); /* just to be sure */ - - memset(check, 0, sizeof(check)); - gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check); - checkGLcall("Reading back the PBO test texture"); - - gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture); - GL_EXTCALL(glDeleteBuffers(1, &pbo)); - checkGLcall("PBO test cleanup"); - - if (memcmp(check, pattern, sizeof(check))) - { - WARN_(d3d_perf)("PBO test failed, read back data doesn't match original.\n" - "Disabling PBOs. This may result in slower performance.\n"); - gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE; - } - else - { - TRACE("PBO test successful.\n"); - } -} - -static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE); -} - -static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - if (gl_vendor != GL_VENDOR_APPLE) return FALSE; - if (card_vendor != HW_VENDOR_AMD) return FALSE; - if (device == CARD_AMD_RADEON_X1600) return FALSE; - return TRUE; -} - -static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports - * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card. - * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44 - * varyings and we subtract one in dx9 shaders it's not going to hurt us because the dx9 limit is - * hardcoded - * - * dx10 cards usually have 64 varyings */ - return gl_info->limits.glsl_varyings > 44; -} - -static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - return !match_dx10_capable(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device); -} - -/* A GL context is provided by the caller */ -static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - GLenum error; - DWORD data[16]; - - if (!gl_info->supported[EXT_SECONDARY_COLOR]) - return FALSE; - - while (gl_info->gl_ops.gl.p_glGetError()); - GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data); - error = gl_info->gl_ops.gl.p_glGetError(); - - if (error == GL_NO_ERROR) - { - TRACE("GL Implementation accepts 4 component specular color pointers\n"); - return TRUE; - } - else - { - TRACE("GL implementation does not accept 4 component specular colors, error %s\n", - debug_glerror(error)); - return FALSE; - } -} +/* Certain applications (Steam) complain if we report an outdated driver version. In general, + * reporting a driver version is moot because we are not the Windows driver, and we have different + * bugs, features, etc. + * + * The driver version has the form "x.y.z.w". + * + * "x" is the Windows version the driver is meant for: + * 4 -> 95/98/NT4 + * 5 -> 2000 + * 6 -> 2000/XP + * 7 -> Vista + * 8 -> Windows 7 + * 9 -> Windows 8 + * 10 -> Windows 10 + * + * "y" is the maximum Direct3D version the driver supports. + * y -> d3d version mapping: + * 11 -> d3d6 + * 12 -> d3d7 + * 13 -> d3d8 + * 14 -> d3d9 + * 15 -> d3d10 + * 16 -> d3d10.1 + * 17 -> d3d11 + * + * "z" is the subversion number. + * + * "w" is the vendor specific driver build number. + */ -/* A GL context is provided by the caller */ -static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +struct driver_version_information { - GLuint prog; - BOOL ret = FALSE; - GLint pos; - static const char testcode[] = - "!!ARBvp1.0\n" - "OPTION NV_vertex_program2;\n" - "MOV result.clip[0], 0.0;\n" - "MOV result.position, 0.0;\n" - "END\n"; - - if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE; - - while (gl_info->gl_ops.gl.p_glGetError()); - - GL_EXTCALL(glGenProgramsARB(1, &prog)); - if(!prog) - { - ERR("Failed to create the NVvp clip test program\n"); - return FALSE; - } - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog)); - GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(testcode), testcode)); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); - if(pos != -1) - { - WARN("GL_NV_vertex_program2_option result.clip[] test failed\n"); - TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB))); - ret = TRUE; - while (gl_info->gl_ops.gl.p_glGetError()); - } - else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n"); - - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0)); - GL_EXTCALL(glDeleteProgramsARB(1, &prog)); - checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup"); - - return ret; -} + enum wined3d_display_driver driver; + enum wined3d_driver_model driver_model; + const char *driver_name; /* name of Windows driver */ + WORD version; /* version word ('y'), contained in low word of DriverVersion.HighPart */ + WORD subversion; /* subversion word ('z'), contained in high word of DriverVersion.LowPart */ + WORD build; /* build number ('w'), contained in low word of DriverVersion.LowPart */ +}; -/* Context activation is done by the caller. */ -static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +/* The driver version table contains driver information for different devices on several OS versions. */ +static const struct driver_version_information driver_version_table[] = { - char data[4 * 4 * 4]; - GLuint tex, fbo; - GLenum status; - - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE; - - memset(data, 0xcc, sizeof(data)); - - gl_info->gl_ops.gl.p_glGenTextures(1, &tex); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - checkGLcall("glTexImage2D"); - - gl_info->fbo_ops.glGenFramebuffers(1, &fbo); - gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); - checkGLcall("glFramebufferTexture2D"); - - status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status); - checkGLcall("glCheckFramebufferStatus"); - - memset(data, 0x11, sizeof(data)); - gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); - checkGLcall("glTexSubImage2D"); - - gl_info->gl_ops.gl.p_glClearColor(0.996f, 0.729f, 0.745f, 0.792f); - gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); - checkGLcall("glClear"); - - gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); - checkGLcall("glGetTexImage"); - - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); - checkGLcall("glBindTexture"); + /* AMD + * - Radeon HD2x00 (R600) and up supported by current drivers. + * - Radeon 9500 (R300) - X1*00 (R5xx) supported up to Catalyst 9.3 (Linux) and 10.2 (XP/Vista/Win7) + * - Radeon 7xxx (R100) - 9250 (RV250) supported up to Catalyst 6.11 (XP) + * - Rage 128 supported up to XP, latest official build 6.13.3279 dated October 2001 */ + {DRIVER_AMD_RAGE_128PRO, DRIVER_MODEL_NT5X, "ati2dvaa.dll", 13, 3279, 0}, + {DRIVER_AMD_R100, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6614}, + {DRIVER_AMD_R300, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6764}, + {DRIVER_AMD_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 17, 10, 1280}, + {DRIVER_AMD_R300, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 }, + {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 17, 10, 1280}, + {DRIVER_AMD_RX, DRIVER_MODEL_NT6X, "aticfx32.dll", 17, 10, 1474}, - gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); - gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); - checkGLcall("glDeleteTextures"); + /* Intel + * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp + * drivers used ialmrnt5.dll for GMA800/GMA900 but at some point the file was renamed to + * igxprd32.dll but the GMA800 driver was never updated. */ + {DRIVER_INTEL_GMA800, DRIVER_MODEL_NT5X, "ialmrnt5.dll", 14, 10, 3889}, + {DRIVER_INTEL_GMA900, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4764}, + {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4926}, + {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 5218}, + {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT6X, "igdumd32.dll", 14, 10, 1504}, + {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT6X, "igdumd32.dll", 15, 10, 1666}, + {DRIVER_INTEL_HD4000, DRIVER_MODEL_NT6X, "igdumdim32.dll", 19, 15, 4352}, - return *(DWORD *)data == 0x11111111; -} + /* Nvidia + * - Geforce8 and newer is supported by the current 340.52 driver on XP-Win8 + * - Geforce6 and 7 support is up to 307.83 on XP-Win8 + * - GeforceFX support is up to 173.x on <= XP + * - Geforce2MX/3/4 up to 96.x on <= XP + * - TNT/Geforce1/2 up to 71.x on <= XP + * All version numbers used below are from the Linux nvidia drivers. */ + {DRIVER_NVIDIA_TNT, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 7186}, + {DRIVER_NVIDIA_GEFORCE2MX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 9371}, + {DRIVER_NVIDIA_GEFORCEFX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 11, 7516}, + {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT5X, "nv4_disp.dll", 18, 13, 783}, + {DRIVER_NVIDIA_GEFORCE8, DRIVER_MODEL_NT5X, "nv4_disp.dll", 18, 13, 4052}, + {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT6X, "nvd3dum.dll", 18, 13, 783}, + {DRIVER_NVIDIA_GEFORCE8, DRIVER_MODEL_NT6X, "nvd3dum.dll", 18, 13, 4052}, -/* Context activation is done by the caller. */ -static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - /* GL_RGBA16 uses GL_RGBA8 internally on Geforce 7 and older cards. - * This leads to graphical bugs in Half Life 2 and Unreal engine games. */ - GLuint tex; - GLint size; - - gl_info->gl_ops.gl.p_glGenTextures(1, &tex); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL); - checkGLcall("glTexImage2D"); - - gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &size); - checkGLcall("glGetTexLevelParameteriv"); - TRACE("Real color depth is %d\n", size); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); - checkGLcall("glBindTexture"); - gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); - checkGLcall("glDeleteTextures"); - - return size < 16; -} + /* Red Hat */ + {DRIVER_REDHAT_VIRGL, DRIVER_MODEL_GENERIC, "virgl.dll", 0, 0, 0}, -static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - return gl_vendor == GL_VENDOR_FGLRX; -} + /* VMware */ + {DRIVER_VMWARE, DRIVER_MODEL_NT5X, "vm3dum.dll", 14, 1, 1134}, -static BOOL match_r200(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - if (card_vendor != HW_VENDOR_AMD) return FALSE; - if (device == CARD_AMD_RADEON_8500) return TRUE; - return FALSE; -} + /* Wine */ + {DRIVER_WINE, DRIVER_MODEL_GENERIC, "wined3d.dll", 0, 0, 0}, +}; -static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - DWORD data[4]; - GLuint tex, fbo; - GLenum status; - float color[4] = {0.0f, 1.0f, 0.0f, 0.0f}; - GLuint prog; - GLint err_pos; - static const char program_code[] = - "!!ARBfp1.0\n" - "OPTION ARB_fog_linear;\n" - "MOV result.color, {1.0, 0.0, 0.0, 0.0};\n" - "END\n"; - - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return FALSE; - if (!gl_info->supported[ARB_FRAGMENT_PROGRAM]) - return FALSE; - - gl_info->gl_ops.gl.p_glGenTextures(1, &tex); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - checkGLcall("glTexImage2D"); - - gl_info->fbo_ops.glGenFramebuffers(1, &fbo); - gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); - checkGLcall("glFramebufferTexture2D"); - - status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status); - checkGLcall("glCheckFramebufferStatus"); - - gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 1.0f, 0.0f); - gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); - checkGLcall("glClear"); - gl_info->gl_ops.gl.p_glViewport(0, 0, 4, 1); - checkGLcall("glViewport"); - - gl_info->gl_ops.gl.p_glEnable(GL_FOG); - gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, 0.5f); - gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, 0.5f); - gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR); - gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST); - gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, color); - checkGLcall("fog setup"); - - GL_EXTCALL(glGenProgramsARB(1, &prog)); - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog)); - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(program_code), program_code)); - gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); - checkGLcall("Test fragment program setup"); - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err_pos); - if (err_pos != -1) - { - const char *error_str; - error_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB); - FIXME("Fog test program error at position %d: %s\n\n", err_pos, debugstr_a(error_str)); - } - - gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f); - gl_info->gl_ops.gl.p_glVertex3f( 1.0f, -1.0f, 1.0f); - gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f); - gl_info->gl_ops.gl.p_glVertex3f( 1.0f, 1.0f, 1.0f); - gl_info->gl_ops.gl.p_glEnd(); - checkGLcall("ARBfp fog test draw"); - - gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); - checkGLcall("glGetTexImage"); - data[0] &= 0x00ffffff; - data[1] &= 0x00ffffff; - data[2] &= 0x00ffffff; - data[3] &= 0x00ffffff; - - gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0); - - gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); - gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); - gl_info->gl_ops.gl.p_glDisable(GL_FOG); - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); - gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); - GL_EXTCALL(glDeleteProgramsARB(1, &prog)); - checkGLcall("ARBfp fog test teardown"); - - TRACE("Fog test data: %08x %08x %08x %08x\n", data[0], data[1], data[2], data[3]); - return data[0] != 0x00ff0000 || data[3] != 0x0000ff00; -} - -static BOOL match_broken_viewport_subpixel_bits(const struct wined3d_gl_info *gl_info, - struct wined3d_caps_gl_ctx *ctx, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - if (!gl_info->supported[ARB_VIEWPORT_ARRAY]) - return FALSE; - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return FALSE; - return !wined3d_caps_gl_ctx_test_viewport_subpixel_bits(ctx); -} - -static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info) -{ - /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms. - * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should - * allow 48 different offsets or other helper immediate values. */ - TRACE("Reserving 12 GLSL constants for compiler private use.\n"); - gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12); -} - -static void quirk_amd_dx9(struct wined3d_gl_info *gl_info) -{ - /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although - * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL). - * If real NP2 textures are used, the driver falls back to software. We could just remove the - * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconvenient - * due to the non-normalized texture coordinates. Thus set an internal extension flag, - * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures - * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits. - * - * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which - * has this extension promoted to core. The extension loading code sets this extension supported - * due to that, so this code works on fglrx as well. */ - if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) - { - TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n"); - gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE; - gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE; - } -} - -static void quirk_no_np2(struct wined3d_gl_info *gl_info) -{ - /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but - * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string. - * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying - * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the - * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used. - * We therefore completely remove ARB_tex_npot from the list of supported extensions. - * - * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot, - * triggering the software fallback. There is not much we can do here apart from disabling the - * software-emulated extension and re-enable ARB_tex_rect (which was previously disabled - * in wined3d_adapter_init_gl_caps). - * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer - * post-processing effects in the game "Max Payne 2"). - * The behaviour can be verified through a simple test app attached in bugreport #14724. */ - TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n"); - gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE; - gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE; -} - -static void quirk_texcoord_w(struct wined3d_gl_info *gl_info) -{ - /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems - * with fixed function fragment processing. Ideally this flag should be detected with a test shader - * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones) - * do not like vertex shaders in feedback mode and return an error, even though it should be valid - * according to the spec. - * - * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This - * makes the shader slower and eats instruction slots which should be available to the d3d app. - * - * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist - * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If - * this workaround is activated on cards that do not need it, it won't break things, just affect - * performance negatively. */ - TRACE("Enabling vertex texture coord fixes in vertex shaders.\n"); - gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W; -} - -static void quirk_clip_varying(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING; -} - -static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA; -} - -static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN; -} - -static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE; -} - -static void quirk_broken_rgba16(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_BROKEN_RGBA16; -} - -static void quirk_infolog_spam(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_INFO_LOG_SPAM; -} - -static void quirk_limited_tex_filtering(struct wined3d_gl_info *gl_info) -{ - /* Nvidia GeForce 6xxx and 7xxx support accelerated VTF only on a few - selected texture formats. They are apparently the only DX9 class GPUs - supporting VTF. - Also, DX9-era GPUs are somewhat limited with float textures - filtering and blending. */ - gl_info->quirks |= WINED3D_QUIRK_LIMITED_TEX_FILTERING; -} - -static void quirk_r200_constants(struct wined3d_gl_info *gl_info) -{ - /* The Mesa r200 driver (and there is no other driver for this GPU Wine would run on) - * loads some fog parameters (start, end, exponent, but not the color) into the - * program. - * - * Apparently the fog hardware is only able to handle linear fog with a range of 0.0;1.0, - * and it is the responsibility of the vertex pipeline to handle non-linear fog and - * linear fog with start and end other than 0.0 and 1.0. */ - TRACE("Reserving 1 ARB constant for compiler private use.\n"); - gl_info->reserved_arb_constants = max(gl_info->reserved_arb_constants, 1); -} - -static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info) -{ - gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG; -} - -static void quirk_broken_viewport_subpixel_bits(struct wined3d_gl_info *gl_info) -{ - if (gl_info->supported[ARB_CLIP_CONTROL]) - { - TRACE("Disabling ARB_clip_control.\n"); - gl_info->supported[ARB_CLIP_CONTROL] = FALSE; - } -} - -struct driver_quirk -{ - BOOL (*match)(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device); - void (*apply)(struct wined3d_gl_info *gl_info); - const char *description; -}; - -static const struct driver_quirk quirk_table[] = -{ - { - match_amd_r300_to_500, - quirk_amd_dx9, - "AMD normalized texrect quirk" - }, - { - match_apple, - quirk_apple_glsl_constants, - "Apple GLSL uniform override" - }, - { - match_geforce5, - quirk_no_np2, - "Geforce 5 NP2 disable" - }, - { - match_apple_intel, - quirk_texcoord_w, - "Init texcoord .w for Apple Intel GPU driver" - }, - { - match_apple_nonr500ati, - quirk_texcoord_w, - "Init texcoord .w for Apple ATI >= r600 GPU driver" - }, - { - match_dx10_capable, - quirk_clip_varying, - "Reserved varying for gl_ClipPos" - }, - { - /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most - * GL implementations accept it. The Mac GL is the only implementation known to - * reject it. - * - * If we can pass 4 component specular colors, do it, because (a) we don't have - * to screw around with the data, and (b) the D3D fixed function vertex pipeline - * passes specular alpha to the pixel shader if any is used. Otherwise the - * specular alpha is used to pass the fog coordinate, which we pass to opengl - * via GL_EXT_fog_coord. - */ - match_allows_spec_alpha, - quirk_allows_specular_alpha, - "Allow specular alpha quirk" - }, - { - match_broken_nv_clip, - quirk_disable_nvvp_clip, - "Apple NV_vertex_program clip bug quirk" - }, - { - match_fbo_tex_update, - quirk_fbo_tex_update, - "FBO rebind for attachment updates" - }, - { - match_broken_rgba16, - quirk_broken_rgba16, - "True RGBA16 is not available" - }, - { - match_fglrx, - quirk_infolog_spam, - "Not printing GLSL infolog" - }, - { - match_not_dx10_capable, - quirk_limited_tex_filtering, - "Texture filtering, blending and VTF support is limited" - }, - { - match_r200, - quirk_r200_constants, - "r200 vertex shader constants" - }, - { - match_broken_arb_fog, - quirk_broken_arb_fog, - "ARBfp fogstart == fogend workaround" - }, - { - match_broken_viewport_subpixel_bits, - quirk_broken_viewport_subpixel_bits, - "Nvidia viewport subpixel bits bug" - }, -}; - -/* Certain applications (Steam) complain if we report an outdated driver version. In general, - * reporting a driver version is moot because we are not the Windows driver, and we have different - * bugs, features, etc. - * - * The driver version has the form "x.y.z.w". - * - * "x" is the Windows version the driver is meant for: - * 4 -> 95/98/NT4 - * 5 -> 2000 - * 6 -> 2000/XP - * 7 -> Vista - * 8 -> Win 7 - * - * "y" is the maximum Direct3D version the driver supports. - * y -> d3d version mapping: - * 11 -> d3d6 - * 12 -> d3d7 - * 13 -> d3d8 - * 14 -> d3d9 - * 15 -> d3d10 - * 16 -> d3d10.1 - * 17 -> d3d11 - * - * "z" is the subversion number. - * - * "w" is the vendor specific driver build number. - */ - -struct driver_version_information -{ - enum wined3d_display_driver driver; - enum wined3d_driver_model driver_model; - const char *driver_name; /* name of Windows driver */ - WORD version; /* version word ('y'), contained in low word of DriverVersion.HighPart */ - WORD subversion; /* subversion word ('z'), contained in high word of DriverVersion.LowPart */ - WORD build; /* build number ('w'), contained in low word of DriverVersion.LowPart */ -}; - -/* The driver version table contains driver information for different devices on several OS versions. */ -static const struct driver_version_information driver_version_table[] = -{ - /* AMD - * - Radeon HD2x00 (R600) and up supported by current drivers. - * - Radeon 9500 (R300) - X1*00 (R5xx) supported up to Catalyst 9.3 (Linux) and 10.2 (XP/Vista/Win7) - * - Radeon 7xxx (R100) - 9250 (RV250) supported up to Catalyst 6.11 (XP) - * - Rage 128 supported up to XP, latest official build 6.13.3279 dated October 2001 */ - {DRIVER_AMD_RAGE_128PRO, DRIVER_MODEL_NT5X, "ati2dvaa.dll", 13, 3279, 0}, - {DRIVER_AMD_R100, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6614}, - {DRIVER_AMD_R300, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6764}, - {DRIVER_AMD_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 17, 10, 1280}, - {DRIVER_AMD_R300, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 }, - {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 17, 10, 1280}, - {DRIVER_AMD_RX, DRIVER_MODEL_NT6X, "aticfx32.dll", 17, 10, 1474}, - - /* Intel - * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp - * drivers used ialmrnt5.dll for GMA800/GMA900 but at some point the file was renamed to - * igxprd32.dll but the GMA800 driver was never updated. */ - {DRIVER_INTEL_GMA800, DRIVER_MODEL_NT5X, "ialmrnt5.dll", 14, 10, 3889}, - {DRIVER_INTEL_GMA900, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4764}, - {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4926}, - {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 5218}, - {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT6X, "igdumd32.dll", 14, 10, 1504}, - {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT6X, "igdumd32.dll", 15, 10, 1666}, - {DRIVER_INTEL_HD4000, DRIVER_MODEL_NT6X, "igdumdim32.dll", 19, 15, 4352}, - - /* Nvidia - * - Geforce8 and newer is supported by the current 340.52 driver on XP-Win8 - * - Geforce6 and 7 support is up to 307.83 on XP-Win8 - * - GeforceFX support is up to 173.x on <= XP - * - Geforce2MX/3/4 up to 96.x on <= XP - * - TNT/Geforce1/2 up to 71.x on <= XP - * All version numbers used below are from the Linux nvidia drivers. */ - {DRIVER_NVIDIA_TNT, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 7186}, - {DRIVER_NVIDIA_GEFORCE2MX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 9371}, - {DRIVER_NVIDIA_GEFORCEFX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 11, 7516}, - {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT5X, "nv4_disp.dll", 18, 13, 783}, - {DRIVER_NVIDIA_GEFORCE8, DRIVER_MODEL_NT5X, "nv4_disp.dll", 18, 13, 4052}, - {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT6X, "nvd3dum.dll", 18, 13, 783}, - {DRIVER_NVIDIA_GEFORCE8, DRIVER_MODEL_NT6X, "nvd3dum.dll", 18, 13, 4052}, - - /* VMware */ - {DRIVER_VMWARE, DRIVER_MODEL_NT5X, "vm3dum.dll", 14, 1, 1134}, -}; - -struct gpu_description -{ - WORD vendor; /* reported PCI card vendor ID */ - WORD card; /* reported PCI card device ID */ - const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */ - enum wined3d_display_driver driver; - unsigned int vidmem; -}; - -/* The amount of video memory stored in the gpu description table is the minimum amount of video memory - * found on a board containing a specific GPU. */ -static const struct gpu_description gpu_description_table[] = +/* The amount of video memory stored in the gpu description table is the minimum amount of video memory + * found on a board containing a specific GPU. */ +static const struct wined3d_gpu_description gpu_description_table[] = { /* Nvidia cards */ {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_128, "NVIDIA RIVA 128", DRIVER_NVIDIA_TNT, 4 }, @@ -1351,6 +278,7 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT610, "NVIDIA GeForce GT 610", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630, "NVIDIA GeForce GT 630", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630M, "NVIDIA GeForce GT 630M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT640, "NVIDIA GeForce GT 640", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT640M, "NVIDIA GeForce GT 640M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT650M, "NVIDIA GeForce GT 650M", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650, "NVIDIA GeForce GTX 650", DRIVER_NVIDIA_GEFORCE8, 1024}, @@ -1360,13 +288,16 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660TI, "NVIDIA GeForce GTX 660 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670, "NVIDIA GeForce GTX 670", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670MX, "NVIDIA GeForce GTX 670MX", DRIVER_NVIDIA_GEFORCE8, 3072}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX675MX, "NVIDIA GeForce GTX 675MX", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX675MX_1, "NVIDIA GeForce GTX 675MX", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX675MX_2, "NVIDIA GeForce GTX 675MX", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX680, "NVIDIA GeForce GTX 680", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX690, "NVIDIA GeForce GTX 690", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT720, "NVIDIA GeForce GT 720", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT730, "NVIDIA GeForce GT 730", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT730M, "NVIDIA GeForce GT 730M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT740M, "NVIDIA GeForce GT 740M", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT750M, "NVIDIA GeForce GT 750M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT755M, "NVIDIA GeForce GT 755M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750, "NVIDIA GeForce GTX 750", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750TI, "NVIDIA GeForce GTX 750 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX760, "NVIDIA GeForce GTX 760", DRIVER_NVIDIA_GEFORCE8, 2048}, @@ -1374,7 +305,9 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX765M, "NVIDIA GeForce GTX 765M", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE8, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770, "NVIDIA GeForce GTX 770", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX775M, "NVIDIA GeForce GTX 775M", DRIVER_NVIDIA_GEFORCE8, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780, "NVIDIA GeForce GTX 780", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780M, "NVIDIA GeForce GTX 780M", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780TI, "NVIDIA GeForce GTX 780 Ti", DRIVER_NVIDIA_GEFORCE8, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTXTITAN, "NVIDIA GeForce GTX TITAN", DRIVER_NVIDIA_GEFORCE8, 6144}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTXTITANB, "NVIDIA GeForce GTX TITAN Black", DRIVER_NVIDIA_GEFORCE8, 6144}, @@ -1398,11 +331,18 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980, "NVIDIA GeForce GTX 980", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980TI, "NVIDIA GeForce GTX 980 Ti", DRIVER_NVIDIA_GEFORCE8, 6144}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050, "NVIDIA GeForce GTX 1050", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050TI, "NVIDIA GeForce GTX 1050 Ti", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1060, "NVIDIA GeForce GTX 1060", DRIVER_NVIDIA_GEFORCE8, 6144}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1070, "NVIDIA GeForce GTX 1070", DRIVER_NVIDIA_GEFORCE8, 8192}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080, "NVIDIA GeForce GTX 1080", DRIVER_NVIDIA_GEFORCE8, 8192}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080TI, "NVIDIA GeForce GTX 1080 Ti", DRIVER_NVIDIA_GEFORCE8, 11264}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANX_PASCAL, "NVIDIA TITAN X (Pascal)", DRIVER_NVIDIA_GEFORCE8, 12288}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANV, "NVIDIA TITAN V", DRIVER_NVIDIA_GEFORCE8, 12288}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1660TI, "NVIDIA GeForce GTX 1660 Ti", DRIVER_NVIDIA_GEFORCE8, 6144}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_RTX2060, "NVIDIA GeForce RTX 2060", DRIVER_NVIDIA_GEFORCE8, 6144}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_RTX2070, "NVIDIA GeForce RTX 2070", DRIVER_NVIDIA_GEFORCE8, 8192}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_RTX2080, "NVIDIA GeForce RTX 2080", DRIVER_NVIDIA_GEFORCE8, 8192}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_RTX2080TI, "NVIDIA GeForce RTX 2080 Ti", DRIVER_NVIDIA_GEFORCE8, 11264}, /* AMD cards */ {HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 }, @@ -1431,6 +371,7 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6400, "AMD Radeon HD 6400 Series", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6410D, "AMD Radeon HD 6410D", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6480G, "AMD Radeon HD 6480G", DRIVER_AMD_R600, 512 }, + {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6490M, "AMD Radeon HD 6490M", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6550D, "AMD Radeon HD 6550D", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6600, "AMD Radeon HD 6600 Series", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6600M, "AMD Radeon HD 6600M Series", DRIVER_AMD_R600, 512 }, @@ -1440,6 +381,7 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7660D, "AMD Radeon HD 7660D", DRIVER_AMD_R600, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7700, "AMD Radeon HD 7700 Series", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7800, "AMD Radeon HD 7800 Series", DRIVER_AMD_R600, 2048}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7870, "AMD Radeon HD 7870 Series", DRIVER_AMD_R600, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7900, "AMD Radeon HD 7900 Series", DRIVER_AMD_R600, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD8600M, "AMD Radeon HD 8600M Series", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD8670, "AMD Radeon HD 8670", DRIVER_AMD_R600, 2048}, @@ -1448,9 +390,19 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_AMD, CARD_AMD_RADEON_R7, "AMD Radeon(TM) R7 Graphics", DRIVER_AMD_R600, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_285, "AMD Radeon R9 285", DRIVER_AMD_RX, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_290, "AMD Radeon R9 290", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_290X, "AMD Radeon R9 290X", DRIVER_AMD_RX, 4096}, {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_FURY, "AMD Radeon (TM) R9 Fury Series", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_M370X, "AMD Radeon R9 M370X", DRIVER_AMD_RX, 2048}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_M380, "AMD Radeon R9 M380", DRIVER_AMD_RX, 2048}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_M395X, "AMD Radeon R9 M395X", DRIVER_AMD_RX, 4096}, {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_460, "Radeon(TM) RX 460 Graphics", DRIVER_AMD_RX, 4096}, {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_480, "Radeon (TM) RX 480 Graphics", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_VEGA_10, "Radeon RX Vega", DRIVER_AMD_RX, 8192}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_VEGA_12, "Radeon Pro Vega 20", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_VEGA_20, "Radeon RX Vega 20", DRIVER_AMD_RX, 4096}, + + /* Red Hat */ + {HW_VENDOR_REDHAT, CARD_REDHAT_VIRGL, "Red Hat VirtIO GPU", DRIVER_REDHAT_VIRGL, 1024}, /* VMware */ {HW_VENDOR_VMWARE, CARD_VMWARE_SVGA3D, "VMware SVGA 3D (Microsoft Corporation - WDDM)", DRIVER_VMWARE, 1024}, @@ -1492,7 +444,8 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_INTEL, CARD_INTEL_IVBS, "Intel(R) HD Graphics Family", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_HWD, "Intel(R) HD Graphics 4600", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_HWM, "Intel(R) HD Graphics 4600", DRIVER_INTEL_HD4000, 1536}, - {HW_VENDOR_INTEL, CARD_INTEL_HD5000, "Intel(R) HD Graphics 5000", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5000_1, "Intel(R) HD Graphics 5000", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5000_2, "Intel(R) HD Graphics 5000", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_I5100_1, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_I5100_2, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_I5100_3, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, @@ -1502,6 +455,7 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_INTEL, CARD_INTEL_IP5200_3, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_IP5200_4, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_IP5200_5, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IP5200_6, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_HD5300, "Intel(R) HD Graphics 5300", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_HD5500, "Intel(R) HD Graphics 5500", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_HD5600, "Intel(R) HD Graphics 5600", DRIVER_INTEL_HD4000, 2048}, @@ -1526,6 +480,11 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_INTEL, CARD_INTEL_IP580_2, "Intel(R) Iris(TM) Pro Graphics 580", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_IPP580_1, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_IPP580_2, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_UHD617, "Intel(R) UHD Graphics 617", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_UHD620, "Intel(R) UHD Graphics 620", DRIVER_INTEL_HD4000, 3072}, + {HW_VENDOR_INTEL, CARD_INTEL_HD620, "Intel(R) HD Graphics 620", DRIVER_INTEL_HD4000, 3072}, + {HW_VENDOR_INTEL, CARD_INTEL_HD630_1, "Intel(R) HD Graphics 630", DRIVER_INTEL_HD4000, 3072}, + {HW_VENDOR_INTEL, CARD_INTEL_HD630_2, "Intel(R) HD Graphics 630", DRIVER_INTEL_HD4000, 3072}, }; static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver, @@ -1533,7 +492,8 @@ static const struct driver_version_information *get_driver_version_info(enum win { unsigned int i; - TRACE("Looking up version info for driver=%d driver_model=%d\n", driver, driver_model); + TRACE("Looking up version info for driver %#x, driver_model %#x.\n", driver, driver_model); + for (i = 0; i < ARRAY_SIZE(driver_version_table); ++i) { const struct driver_version_information *entry = &driver_version_table[i]; @@ -1549,85 +509,67 @@ static const struct driver_version_information *get_driver_version_info(enum win return NULL; } -static const struct gpu_description *get_gpu_description(enum wined3d_pci_vendor vendor, +const struct wined3d_gpu_description *wined3d_get_gpu_description(enum wined3d_pci_vendor vendor, enum wined3d_pci_device device) { unsigned int i; for (i = 0; i < ARRAY_SIZE(gpu_description_table); ++i) { - if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].card) + if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].device) return &gpu_description_table[i]; } return NULL; } -static const struct gpu_description *query_gpu_description(const struct wined3d_gl_info *gl_info, UINT64 *vram_bytes) +const struct wined3d_gpu_description *wined3d_get_user_override_gpu_description(enum wined3d_pci_vendor vendor, + enum wined3d_pci_device device) { - enum wined3d_pci_vendor vendor = PCI_VENDOR_NONE; - enum wined3d_pci_device device = PCI_DEVICE_NONE; - const struct gpu_description *gpu_description; + const struct wined3d_gpu_description *gpu_desc; static unsigned int once; - if (gl_info->supported[WGL_WINE_QUERY_RENDERER]) - { - GLuint value; - - if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VENDOR_ID_WINE, &value))) - vendor = value; - if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_DEVICE_ID_WINE, &value))) - device = value; - if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VIDEO_MEMORY_WINE, &value))) - *vram_bytes = (UINT64)value * 1024 * 1024; - TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes of video memory.\n", - vendor, device, wine_dbgstr_longlong(*vram_bytes)); - } - else if (gl_info->supported[NVX_GPU_MEMORY_INFO]) - { - GLint vram_kb; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb); - - *vram_bytes = (UINT64)vram_kb * 1024; - TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n", - wine_dbgstr_longlong(*vram_bytes)); - } + if (wined3d_settings.pci_vendor_id == PCI_VENDOR_NONE && wined3d_settings.pci_device_id == PCI_DEVICE_NONE) + return NULL; if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE) { vendor = wined3d_settings.pci_vendor_id; TRACE("Overriding vendor PCI ID with 0x%04x.\n", vendor); } - if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE) { device = wined3d_settings.pci_device_id; TRACE("Overriding device PCI ID with 0x%04x.\n", device); } - if (wined3d_settings.emulated_textureram) - { - *vram_bytes = wined3d_settings.emulated_textureram; - TRACE("Overriding amount of video memory with 0x%s bytes.\n", - wine_dbgstr_longlong(*vram_bytes)); - } - - if (!(gpu_description = get_gpu_description(vendor, device)) - && (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE - || wined3d_settings.pci_device_id != PCI_DEVICE_NONE) && !once++) + if (!(gpu_desc = wined3d_get_gpu_description(vendor, device)) && !once++) ERR_(winediag)("Invalid GPU override %04x:%04x specified, ignoring.\n", vendor, device); - return gpu_description; + return gpu_desc; +} + +static void wined3d_copy_name(char *dst, const char *src, unsigned int dst_size) +{ + size_t len; + + if (dst_size) + { + len = min(strlen(src), dst_size - 1); + memcpy(dst, src, len); + memset(&dst[len], 0, dst_size - len); + } } -static void init_driver_info(struct wined3d_driver_info *driver_info, - const struct gpu_description *gpu_desc, UINT64 vram_bytes) +void wined3d_driver_info_init(struct wined3d_driver_info *driver_info, + const struct wined3d_gpu_description *gpu_desc, UINT64 vram_bytes, UINT64 sysmem_bytes) { + const struct driver_version_information *version_info; + enum wined3d_driver_model driver_model; + enum wined3d_display_driver driver; + MEMORYSTATUSEX memory_status; OSVERSIONINFOW os_version; WORD driver_os_version; - enum wined3d_display_driver driver; - enum wined3d_driver_model driver_model; - const struct driver_version_information *version_info; memset(&os_version, 0, sizeof(os_version)); os_version.dwOSVersionInfoSize = sizeof(os_version); @@ -1642,6 +584,8 @@ static void init_driver_info(struct wined3d_driver_info *driver_info, TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion); switch (os_version.dwMajorVersion) { + case 2: + case 3: case 4: /* If needed we could distinguish between 9x and NT4, but this code won't make * sense for NT4 since it had no way to obtain this info through DirectDraw 3.0. @@ -1668,7 +612,7 @@ static void init_driver_info(struct wined3d_driver_info *driver_info, } else { - if (os_version.dwMinorVersion > 2) + if (os_version.dwMinorVersion > 3) { FIXME("Unhandled OS version %u.%u, reporting Win 8.\n", os_version.dwMajorVersion, os_version.dwMinorVersion); @@ -1676,2809 +620,163 @@ static void init_driver_info(struct wined3d_driver_info *driver_info, driver_os_version = 9; driver_model = DRIVER_MODEL_NT6X; } - break; - - case 10: - driver_os_version = 10; - driver_model = DRIVER_MODEL_NT6X; - break; - - default: - FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n", - os_version.dwMajorVersion, os_version.dwMinorVersion); - driver_os_version = 6; - driver_model = DRIVER_MODEL_NT5X; - break; - } - } - - driver_info->vendor = gpu_desc->vendor; - driver_info->device = gpu_desc->card; - driver_info->description = gpu_desc->description; - driver_info->vram_bytes = vram_bytes ? vram_bytes : (UINT64)gpu_desc->vidmem * 1024 * 1024; - driver = gpu_desc->driver; - - /** - * Diablo 2 crashes when the amount of video memory is greater than 0x7fffffff. - * In order to avoid this application bug we limit the amount of video memory - * to LONG_MAX for older Windows versions. - */ -#ifdef __i386__ - if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX) - { - TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX); - driver_info->vram_bytes = LONG_MAX; - } -#endif - - /* Try to obtain driver version information for the current Windows version. This fails in - * some cases: - * - the gpu is not available on the currently selected OS version: - * - Geforce GTX480 on Win98. When running applications in compatibility mode on Windows, - * version information for the current Windows version is returned instead of faked info. - * We do the same and assume the default Windows version to emulate is WinXP. - * - * - Videocard is a Riva TNT but winver is set to win7 (there are no drivers for this beast) - * For now return the XP driver info. Perhaps later on we should return VESA. - * - * - the gpu is not in our database (can happen when the user overrides the vendor_id / device_id) - * This could be an indication that our database is not up to date, so this should be fixed. - */ - if ((version_info = get_driver_version_info(driver, driver_model)) - || (version_info = get_driver_version_info(driver, DRIVER_MODEL_GENERIC))) - { - driver_info->name = version_info->driver_name; - driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version); - driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build); - } - else - { - ERR("No driver version info found for device %04x:%04x, driver model %#x.\n", - driver_info->vendor, driver_info->device, driver_model); - driver_info->name = "Display"; - driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15); - driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */ - } - - TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n", - driver_info->version_high, driver_info->version_low); -} - -/* Context activation is done by the caller. */ -static void fixup_extensions(struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, - const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, - enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(quirk_table); ++i) - { - if (!quirk_table[i].match(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device)) continue; - TRACE("Applying driver quirk \"%s\".\n", quirk_table[i].description); - quirk_table[i].apply(gl_info); - } - - /* Find out if PBOs work as they are supposed to. */ - test_pbo_functionality(gl_info); -} - -static DWORD wined3d_parse_gl_version(const char *gl_version) -{ - const char *ptr = gl_version; - int major, minor; - - major = atoi(ptr); - if (major <= 0) - ERR("Invalid OpenGL major version %d.\n", major); - - while (isdigit(*ptr)) ++ptr; - if (*ptr++ != '.') - ERR("Invalid OpenGL version string %s.\n", debugstr_a(gl_version)); - - minor = atoi(ptr); - - TRACE("Found OpenGL version %d.%d.\n", major, minor); - - return MAKEDWORD_VERSION(major, minor); -} - -static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info, - const char *gl_vendor_string, const char *gl_renderer, const char *gl_version) -{ - /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from - * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to - * detect the Apple OpenGL implementation to apply some extension fixups afterwards. - * - * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks - * aren't sufficient either because a Linux binary may display on a macos X server via remote X11. - * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions - * like client storage might be supported on other implementations too, but GL_APPLE_flush_render - * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So - * the chance that other implementations support them is rather small since Win32 QuickTime uses - * DirectDraw, not OpenGL. */ - if (gl_info->supported[APPLE_FENCE] && gl_info->supported[APPLE_YCBCR_422]) - return GL_VENDOR_APPLE; - - if (strstr(gl_vendor_string, "NVIDIA")) - return GL_VENDOR_NVIDIA; - - if (strstr(gl_vendor_string, "ATI")) - return GL_VENDOR_FGLRX; - - if (strstr(gl_vendor_string, "Mesa") - || strstr(gl_vendor_string, "Brian Paul") - || strstr(gl_vendor_string, "X.Org") - || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.") - || strstr(gl_vendor_string, "DRI R300 Project") - || strstr(gl_vendor_string, "Tungsten Graphics, Inc") - || strstr(gl_vendor_string, "VMware, Inc.") - || strstr(gl_vendor_string, "Intel") - || strstr(gl_renderer, "Mesa") - || strstr(gl_renderer, "Gallium") - || strstr(gl_renderer, "Intel") - || strstr(gl_version, "Mesa")) - return GL_VENDOR_MESA; - - FIXME("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n", - debugstr_a(gl_vendor_string)); - - return GL_VENDOR_UNKNOWN; -} - -static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer) -{ - if (strstr(gl_vendor_string, "NVIDIA") - || strstr(gl_vendor_string, "Nouveau") - || strstr(gl_vendor_string, "nouveau")) - return HW_VENDOR_NVIDIA; - - if (strstr(gl_vendor_string, "ATI") - || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.") - || strstr(gl_vendor_string, "X.Org R300 Project") - || strstr(gl_renderer, "AMD") - || strstr(gl_renderer, "FirePro") - || strstr(gl_renderer, "Radeon") - || strstr(gl_renderer, "R100") - || strstr(gl_renderer, "R200") - || strstr(gl_renderer, "R300") - || strstr(gl_renderer, "R600") - || strstr(gl_renderer, "R700")) - return HW_VENDOR_AMD; - - if (strstr(gl_vendor_string, "Intel(R)") - /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */ - || strstr(gl_renderer, "Intel") - || strstr(gl_renderer, "i915") - || strstr(gl_vendor_string, "Intel Inc.")) - return HW_VENDOR_INTEL; - - if (strstr(gl_renderer, "SVGA3D")) - return HW_VENDOR_VMWARE; - - if (strstr(gl_vendor_string, "Mesa") - || strstr(gl_vendor_string, "Brian Paul") - || strstr(gl_vendor_string, "Tungsten Graphics, Inc") - || strstr(gl_vendor_string, "VMware, Inc.")) - return HW_VENDOR_SOFTWARE; - - FIXME("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string)); - - return HW_VENDOR_NVIDIA; -} - -static enum wined3d_d3d_level d3d_level_from_caps(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, DWORD glsl_version) -{ - if (shader_caps->vs_version >= 5) - return WINED3D_D3D_LEVEL_11; - if (shader_caps->vs_version == 4) - return WINED3D_D3D_LEVEL_10; - if (shader_caps->vs_version == 3) - { - /* wined3d with default settings at the moment doesn't expose SM4+ on - * Mesa drivers. */ - if (glsl_version >= MAKEDWORD_VERSION(4, 30)) - return WINED3D_D3D_LEVEL_11; - if (glsl_version >= MAKEDWORD_VERSION(1, 30)) - return WINED3D_D3D_LEVEL_10; - return WINED3D_D3D_LEVEL_9_SM3; - } - if (shader_caps->vs_version == 2) - return WINED3D_D3D_LEVEL_9_SM2; - if (shader_caps->vs_version == 1) - return WINED3D_D3D_LEVEL_8; - - if (fragment_caps->TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3) - return WINED3D_D3D_LEVEL_7; - if (fragment_caps->MaxSimultaneousTextures > 1) - return WINED3D_D3D_LEVEL_6; - - return WINED3D_D3D_LEVEL_5; -} - -static const struct wined3d_renderer_table -{ - const char *renderer; - enum wined3d_pci_device id; -} -cards_nvidia_binary[] = -{ - /* Direct 3D 11 */ - {"TITAN X (Pascal)", CARD_NVIDIA_TITANX_PASCAL}, /* GeForce 1000 - highend */ - {"GTX 1080 Ti", CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */ - {"GTX 1080", CARD_NVIDIA_GEFORCE_GTX1080}, /* GeForce 1000 - highend */ - {"GTX 1070", CARD_NVIDIA_GEFORCE_GTX1070}, /* GeForce 1000 - highend */ - {"GTX 1060", CARD_NVIDIA_GEFORCE_GTX1060}, /* GeForce 1000 - midend high */ - {"GTX 1050", CARD_NVIDIA_GEFORCE_GTX1050}, /* GeForce 1000 - midend */ - {"GTX 980 Ti", CARD_NVIDIA_GEFORCE_GTX980TI}, /* GeForce 900 - highend */ - {"GTX 980", CARD_NVIDIA_GEFORCE_GTX980}, /* GeForce 900 - highend */ - {"GTX 970M", CARD_NVIDIA_GEFORCE_GTX970M}, /* GeForce 900 - highend mobile*/ - {"GTX 970", CARD_NVIDIA_GEFORCE_GTX970}, /* GeForce 900 - highend */ - {"GTX TITAN X", CARD_NVIDIA_GEFORCE_GTXTITANX}, /* Geforce 900 - highend */ - {"GTX 960M", CARD_NVIDIA_GEFORCE_GTX960M}, /* GeForce 900 - midend high mobile */ - {"GTX 960", CARD_NVIDIA_GEFORCE_GTX960}, /* GeForce 900 - midend high */ - {"GTX 950M", CARD_NVIDIA_GEFORCE_GTX950M}, /* GeForce 900 - midend mobile */ - {"GTX 950", CARD_NVIDIA_GEFORCE_GTX950}, /* GeForce 900 - midend */ - {"GeForce 940M", CARD_NVIDIA_GEFORCE_940M}, /* GeForce 900 - midend mobile */ - {"GTX 880M", CARD_NVIDIA_GEFORCE_GTX880M}, /* GeForce 800 - mobile */ - {"GTX 870M", CARD_NVIDIA_GEFORCE_GTX870M}, /* GeForce 800 - mobile */ - {"GTX 860M", CARD_NVIDIA_GEFORCE_GTX860M}, /* GeForce 800 - mobile */ - {"GTX 850M", CARD_NVIDIA_GEFORCE_GTX850M}, /* GeForce 800 - mobile */ - {"GeForce 845M", CARD_NVIDIA_GEFORCE_845M}, /* GeForce 800 - mobile */ - {"GeForce 840M", CARD_NVIDIA_GEFORCE_840M}, /* GeForce 800 - mobile */ - {"GeForce 830M", CARD_NVIDIA_GEFORCE_830M}, /* GeForce 800 - mobile */ - {"GeForce 820M", CARD_NVIDIA_GEFORCE_820M}, /* GeForce 800 - mobile */ - {"GTX 780 Ti", CARD_NVIDIA_GEFORCE_GTX780TI}, /* Geforce 700 - highend */ - {"GTX TITAN Black", CARD_NVIDIA_GEFORCE_GTXTITANB}, /* Geforce 700 - highend */ - {"GTX TITAN Z", CARD_NVIDIA_GEFORCE_GTXTITANZ}, /* Geforce 700 - highend */ - {"GTX TITAN", CARD_NVIDIA_GEFORCE_GTXTITAN}, /* Geforce 700 - highend */ - {"GTX 780", CARD_NVIDIA_GEFORCE_GTX780}, /* Geforce 700 - highend */ - {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */ - {"GTX 770", CARD_NVIDIA_GEFORCE_GTX770}, /* Geforce 700 - highend */ - {"GTX 765M", CARD_NVIDIA_GEFORCE_GTX765M}, /* Geforce 700 - midend high mobile */ - {"GTX 760 Ti", CARD_NVIDIA_GEFORCE_GTX760TI}, /* Geforce 700 - midend high */ - {"GTX 760", CARD_NVIDIA_GEFORCE_GTX760}, /* Geforce 700 - midend high */ - {"GTX 750 Ti", CARD_NVIDIA_GEFORCE_GTX750TI}, /* Geforce 700 - midend */ - {"GTX 750", CARD_NVIDIA_GEFORCE_GTX750}, /* Geforce 700 - midend */ - {"GT 750M", CARD_NVIDIA_GEFORCE_GT750M}, /* Geforce 700 - midend mobile */ - {"GT 740M", CARD_NVIDIA_GEFORCE_GT740M}, /* Geforce 700 - midend mobile */ - {"GT 730M", CARD_NVIDIA_GEFORCE_GT730M}, /* Geforce 700 - midend mobile */ - {"GT 730", CARD_NVIDIA_GEFORCE_GT730}, /* Geforce 700 - lowend */ - {"GTX 690", CARD_NVIDIA_GEFORCE_GTX690}, /* Geforce 600 - highend */ - {"GTX 680", CARD_NVIDIA_GEFORCE_GTX680}, /* Geforce 600 - highend */ - {"GTX 675MX", CARD_NVIDIA_GEFORCE_GTX675MX}, /* Geforce 600 - highend */ - {"GTX 670MX", CARD_NVIDIA_GEFORCE_GTX670MX}, /* Geforce 600 - highend */ - {"GTX 670", CARD_NVIDIA_GEFORCE_GTX670}, /* Geforce 600 - midend high */ - {"GTX 660 Ti", CARD_NVIDIA_GEFORCE_GTX660TI}, /* Geforce 600 - midend high */ - {"GTX 660M", CARD_NVIDIA_GEFORCE_GTX660M}, /* Geforce 600 - midend high mobile */ - {"GTX 660", CARD_NVIDIA_GEFORCE_GTX660}, /* Geforce 600 - midend high */ - {"GTX 650 Ti", CARD_NVIDIA_GEFORCE_GTX650TI}, /* Geforce 600 - lowend */ - {"GTX 650", CARD_NVIDIA_GEFORCE_GTX650}, /* Geforce 600 - lowend */ - {"GT 650M", CARD_NVIDIA_GEFORCE_GT650M}, /* Geforce 600 - midend mobile */ - {"GT 640M", CARD_NVIDIA_GEFORCE_GT640M}, /* Geforce 600 - midend mobile */ - {"GT 630M", CARD_NVIDIA_GEFORCE_GT630M}, /* Geforce 600 - midend mobile */ - {"GT 630", CARD_NVIDIA_GEFORCE_GT630}, /* Geforce 600 - lowend */ - {"GT 610", CARD_NVIDIA_GEFORCE_GT610}, /* Geforce 600 - lowend */ - {"GTX 580", CARD_NVIDIA_GEFORCE_GTX580}, /* Geforce 500 - highend */ - {"GTX 570", CARD_NVIDIA_GEFORCE_GTX570}, /* Geforce 500 - midend high */ - {"GTX 560 Ti", CARD_NVIDIA_GEFORCE_GTX560TI}, /* Geforce 500 - midend */ - {"GTX 560M", CARD_NVIDIA_GEFORCE_GTX560M}, /* Geforce 500 - midend mobile */ - {"GTX 560", CARD_NVIDIA_GEFORCE_GTX560}, /* Geforce 500 - midend */ - {"GT 555M", CARD_NVIDIA_GEFORCE_GT555M}, /* Geforce 500 - midend mobile */ - {"GTX 550 Ti", CARD_NVIDIA_GEFORCE_GTX550}, /* Geforce 500 - midend */ - {"GT 540M", CARD_NVIDIA_GEFORCE_GT540M}, /* Geforce 500 - midend mobile */ - {"GT 525M", CARD_NVIDIA_GEFORCE_GT525M}, /* Geforce 500 - lowend mobile */ - {"GT 520", CARD_NVIDIA_GEFORCE_GT520}, /* Geforce 500 - lowend */ - {"GTX 480", CARD_NVIDIA_GEFORCE_GTX480}, /* Geforce 400 - highend */ - {"GTX 470", CARD_NVIDIA_GEFORCE_GTX470}, /* Geforce 400 - midend high */ - /* Direct 3D 10 */ - {"GTX 465", CARD_NVIDIA_GEFORCE_GTX465}, /* Geforce 400 - midend */ - {"GTX 460M", CARD_NVIDIA_GEFORCE_GTX460M}, /* Geforce 400 - highend mobile */ - {"GTX 460", CARD_NVIDIA_GEFORCE_GTX460}, /* Geforce 400 - midend */ - {"GTS 450", CARD_NVIDIA_GEFORCE_GTS450}, /* Geforce 400 - midend low */ - {"GT 440", CARD_NVIDIA_GEFORCE_GT440}, /* Geforce 400 - lowend */ - {"GT 430", CARD_NVIDIA_GEFORCE_GT430}, /* Geforce 400 - lowend */ - {"GT 425M", CARD_NVIDIA_GEFORCE_GT425M}, /* Geforce 400 - lowend mobile */ - {"GT 420", CARD_NVIDIA_GEFORCE_GT420}, /* Geforce 400 - lowend */ - {"410M", CARD_NVIDIA_GEFORCE_410M}, /* Geforce 400 - lowend mobile */ - {"GT 330", CARD_NVIDIA_GEFORCE_GT330}, /* Geforce 300 - highend */ - {"GTS 360M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */ - {"GTS 350M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */ - {"GT 330M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */ - {"GT 325M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */ - {"GT 320M", CARD_NVIDIA_GEFORCE_GT320M}, /* Geforce 300 - midend mobile */ - {"320M", CARD_NVIDIA_GEFORCE_320M}, /* Geforce 300 - midend mobile */ - {"315M", CARD_NVIDIA_GEFORCE_315M}, /* Geforce 300 - midend mobile */ - {"GTX 295", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ - {"GTX 285", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ - {"GTX 280", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ - {"GTX 275", CARD_NVIDIA_GEFORCE_GTX275}, /* Geforce 200 - midend high */ - {"GTX 260", CARD_NVIDIA_GEFORCE_GTX260}, /* Geforce 200 - midend */ - {"GTS 250", CARD_NVIDIA_GEFORCE_GTS250}, /* Geforce 200 - midend */ - {"GT 240", CARD_NVIDIA_GEFORCE_GT240}, /* Geforce 200 - midend */ - {"GT 220", CARD_NVIDIA_GEFORCE_GT220}, /* Geforce 200 - lowend */ - {"GeForce 310", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ - {"GeForce 305", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ - {"GeForce 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ - {"G 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ - {"GTS 150", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ - {"9800", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ - {"9700M GT", CARD_NVIDIA_GEFORCE_9700MGT}, /* Geforce 9 - midend */ - {"GT 140", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */ - {"9600", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */ - {"GT 130", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ - {"GT 120", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ - {"9500", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ - {"9400M", CARD_NVIDIA_GEFORCE_9400M}, /* Geforce 9 - lowend */ - {"9400", CARD_NVIDIA_GEFORCE_9400GT}, /* Geforce 9 - lowend */ - {"9300", CARD_NVIDIA_GEFORCE_9300}, /* Geforce 9 - lowend low */ - {"9200", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */ - {"9100", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */ - {"G 100", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */ - {"8800 GTX", CARD_NVIDIA_GEFORCE_8800GTX}, /* Geforce 8 - highend high */ - {"8800", CARD_NVIDIA_GEFORCE_8800GTS}, /* Geforce 8 - highend */ - {"8600M", CARD_NVIDIA_GEFORCE_8600MGT}, /* Geforce 8 - midend mobile */ - {"8600 M", CARD_NVIDIA_GEFORCE_8600MGT}, /* Geforce 8 - midend mobile */ - {"8700", CARD_NVIDIA_GEFORCE_8600GT}, /* Geforce 8 - midend */ - {"8600", CARD_NVIDIA_GEFORCE_8600GT}, /* Geforce 8 - midend */ - {"8500", CARD_NVIDIA_GEFORCE_8500GT}, /* Geforce 8 - mid-lowend */ - {"8400", CARD_NVIDIA_GEFORCE_8400GS}, /* Geforce 8 - mid-lowend */ - {"8300", CARD_NVIDIA_GEFORCE_8300GS}, /* Geforce 8 - lowend */ - {"8200", CARD_NVIDIA_GEFORCE_8200}, /* Geforce 8 - lowend */ - {"8100", CARD_NVIDIA_GEFORCE_8200}, /* Geforce 8 - lowend */ - /* Direct 3D 9 SM3 */ - {"Quadro FX 5", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ - {"Quadro FX 4", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ - {"7950", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ - {"7900", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ - {"7800", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */ - {"7700", CARD_NVIDIA_GEFORCE_7600}, /* Geforce 7 - midend */ - {"7600", CARD_NVIDIA_GEFORCE_7600}, /* Geforce 7 - midend */ - {"7400", CARD_NVIDIA_GEFORCE_7400}, /* Geforce 7 - lower medium */ - {"7300", CARD_NVIDIA_GEFORCE_7300}, /* Geforce 7 - lowend */ - {"6800", CARD_NVIDIA_GEFORCE_6800}, /* Geforce 6 - highend */ - {"6700", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */ - {"6610", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */ - {"6600", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */ - /* Direct 3D 9 SM2 */ - {"Quadro FX", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ - {"5950", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ - {"5900", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ - {"5800", CARD_NVIDIA_GEFORCEFX_5800}, /* GeforceFX - highend */ - {"5750", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ - {"5700", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ - {"5650", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ - {"5600", CARD_NVIDIA_GEFORCEFX_5600}, /* GeforceFX - midend */ - {"5500", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ - {"5300", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ - {"5250", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ - {"5200", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ - {"5100", CARD_NVIDIA_GEFORCEFX_5200}, /* GeforceFX - lowend */ - /* Direct 3D 8 */ - {"Quadro4", CARD_NVIDIA_GEFORCE4_TI4200}, - {"GeForce4 Ti", CARD_NVIDIA_GEFORCE4_TI4200}, /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800 */ - /* Direct 3D 7 */ - {"GeForce4 MX", CARD_NVIDIA_GEFORCE4_MX}, /* MX420/MX440/MX460/MX4000 */ - {"Quadro2 MXR", CARD_NVIDIA_GEFORCE2_MX}, - {"GeForce2 MX", CARD_NVIDIA_GEFORCE2_MX}, /* Geforce2 standard/MX100/MX200/MX400 */ - {"Quadro2", CARD_NVIDIA_GEFORCE2}, - {"GeForce2", CARD_NVIDIA_GEFORCE2}, /* Geforce2 GTS/Pro/Ti/Ultra */ - /* Direct 3D 6 */ - {"TNT2", CARD_NVIDIA_RIVA_TNT2}, /* Riva TNT2 standard/M64/Pro/Ultra */ -}, -/* See http://developer.amd.com/resources/hardware-drivers/ati-catalyst-pc-vendor-id-1002-li/ - * - * Beware: renderer string do not match exact card model, - * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */ -cards_amd_binary[] = -{ - {"RX 480", CARD_AMD_RADEON_RX_480}, - {"RX 460", CARD_AMD_RADEON_RX_460}, - {"R9 Fury Series", CARD_AMD_RADEON_R9_FURY}, - /* Southern Islands */ - {"HD 7900", CARD_AMD_RADEON_HD7900}, - {"HD 7800", CARD_AMD_RADEON_HD7800}, - {"HD 7700", CARD_AMD_RADEON_HD7700}, - /* Northern Islands */ - {"HD 6970", CARD_AMD_RADEON_HD6900}, - {"HD 6900", CARD_AMD_RADEON_HD6900}, - {"HD 6800", CARD_AMD_RADEON_HD6800}, - {"HD 6770M", CARD_AMD_RADEON_HD6600M}, - {"HD 6750M", CARD_AMD_RADEON_HD6600M}, - {"HD 6700", CARD_AMD_RADEON_HD6700}, - {"HD 6670", CARD_AMD_RADEON_HD6600}, - {"HD 6630M", CARD_AMD_RADEON_HD6600M}, - {"HD 6600M", CARD_AMD_RADEON_HD6600M}, - {"HD 6600", CARD_AMD_RADEON_HD6600}, - {"HD 6570", CARD_AMD_RADEON_HD6600}, - {"HD 6500M", CARD_AMD_RADEON_HD6600M}, - {"HD 6500", CARD_AMD_RADEON_HD6600}, - {"HD 6480G", CARD_AMD_RADEON_HD6480G}, - {"HD 6400", CARD_AMD_RADEON_HD6400}, - {"HD 6300", CARD_AMD_RADEON_HD6300}, - {"HD 6200", CARD_AMD_RADEON_HD6300}, - /* Evergreen */ - {"HD 5870", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS PRO */ - {"HD 5850", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS XT */ - {"HD 5800", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS HD58xx generic renderer string */ - {"HD 5770", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER XT */ - {"HD 5750", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER LE */ - {"HD 5700", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER HD57xx generic renderer string */ - {"HD 5670", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD XT */ - {"HD 5570", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD PRO mapped to HD5600 series */ - {"HD 5550", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD LE mapped to HD5600 series */ - {"HD 5450", CARD_AMD_RADEON_HD5400}, /* Radeon EG CEDAR PRO */ - {"HD 5000", CARD_AMD_RADEON_HD5600}, /* Defaulting to HD 5600 */ - /* R700 */ - {"HD 4890", CARD_AMD_RADEON_HD4800}, /* Radeon RV790 */ - {"HD 4870", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */ - {"HD 4850", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */ - {"HD 4830", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */ - {"HD 4800", CARD_AMD_RADEON_HD4800}, /* Radeon RV7xx HD48xx generic renderer string */ - {"HD 4770", CARD_AMD_RADEON_HD4700}, /* Radeon RV740 */ - {"HD 4700", CARD_AMD_RADEON_HD4700}, /* Radeon RV7xx HD47xx generic renderer string */ - {"HD 4670", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */ - {"HD 4650", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */ - {"HD 4600", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */ - {"HD 4550", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */ - {"HD 4350", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */ - /* R600/R700 integrated */ - {"HD 4200M", CARD_AMD_RADEON_HD4200M}, - {"HD 3300", CARD_AMD_RADEON_HD3200}, - {"HD 3200", CARD_AMD_RADEON_HD3200}, - {"HD 3100", CARD_AMD_RADEON_HD3200}, - /* R600 */ - {"HD 3870", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */ - {"HD 3850", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */ - {"HD 2900", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */ - {"HD 3830", CARD_AMD_RADEON_HD2600}, /* China-only midend */ - {"HD 3690", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */ - {"HD 3650", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */ - {"HD 2600", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */ - {"HD 3470", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ - {"HD 3450", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ - {"HD 3430", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ - {"HD 3400", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ - {"HD 2400", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ - {"HD 2350", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */ - /* Radeon R5xx */ - {"X1950", CARD_AMD_RADEON_X1600}, - {"X1900", CARD_AMD_RADEON_X1600}, - {"X1800", CARD_AMD_RADEON_X1600}, - {"X1650", CARD_AMD_RADEON_X1600}, - {"X1600", CARD_AMD_RADEON_X1600}, - /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx) - * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */ - {"HD 2300", CARD_AMD_RADEON_X700}, - {"X2500", CARD_AMD_RADEON_X700}, - {"X2300", CARD_AMD_RADEON_X700}, - {"X1550", CARD_AMD_RADEON_X700}, - {"X1450", CARD_AMD_RADEON_X700}, - {"X1400", CARD_AMD_RADEON_X700}, - {"X1300", CARD_AMD_RADEON_X700}, - {"X850", CARD_AMD_RADEON_X700}, - {"X800", CARD_AMD_RADEON_X700}, - {"X700", CARD_AMD_RADEON_X700}, - /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400 MHz */ - {"Radeon Xpress", CARD_AMD_RADEON_XPRESS_200M}, -}, -cards_intel[] = -{ - /* Skylake */ - {"Iris Pro Graphics P580", CARD_INTEL_IPP580_1}, - {"Skylake", CARD_INTEL_HD520_1}, - /* Broadwell */ - {"Iris Pro P6300", CARD_INTEL_IPP6300}, - {"Iris Pro 6200", CARD_INTEL_IP6200}, - {"Iris 6100", CARD_INTEL_I6100}, - {"Iris(TM) Graphics 6100", CARD_INTEL_I6100}, /* MacOS */ - /* Haswell */ - {"Iris Pro 5200", CARD_INTEL_IP5200_1}, - {"Iris 5100", CARD_INTEL_I5100_1}, - {"HD Graphics 5000", CARD_INTEL_HD5000}, /* MacOS */ - {"Haswell Mobile", CARD_INTEL_HWM}, - {"Iris OpenGL Engine", CARD_INTEL_HWM}, /* MacOS */ - /* Ivybridge */ - {"Ivybridge Server", CARD_INTEL_IVBS}, - {"Ivybridge Mobile", CARD_INTEL_IVBM}, - {"Ivybridge Desktop", CARD_INTEL_IVBD}, - {"HD Graphics 4000", CARD_INTEL_IVBD}, /* MacOS */ - /* Sandybridge */ - {"Sandybridge Server", CARD_INTEL_SNBS}, - {"Sandybridge Mobile", CARD_INTEL_SNBM}, - {"Sandybridge Desktop", CARD_INTEL_SNBD}, - /* Ironlake */ - {"Ironlake Mobile", CARD_INTEL_ILKM}, - {"Ironlake Desktop", CARD_INTEL_ILKD}, - /* G4x */ - {"B43", CARD_INTEL_B43}, - {"G41", CARD_INTEL_G41}, - {"G45", CARD_INTEL_G45}, - {"Q45", CARD_INTEL_Q45}, - {"Integrated Graphics Device", CARD_INTEL_IGD}, - {"GM45", CARD_INTEL_GM45}, - /* i965 */ - {"965GME", CARD_INTEL_965GME}, - {"965GM", CARD_INTEL_965GM}, - {"X3100", CARD_INTEL_965GM}, /* MacOS */ - {"946GZ", CARD_INTEL_946GZ}, - {"965G", CARD_INTEL_965G}, - {"965Q", CARD_INTEL_965Q}, - /* i945 */ - {"Pineview M", CARD_INTEL_PNVM}, - {"Pineview G", CARD_INTEL_PNVG}, - {"IGD", CARD_INTEL_PNVG}, - {"Q33", CARD_INTEL_Q33}, - {"G33", CARD_INTEL_G33}, - {"Q35", CARD_INTEL_Q35}, - {"945GME", CARD_INTEL_945GME}, - {"945GM", CARD_INTEL_945GM}, - {"GMA 950", CARD_INTEL_945GM}, /* MacOS */ - {"945G", CARD_INTEL_945G}, - /* i915 */ - {"915GM", CARD_INTEL_915GM}, - {"E7221G", CARD_INTEL_E7221G}, - {"915G", CARD_INTEL_915G}, - /* i8xx */ - {"865G", CARD_INTEL_865G}, - {"845G", CARD_INTEL_845G}, - {"855GM", CARD_INTEL_855GM}, - {"830M", CARD_INTEL_830M}, -}, -/* 20101109 - These are never returned by current Gallium radeon - * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. - * - * These are returned but not handled: RC410, RV380. */ -cards_amd_mesa[] = -{ - /* Polaris 10/11 */ - {"POLARIS10", CARD_AMD_RADEON_RX_480}, - {"POLARIS11", CARD_AMD_RADEON_RX_460}, - /* Volcanic Islands */ - {"FIJI", CARD_AMD_RADEON_R9_FURY}, - {"TONGA", CARD_AMD_RADEON_R9_285}, - /* Sea Islands */ - {"HAWAII", CARD_AMD_RADEON_R9_290}, - {"KAVERI", CARD_AMD_RADEON_R7 }, - {"KABINI", CARD_AMD_RADEON_R3 }, - {"BONAIRE", CARD_AMD_RADEON_HD8770}, - /* Southern Islands */ - {"OLAND", CARD_AMD_RADEON_HD8670}, - {"HAINAN", CARD_AMD_RADEON_HD8600M}, - {"TAHITI", CARD_AMD_RADEON_HD7900}, - {"PITCAIRN", CARD_AMD_RADEON_HD7800}, - {"CAPE VERDE", CARD_AMD_RADEON_HD7700}, - /* Northern Islands */ - {"ARUBA", CARD_AMD_RADEON_HD7660D}, - {"CAYMAN", CARD_AMD_RADEON_HD6900}, - {"BARTS", CARD_AMD_RADEON_HD6800}, - {"TURKS", CARD_AMD_RADEON_HD6600}, - {"SUMO2", CARD_AMD_RADEON_HD6410D}, /* SUMO2 first, because we do a strstr(). */ - {"SUMO", CARD_AMD_RADEON_HD6550D}, - {"CAICOS", CARD_AMD_RADEON_HD6400}, - {"PALM", CARD_AMD_RADEON_HD6300}, - /* Evergreen */ - {"HEMLOCK", CARD_AMD_RADEON_HD5900}, - {"CYPRESS", CARD_AMD_RADEON_HD5800}, - {"JUNIPER", CARD_AMD_RADEON_HD5700}, - {"REDWOOD", CARD_AMD_RADEON_HD5600}, - {"CEDAR", CARD_AMD_RADEON_HD5400}, - /* R700 */ - {"R700", CARD_AMD_RADEON_HD4800}, - {"RV790", CARD_AMD_RADEON_HD4800}, - {"RV770", CARD_AMD_RADEON_HD4800}, - {"RV740", CARD_AMD_RADEON_HD4700}, - {"RV730", CARD_AMD_RADEON_HD4600}, - {"RV710", CARD_AMD_RADEON_HD4350}, - /* R600/R700 integrated */ - {"RS880", CARD_AMD_RADEON_HD4200M}, - {"RS780", CARD_AMD_RADEON_HD3200}, - /* R600 */ - {"R680", CARD_AMD_RADEON_HD2900}, - {"R600", CARD_AMD_RADEON_HD2900}, - {"RV670", CARD_AMD_RADEON_HD3850}, - {"RV635", CARD_AMD_RADEON_HD2600}, - {"RV630", CARD_AMD_RADEON_HD2600}, - {"RV620", CARD_AMD_RADEON_HD2350}, - {"RV610", CARD_AMD_RADEON_HD2350}, - /* R500 */ - {"R580", CARD_AMD_RADEON_X1600}, - {"R520", CARD_AMD_RADEON_X1600}, - {"RV570", CARD_AMD_RADEON_X1600}, - {"RV560", CARD_AMD_RADEON_X1600}, - {"RV535", CARD_AMD_RADEON_X1600}, - {"RV530", CARD_AMD_RADEON_X1600}, - {"RV516", CARD_AMD_RADEON_X700}, - {"RV515", CARD_AMD_RADEON_X700}, - /* R400 */ - {"R481", CARD_AMD_RADEON_X700}, - {"R480", CARD_AMD_RADEON_X700}, - {"R430", CARD_AMD_RADEON_X700}, - {"R423", CARD_AMD_RADEON_X700}, - {"R420", CARD_AMD_RADEON_X700}, - {"R410", CARD_AMD_RADEON_X700}, - {"RV410", CARD_AMD_RADEON_X700}, - /* Radeon Xpress - onboard, DX9b, Shader 2.0, 300-400 MHz */ - {"RS740", CARD_AMD_RADEON_XPRESS_200M}, - {"RS690", CARD_AMD_RADEON_XPRESS_200M}, - {"RS600", CARD_AMD_RADEON_XPRESS_200M}, - {"RS485", CARD_AMD_RADEON_XPRESS_200M}, - {"RS482", CARD_AMD_RADEON_XPRESS_200M}, - {"RS480", CARD_AMD_RADEON_XPRESS_200M}, - {"RS400", CARD_AMD_RADEON_XPRESS_200M}, - /* R300 */ - {"R360", CARD_AMD_RADEON_9500}, - {"R350", CARD_AMD_RADEON_9500}, - {"R300", CARD_AMD_RADEON_9500}, - {"RV370", CARD_AMD_RADEON_9500}, - {"RV360", CARD_AMD_RADEON_9500}, - {"RV351", CARD_AMD_RADEON_9500}, - {"RV350", CARD_AMD_RADEON_9500}, -}, -cards_nvidia_mesa[] = -{ - /* Maxwell */ - {"NV124", CARD_NVIDIA_GEFORCE_GTX970}, - {"NV120", CARD_NVIDIA_GEFORCE_GTX980TI}, - {"NV118", CARD_NVIDIA_GEFORCE_840M}, - {"NV117", CARD_NVIDIA_GEFORCE_GTX750}, - /* Kepler */ - {"NV108", CARD_NVIDIA_GEFORCE_GT740M}, - {"NVF1", CARD_NVIDIA_GEFORCE_GTX780TI}, - {"NVF0", CARD_NVIDIA_GEFORCE_GTX780}, - {"NVE6", CARD_NVIDIA_GEFORCE_GTX770M}, - {"NVE4", CARD_NVIDIA_GEFORCE_GTX680}, /* 690 / 675MX / 760TI */ - /* Fermi */ - {"NVD9", CARD_NVIDIA_GEFORCE_GT520}, - {"NVD7", CARD_NVIDIA_GEFORCE_820M}, - {"NVCF", CARD_NVIDIA_GEFORCE_GTX550}, - {"NVCE", CARD_NVIDIA_GEFORCE_GTX560}, - {"NVC8", CARD_NVIDIA_GEFORCE_GTX570}, - {"NVC4", CARD_NVIDIA_GEFORCE_GTX460}, - {"NVC3", CARD_NVIDIA_GEFORCE_GT440}, - {"NVC1", CARD_NVIDIA_GEFORCE_GT420}, - {"NVC0", CARD_NVIDIA_GEFORCE_GTX480}, - /* Tesla */ - {"NVAF", CARD_NVIDIA_GEFORCE_GT320M}, - {"NVAC", CARD_NVIDIA_GEFORCE_8200}, - {"NVAA", CARD_NVIDIA_GEFORCE_8200}, /* 8100 */ - {"NVA8", CARD_NVIDIA_GEFORCE_210}, - {"NVA5", CARD_NVIDIA_GEFORCE_GT220}, - {"NVA3", CARD_NVIDIA_GEFORCE_GT240}, - {"NVA0", CARD_NVIDIA_GEFORCE_GTX280}, - {"NV98", CARD_NVIDIA_GEFORCE_9200}, - {"NV96", CARD_NVIDIA_GEFORCE_9400GT}, - {"NV94", CARD_NVIDIA_GEFORCE_9600GT}, - {"NV92", CARD_NVIDIA_GEFORCE_9800GT}, - {"NV86", CARD_NVIDIA_GEFORCE_8500GT}, - {"NV84", CARD_NVIDIA_GEFORCE_8600GT}, - {"NV50", CARD_NVIDIA_GEFORCE_8800GTX}, - /* Curie */ - {"NV68", CARD_NVIDIA_GEFORCE_6200}, /* 7050 */ - {"NV67", CARD_NVIDIA_GEFORCE_6200}, /* 7000M */ - {"NV63", CARD_NVIDIA_GEFORCE_6200}, /* 7100 */ - {"NV4E", CARD_NVIDIA_GEFORCE_6200}, /* 6100 Go / 6150 Go */ - {"NV4C", CARD_NVIDIA_GEFORCE_6200}, /* 6150SE */ - {"NV4B", CARD_NVIDIA_GEFORCE_7600}, - {"NV4A", CARD_NVIDIA_GEFORCE_6200}, - {"NV49", CARD_NVIDIA_GEFORCE_7800GT}, /* 7900 */ - {"NV47", CARD_NVIDIA_GEFORCE_7800GT}, - {"NV46", CARD_NVIDIA_GEFORCE_7400}, - {"NV45", CARD_NVIDIA_GEFORCE_6800}, - {"NV44", CARD_NVIDIA_GEFORCE_6200}, - {"NV43", CARD_NVIDIA_GEFORCE_6600GT}, - {"NV42", CARD_NVIDIA_GEFORCE_6800}, - {"NV41", CARD_NVIDIA_GEFORCE_6800}, - {"NV40", CARD_NVIDIA_GEFORCE_6800}, - /* Rankine */ - {"NV38", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5950 Ultra */ - {"NV36", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5700/5750 */ - {"NV35", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5900 */ - {"NV34", CARD_NVIDIA_GEFORCEFX_5200}, - {"NV31", CARD_NVIDIA_GEFORCEFX_5600}, - {"NV30", CARD_NVIDIA_GEFORCEFX_5800}, - /* Kelvin */ - {"nv28", CARD_NVIDIA_GEFORCE4_TI4200}, - {"nv25", CARD_NVIDIA_GEFORCE4_TI4200}, - {"nv20", CARD_NVIDIA_GEFORCE3}, - /* Celsius */ - {"nv1F", CARD_NVIDIA_GEFORCE4_MX}, /* GF4 MX IGP */ - {"nv1A", CARD_NVIDIA_GEFORCE2}, /* GF2 IGP */ - {"nv18", CARD_NVIDIA_GEFORCE4_MX}, - {"nv17", CARD_NVIDIA_GEFORCE4_MX}, - {"nv16", CARD_NVIDIA_GEFORCE2}, - {"nv15", CARD_NVIDIA_GEFORCE2}, - {"nv11", CARD_NVIDIA_GEFORCE2_MX}, - {"nv10", CARD_NVIDIA_GEFORCE}, - /* Fahrenheit */ - {"nv05", CARD_NVIDIA_RIVA_TNT2}, - {"nv04", CARD_NVIDIA_RIVA_TNT}, - {"nv03", CARD_NVIDIA_RIVA_128}, -}, -cards_vmware[] = -{ - {"SVGA3D", CARD_VMWARE_SVGA3D}, -}; - -static const struct gl_vendor_selection -{ - enum wined3d_gl_vendor gl_vendor; - const char *description; /* Description of the card selector i.e. Apple OS/X Intel */ - const struct wined3d_renderer_table *cards; /* To be used as cards[], pointer to the first member in an array */ - size_t cards_size; /* Number of entries in the array above */ -} -amd_gl_vendor_table[] = -{ - {GL_VENDOR_APPLE, "Apple OSX AMD/ATI binary driver", cards_amd_binary, ARRAY_SIZE(cards_amd_binary)}, - {GL_VENDOR_FGLRX, "AMD/ATI binary driver", cards_amd_binary, ARRAY_SIZE(cards_amd_binary)}, - {GL_VENDOR_MESA, "Mesa AMD/ATI driver", cards_amd_mesa, ARRAY_SIZE(cards_amd_mesa)}, -}, -nvidia_gl_vendor_table[] = -{ - {GL_VENDOR_APPLE, "Apple OSX NVidia binary driver", cards_nvidia_binary, ARRAY_SIZE(cards_nvidia_binary)}, - {GL_VENDOR_MESA, "Mesa Nouveau driver", cards_nvidia_mesa, ARRAY_SIZE(cards_nvidia_mesa)}, - {GL_VENDOR_NVIDIA, "Nvidia binary driver", cards_nvidia_binary, ARRAY_SIZE(cards_nvidia_binary)}, -}, -vmware_gl_vendor_table[] = -{ - {GL_VENDOR_MESA, "VMware driver", cards_vmware, ARRAY_SIZE(cards_vmware)}, -}, -intel_gl_vendor_table[] = -{ - {GL_VENDOR_APPLE, "Apple OSX Intel binary driver", cards_intel, ARRAY_SIZE(cards_intel)}, - {GL_VENDOR_MESA, "Mesa Intel driver", cards_intel, ARRAY_SIZE(cards_intel)}, -}; - -static const enum wined3d_pci_device -card_fallback_nvidia[] = -{ - CARD_NVIDIA_RIVA_128, /* D3D5 */ - CARD_NVIDIA_RIVA_TNT, /* D3D6 */ - CARD_NVIDIA_GEFORCE, /* D3D7 */ - CARD_NVIDIA_GEFORCE3, /* D3D8 */ - CARD_NVIDIA_GEFORCEFX_5800, /* D3D9_SM2 */ - CARD_NVIDIA_GEFORCE_6800, /* D3D9_SM3 */ - CARD_NVIDIA_GEFORCE_8800GTX, /* D3D10 */ - CARD_NVIDIA_GEFORCE_GTX470, /* D3D11 */ -}, -card_fallback_amd[] = -{ - CARD_AMD_RAGE_128PRO, /* D3D5 */ - CARD_AMD_RAGE_128PRO, /* D3D6 */ - CARD_AMD_RADEON_7200, /* D3D7 */ - CARD_AMD_RADEON_8500, /* D3D8 */ - CARD_AMD_RADEON_9500, /* D3D9_SM2 */ - CARD_AMD_RADEON_X1600, /* D3D9_SM3 */ - CARD_AMD_RADEON_HD2900, /* D3D10 */ - CARD_AMD_RADEON_HD5600, /* D3D11 */ -}, -card_fallback_intel[] = -{ - CARD_INTEL_845G, /* D3D5 */ - CARD_INTEL_845G, /* D3D6 */ - CARD_INTEL_845G, /* D3D7 */ - CARD_INTEL_915G, /* D3D8 */ - CARD_INTEL_915G, /* D3D9_SM2 */ - CARD_INTEL_945G, /* D3D9_SM3 */ - CARD_INTEL_G45, /* D3D10 */ - CARD_INTEL_IVBD, /* D3D11 */ -}; -C_ASSERT(ARRAY_SIZE(card_fallback_nvidia) == WINED3D_D3D_LEVEL_COUNT); -C_ASSERT(ARRAY_SIZE(card_fallback_amd) == WINED3D_D3D_LEVEL_COUNT); -C_ASSERT(ARRAY_SIZE(card_fallback_intel) == WINED3D_D3D_LEVEL_COUNT); - -static enum wined3d_pci_device select_card_handler(const struct gl_vendor_selection *table, - unsigned int table_size, enum wined3d_gl_vendor gl_vendor, const char *gl_renderer) -{ - unsigned int i, j; - - for (i = 0; i < table_size; ++i) - { - if (table[i].gl_vendor != gl_vendor) - continue; - - TRACE("Applying card selector \"%s\".\n", table[i].description); - - for (j = 0; j < table[i].cards_size; ++j) - { - if (strstr(gl_renderer, table[i].cards[j].renderer)) - return table[i].cards[j].id; - } - return PCI_DEVICE_NONE; - } - FIXME("Couldn't find a suitable card selector for GL vendor %04x (using GL_RENDERER %s)\n", - gl_vendor, debugstr_a(gl_renderer)); - - return PCI_DEVICE_NONE; -} - -static const struct -{ - enum wined3d_pci_vendor card_vendor; - const char *description; /* Description of the card selector i.e. Apple OS/X Intel */ - const struct gl_vendor_selection *gl_vendor_selection; - unsigned int gl_vendor_count; - const enum wined3d_pci_device *card_fallback; /* An array with D3D_LEVEL_COUNT elements */ -} -card_vendor_table[] = -{ - {HW_VENDOR_AMD, "AMD", amd_gl_vendor_table, - ARRAY_SIZE(amd_gl_vendor_table), - card_fallback_amd}, - {HW_VENDOR_NVIDIA, "Nvidia", nvidia_gl_vendor_table, - ARRAY_SIZE(nvidia_gl_vendor_table), - card_fallback_nvidia}, - {HW_VENDOR_VMWARE, "VMware", vmware_gl_vendor_table, - ARRAY_SIZE(vmware_gl_vendor_table), - card_fallback_amd}, - {HW_VENDOR_INTEL, "Intel", intel_gl_vendor_table, - ARRAY_SIZE(intel_gl_vendor_table), - card_fallback_intel}, -}; - - -static enum wined3d_pci_device wined3d_guess_card(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, - DWORD glsl_version, const char *gl_renderer, enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor) -{ - /* A Direct3D device object contains the PCI id (vendor + device) of the - * videocard which is used for rendering. Various applications use this - * information to get a rough estimation of the features of the card and - * some might use it for enabling 3d effects only on certain types of - * videocards. In some cases games might even use it to work around bugs - * which happen on certain videocards/driver combinations. The problem is - * that OpenGL only exposes a rendering string containing the name of the - * videocard and not the PCI id. - * - * Various games depend on the PCI id, so somehow we need to provide one. - * A simple option is to parse the renderer string and translate this to - * the right PCI id. This is a lot of work because there are more than 200 - * GPUs just for Nvidia. Various cards share the same renderer string, so - * the amount of code might be 'small' but there are quite a number of - * exceptions which would make this a pain to maintain. Another way would - * be to query the PCI id from the operating system (assuming this is the - * videocard which is used for rendering which is not always the case). - * This would work but it is not very portable. Second it would not work - * well in, let's say, a remote X situation in which the amount of 3d - * features which can be used is limited. - * - * As said most games only use the PCI id to get an indication of the - * capabilities of the card. It doesn't really matter if the given id is - * the correct one if we return the id of a card with similar 3d features. - * - * The code below checks the OpenGL capabilities of a videocard and matches - * that to a certain level of Direct3D functionality. Once a card passes - * the Direct3D9 check, we know that the card (in case of Nvidia) is at - * least a GeforceFX. To give a better estimate we do a basic check on the - * renderer string but if that won't pass we return a default card. This - * way is better than maintaining a full card database as even without a - * full database we can return a card with similar features. Second the - * size of the database can be made quite small because when you know what - * type of 3d functionality a card has, you know to which GPU family the - * GPU must belong. Because of this you only have to check a small part of - * the renderer string to distinguish between different models from that - * family. - * - * The code also selects a default amount of video memory which we will - * use for an estimation of the amount of free texture memory. In case of - * real D3D the amount of texture memory includes video memory and system - * memory (to be specific AGP memory or in case of PCIE TurboCache / - * HyperMemory). We don't know how much system memory can be addressed by - * the system but we can make a reasonable estimation about the amount of - * video memory. If the value is slightly wrong it doesn't matter as we - * didn't include AGP-like memory which makes the amount of addressable - * memory higher and second OpenGL isn't that critical it moves to system - * memory behind our backs if really needed. Note that the amount of video - * memory can be overruled using a registry setting. */ - - unsigned int i; - enum wined3d_d3d_level d3d_level = d3d_level_from_caps(shader_caps, fragment_caps, glsl_version); - enum wined3d_pci_device device; - - for (i = 0; i < ARRAY_SIZE(card_vendor_table); ++i) - { - if (card_vendor_table[i].card_vendor != *card_vendor) - continue; - - TRACE("Applying card selector \"%s\".\n", card_vendor_table[i].description); - device = select_card_handler(card_vendor_table[i].gl_vendor_selection, - card_vendor_table[i].gl_vendor_count, *gl_vendor, gl_renderer); - if (device != PCI_DEVICE_NONE) - return device; - - TRACE("Unrecognized renderer %s, falling back to default.\n", debugstr_a(gl_renderer)); - return card_vendor_table[i].card_fallback[d3d_level]; - } - - FIXME("No card selector available for card vendor %04x (using GL_RENDERER %s).\n", - *card_vendor, debugstr_a(gl_renderer)); - - /* Default to generic Nvidia hardware based on the supported OpenGL extensions. */ - *card_vendor = HW_VENDOR_NVIDIA; - return card_fallback_nvidia[d3d_level]; -} - -static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info, - const struct wined3d_shader_backend_ops *shader_backend_ops) -{ - if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_VERTEX_SHADER]) - return &glsl_vertex_pipe; - return &ffp_vertex_pipe; -} - -static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info, - const struct wined3d_shader_backend_ops *shader_backend_ops) -{ - if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_FRAGMENT_SHADER]) - return &glsl_fragment_pipe; - if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) - return &arbfp_fragment_pipeline; - if (gl_info->supported[ATI_FRAGMENT_SHADER]) - return &atifs_fragment_pipeline; - if (gl_info->supported[NV_REGISTER_COMBINERS] && gl_info->supported[NV_TEXTURE_SHADER2]) - return &nvts_fragment_pipeline; - if (gl_info->supported[NV_REGISTER_COMBINERS]) - return &nvrc_fragment_pipeline; - return &ffp_fragment_pipeline; -} - -static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info) -{ - BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20); - - if (glsl && gl_info->supported[ARB_VERTEX_SHADER] && gl_info->supported[ARB_FRAGMENT_SHADER]) - return &glsl_shader_backend; - if (gl_info->supported[ARB_VERTEX_PROGRAM] && gl_info->supported[ARB_FRAGMENT_PROGRAM]) - return &arb_program_shader_backend; - if (glsl && (gl_info->supported[ARB_VERTEX_SHADER] || gl_info->supported[ARB_FRAGMENT_SHADER])) - return &glsl_shader_backend; - if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM]) - return &arb_program_shader_backend; - return &none_shader_backend; -} - -static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *extensions, - const struct wined3d_extension_map *map, UINT entry_count) -{ - while (*extensions) - { - const char *start; - size_t len; - UINT i; - - while (isspace(*extensions)) - ++extensions; - start = extensions; - while (!isspace(*extensions) && *extensions) - ++extensions; - - len = extensions - start; - if (!len) - continue; - - TRACE("- %s.\n", debugstr_an(start, len)); - - for (i = 0; i < entry_count; ++i) - { - if (len == strlen(map[i].extension_string) - && !memcmp(start, map[i].extension_string, len)) - { - TRACE(" FOUND: %s support.\n", map[i].extension_string); - gl_info->supported[map[i].extension] = TRUE; - break; - } - } - } -} - -static void enumerate_gl_extensions(struct wined3d_gl_info *gl_info, - const struct wined3d_extension_map *map, unsigned int map_entries_count) -{ - const char *gl_extension_name; - unsigned int i, j; - GLint extensions_count; - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count); - for (i = 0; i < extensions_count; ++i) - { - gl_extension_name = (const char *)GL_EXTCALL(glGetStringi(GL_EXTENSIONS, i)); - TRACE("- %s.\n", debugstr_a(gl_extension_name)); - for (j = 0; j < map_entries_count; ++j) - { - if (!strcmp(gl_extension_name, map[j].extension_string)) - { - TRACE("FOUND: %s support.\n", map[j].extension_string); - gl_info->supported[map[j].extension] = TRUE; - break; - } - } - } -} - -static void load_gl_funcs(struct wined3d_gl_info *gl_info) -{ -#define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn); - /* GL_APPLE_fence */ - USE_GL_FUNC(glDeleteFencesAPPLE) - USE_GL_FUNC(glFinishFenceAPPLE) - USE_GL_FUNC(glFinishObjectAPPLE) - USE_GL_FUNC(glGenFencesAPPLE) - USE_GL_FUNC(glIsFenceAPPLE) - USE_GL_FUNC(glSetFenceAPPLE) - USE_GL_FUNC(glTestFenceAPPLE) - USE_GL_FUNC(glTestObjectAPPLE) - /* GL_APPLE_flush_buffer_range */ - USE_GL_FUNC(glBufferParameteriAPPLE) - USE_GL_FUNC(glFlushMappedBufferRangeAPPLE) - /* GL_ARB_base_instance */ - USE_GL_FUNC(glDrawArraysInstancedBaseInstance) - USE_GL_FUNC(glDrawElementsInstancedBaseVertexBaseInstance) - /* GL_ARB_blend_func_extended */ - USE_GL_FUNC(glBindFragDataLocationIndexed) - USE_GL_FUNC(glGetFragDataIndex) - /* GL_ARB_clear_buffer_object */ - USE_GL_FUNC(glClearBufferData) - USE_GL_FUNC(glClearBufferSubData) - /* GL_ARB_clear_texture */ - USE_GL_FUNC(glClearTexImage) - USE_GL_FUNC(glClearTexSubImage) - /* GL_ARB_clip_control */ - USE_GL_FUNC(glClipControl) - /* GL_ARB_color_buffer_float */ - USE_GL_FUNC(glClampColorARB) - /* GL_ARB_compute_shader */ - USE_GL_FUNC(glDispatchCompute) - USE_GL_FUNC(glDispatchComputeIndirect) - /* GL_ARB_copy_buffer */ - USE_GL_FUNC(glCopyBufferSubData) - /* GL_ARB_copy_image */ - USE_GL_FUNC(glCopyImageSubData) - /* GL_ARB_debug_output */ - USE_GL_FUNC(glDebugMessageCallbackARB) - USE_GL_FUNC(glDebugMessageControlARB) - USE_GL_FUNC(glDebugMessageInsertARB) - USE_GL_FUNC(glGetDebugMessageLogARB) - /* GL_ARB_draw_buffers */ - USE_GL_FUNC(glDrawBuffersARB) - /* GL_ARB_draw_elements_base_vertex */ - USE_GL_FUNC(glDrawElementsBaseVertex) - USE_GL_FUNC(glDrawElementsInstancedBaseVertex) - USE_GL_FUNC(glDrawRangeElementsBaseVertex) - USE_GL_FUNC(glMultiDrawElementsBaseVertex) - /* GL_ARB_draw_indirect */ - USE_GL_FUNC(glDrawArraysIndirect) - USE_GL_FUNC(glDrawElementsIndirect) - /* GL_ARB_draw_instanced */ - USE_GL_FUNC(glDrawArraysInstancedARB) - USE_GL_FUNC(glDrawElementsInstancedARB) - /* GL_ARB_ES2_compatibility */ - USE_GL_FUNC(glReleaseShaderCompiler) - USE_GL_FUNC(glShaderBinary) - USE_GL_FUNC(glGetShaderPrecisionFormat) - USE_GL_FUNC(glDepthRangef) - USE_GL_FUNC(glClearDepthf) - /* GL_ARB_framebuffer_no_attachments */ - USE_GL_FUNC(glFramebufferParameteri) - /* GL_ARB_framebuffer_object */ - USE_GL_FUNC(glBindFramebuffer) - USE_GL_FUNC(glBindRenderbuffer) - USE_GL_FUNC(glBlitFramebuffer) - USE_GL_FUNC(glCheckFramebufferStatus) - USE_GL_FUNC(glDeleteFramebuffers) - USE_GL_FUNC(glDeleteRenderbuffers) - USE_GL_FUNC(glFramebufferRenderbuffer) - USE_GL_FUNC(glFramebufferTexture) - USE_GL_FUNC(glFramebufferTexture1D) - USE_GL_FUNC(glFramebufferTexture2D) - USE_GL_FUNC(glFramebufferTexture3D) - USE_GL_FUNC(glFramebufferTextureLayer) - USE_GL_FUNC(glGenFramebuffers) - USE_GL_FUNC(glGenRenderbuffers) - USE_GL_FUNC(glGenerateMipmap) - USE_GL_FUNC(glGetFramebufferAttachmentParameteriv) - USE_GL_FUNC(glGetRenderbufferParameteriv) - USE_GL_FUNC(glIsFramebuffer) - USE_GL_FUNC(glIsRenderbuffer) - USE_GL_FUNC(glRenderbufferStorage) - USE_GL_FUNC(glRenderbufferStorageMultisample) - /* GL_ARB_geometry_shader4 */ - USE_GL_FUNC(glFramebufferTextureARB) - USE_GL_FUNC(glFramebufferTextureFaceARB) - USE_GL_FUNC(glFramebufferTextureLayerARB) - USE_GL_FUNC(glProgramParameteriARB) - /* GL_ARB_instanced_arrays */ - USE_GL_FUNC(glVertexAttribDivisorARB) - /* GL_ARB_internalformat_query */ - USE_GL_FUNC(glGetInternalformativ) - /* GL_ARB_internalformat_query2 */ - USE_GL_FUNC(glGetInternalformati64v) - /* GL_ARB_map_buffer_range */ - USE_GL_FUNC(glFlushMappedBufferRange) - USE_GL_FUNC(glMapBufferRange) - /* GL_ARB_multisample */ - USE_GL_FUNC(glSampleCoverageARB) - /* GL_ARB_multitexture */ - USE_GL_FUNC(glActiveTextureARB) - USE_GL_FUNC(glClientActiveTextureARB) - USE_GL_FUNC(glMultiTexCoord1fARB) - USE_GL_FUNC(glMultiTexCoord1fvARB) - USE_GL_FUNC(glMultiTexCoord2fARB) - USE_GL_FUNC(glMultiTexCoord2fvARB) - USE_GL_FUNC(glMultiTexCoord2svARB) - USE_GL_FUNC(glMultiTexCoord3fARB) - USE_GL_FUNC(glMultiTexCoord3fvARB) - USE_GL_FUNC(glMultiTexCoord4fARB) - USE_GL_FUNC(glMultiTexCoord4fvARB) - USE_GL_FUNC(glMultiTexCoord4svARB) - /* GL_ARB_occlusion_query */ - USE_GL_FUNC(glBeginQueryARB) - USE_GL_FUNC(glDeleteQueriesARB) - USE_GL_FUNC(glEndQueryARB) - USE_GL_FUNC(glGenQueriesARB) - USE_GL_FUNC(glGetQueryivARB) - USE_GL_FUNC(glGetQueryObjectivARB) - USE_GL_FUNC(glGetQueryObjectuivARB) - USE_GL_FUNC(glIsQueryARB) - /* GL_ARB_point_parameters */ - USE_GL_FUNC(glPointParameterfARB) - USE_GL_FUNC(glPointParameterfvARB) - /* GL_ARB_provoking_vertex */ - USE_GL_FUNC(glProvokingVertex) - /* GL_ARB_sampler_objects */ - USE_GL_FUNC(glGenSamplers) - USE_GL_FUNC(glDeleteSamplers) - USE_GL_FUNC(glIsSampler) - USE_GL_FUNC(glBindSampler) - USE_GL_FUNC(glSamplerParameteri) - USE_GL_FUNC(glSamplerParameterf) - USE_GL_FUNC(glSamplerParameteriv) - USE_GL_FUNC(glSamplerParameterfv) - USE_GL_FUNC(glSamplerParameterIiv) - USE_GL_FUNC(glSamplerParameterIuiv) - USE_GL_FUNC(glGetSamplerParameteriv) - USE_GL_FUNC(glGetSamplerParameterfv) - USE_GL_FUNC(glGetSamplerParameterIiv) - USE_GL_FUNC(glGetSamplerParameterIuiv) - /* GL_ARB_shader_atomic_counters */ - USE_GL_FUNC(glGetActiveAtomicCounterBufferiv) - /* GL_ARB_shader_image_load_store */ - USE_GL_FUNC(glBindImageTexture) - USE_GL_FUNC(glMemoryBarrier) - /* GL_ARB_shader_objects */ - USE_GL_FUNC(glAttachObjectARB) - USE_GL_FUNC(glBindAttribLocationARB) - USE_GL_FUNC(glCompileShaderARB) - USE_GL_FUNC(glCreateProgramObjectARB) - USE_GL_FUNC(glCreateShaderObjectARB) - USE_GL_FUNC(glDeleteObjectARB) - USE_GL_FUNC(glDetachObjectARB) - USE_GL_FUNC(glGetActiveUniformARB) - USE_GL_FUNC(glGetAttachedObjectsARB) - USE_GL_FUNC(glGetAttribLocationARB) - USE_GL_FUNC(glGetHandleARB) - USE_GL_FUNC(glGetInfoLogARB) - USE_GL_FUNC(glGetObjectParameterfvARB) - USE_GL_FUNC(glGetObjectParameterivARB) - USE_GL_FUNC(glGetShaderSourceARB) - USE_GL_FUNC(glGetUniformLocationARB) - USE_GL_FUNC(glGetUniformfvARB) - USE_GL_FUNC(glGetUniformivARB) - USE_GL_FUNC(glLinkProgramARB) - USE_GL_FUNC(glShaderSourceARB) - USE_GL_FUNC(glUniform1fARB) - USE_GL_FUNC(glUniform1fvARB) - USE_GL_FUNC(glUniform1iARB) - USE_GL_FUNC(glUniform1ivARB) - USE_GL_FUNC(glUniform2fARB) - USE_GL_FUNC(glUniform2fvARB) - USE_GL_FUNC(glUniform2iARB) - USE_GL_FUNC(glUniform2ivARB) - USE_GL_FUNC(glUniform3fARB) - USE_GL_FUNC(glUniform3fvARB) - USE_GL_FUNC(glUniform3iARB) - USE_GL_FUNC(glUniform3ivARB) - USE_GL_FUNC(glUniform4fARB) - USE_GL_FUNC(glUniform4fvARB) - USE_GL_FUNC(glUniform4iARB) - USE_GL_FUNC(glUniform4ivARB) - USE_GL_FUNC(glUniformMatrix2fvARB) - USE_GL_FUNC(glUniformMatrix3fvARB) - USE_GL_FUNC(glUniformMatrix4fvARB) - USE_GL_FUNC(glUseProgramObjectARB) - USE_GL_FUNC(glValidateProgramARB) - /* GL_ARB_shader_storage_buffer_object */ - USE_GL_FUNC(glShaderStorageBlockBinding) - /* GL_ARB_sync */ - USE_GL_FUNC(glClientWaitSync) - USE_GL_FUNC(glDeleteSync) - USE_GL_FUNC(glFenceSync) - USE_GL_FUNC(glGetInteger64v) - USE_GL_FUNC(glGetSynciv) - USE_GL_FUNC(glIsSync) - USE_GL_FUNC(glWaitSync) - /* GL_ARB_tessellation_shader */ - USE_GL_FUNC(glPatchParameteri) - USE_GL_FUNC(glPatchParameterfv) - /* GL_ARB_texture_buffer_object */ - USE_GL_FUNC(glTexBufferARB) - /* GL_ARB_texture_buffer_range */ - USE_GL_FUNC(glTexBufferRange) - /* GL_ARB_texture_compression */ - USE_GL_FUNC(glCompressedTexImage2DARB) - USE_GL_FUNC(glCompressedTexImage3DARB) - USE_GL_FUNC(glCompressedTexSubImage2DARB) - USE_GL_FUNC(glCompressedTexSubImage3DARB) - USE_GL_FUNC(glGetCompressedTexImageARB) - /* GL_ARB_texture_multisample */ - USE_GL_FUNC(glGetMultisamplefv); - USE_GL_FUNC(glSampleMaski); - USE_GL_FUNC(glTexImage2DMultisample); - USE_GL_FUNC(glTexImage3DMultisample); - /* GL_ARB_texture_storage */ - USE_GL_FUNC(glTexStorage1D) - USE_GL_FUNC(glTexStorage2D) - USE_GL_FUNC(glTexStorage3D) - /* GL_ARB_texture_storage_multisample */ - USE_GL_FUNC(glTexStorage2DMultisample); - USE_GL_FUNC(glTexStorage3DMultisample); - /* GL_ARB_texture_view */ - USE_GL_FUNC(glTextureView) - /* GL_ARB_timer_query */ - USE_GL_FUNC(glQueryCounter) - USE_GL_FUNC(glGetQueryObjectui64v) - /* GL_ARB_transform_feedback2 */ - USE_GL_FUNC(glBindTransformFeedback); - USE_GL_FUNC(glDeleteTransformFeedbacks); - USE_GL_FUNC(glDrawTransformFeedback); - USE_GL_FUNC(glGenTransformFeedbacks); - USE_GL_FUNC(glIsTransformFeedback); - USE_GL_FUNC(glPauseTransformFeedback); - USE_GL_FUNC(glResumeTransformFeedback); - /* GL_ARB_transform_feedback3 */ - USE_GL_FUNC(glBeginQueryIndexed); - USE_GL_FUNC(glDrawTransformFeedbackStream); - USE_GL_FUNC(glEndQueryIndexed); - USE_GL_FUNC(glGetQueryIndexediv); - /* GL_ARB_uniform_buffer_object */ - USE_GL_FUNC(glBindBufferBase) - USE_GL_FUNC(glBindBufferRange) - USE_GL_FUNC(glGetActiveUniformBlockName) - USE_GL_FUNC(glGetActiveUniformBlockiv) - USE_GL_FUNC(glGetActiveUniformName) - USE_GL_FUNC(glGetActiveUniformsiv) - USE_GL_FUNC(glGetIntegeri_v) - USE_GL_FUNC(glGetUniformBlockIndex) - USE_GL_FUNC(glGetUniformIndices) - USE_GL_FUNC(glUniformBlockBinding) - /* GL_ARB_vertex_blend */ - USE_GL_FUNC(glVertexBlendARB) - USE_GL_FUNC(glWeightPointerARB) - USE_GL_FUNC(glWeightbvARB) - USE_GL_FUNC(glWeightdvARB) - USE_GL_FUNC(glWeightfvARB) - USE_GL_FUNC(glWeightivARB) - USE_GL_FUNC(glWeightsvARB) - USE_GL_FUNC(glWeightubvARB) - USE_GL_FUNC(glWeightuivARB) - USE_GL_FUNC(glWeightusvARB) - /* GL_ARB_vertex_buffer_object */ - USE_GL_FUNC(glBindBufferARB) - USE_GL_FUNC(glBufferDataARB) - USE_GL_FUNC(glBufferSubDataARB) - USE_GL_FUNC(glDeleteBuffersARB) - USE_GL_FUNC(glGenBuffersARB) - USE_GL_FUNC(glGetBufferParameterivARB) - USE_GL_FUNC(glGetBufferPointervARB) - USE_GL_FUNC(glGetBufferSubDataARB) - USE_GL_FUNC(glIsBufferARB) - USE_GL_FUNC(glMapBufferARB) - USE_GL_FUNC(glUnmapBufferARB) - /* GL_ARB_vertex_program */ - USE_GL_FUNC(glBindProgramARB) - USE_GL_FUNC(glDeleteProgramsARB) - USE_GL_FUNC(glDisableVertexAttribArrayARB) - USE_GL_FUNC(glEnableVertexAttribArrayARB) - USE_GL_FUNC(glGenProgramsARB) - USE_GL_FUNC(glGetProgramivARB) - USE_GL_FUNC(glProgramEnvParameter4fvARB) - USE_GL_FUNC(glProgramLocalParameter4fvARB) - USE_GL_FUNC(glProgramStringARB) - USE_GL_FUNC(glVertexAttrib1dARB) - USE_GL_FUNC(glVertexAttrib1dvARB) - USE_GL_FUNC(glVertexAttrib1fARB) - USE_GL_FUNC(glVertexAttrib1fvARB) - USE_GL_FUNC(glVertexAttrib1sARB) - USE_GL_FUNC(glVertexAttrib1svARB) - USE_GL_FUNC(glVertexAttrib2dARB) - USE_GL_FUNC(glVertexAttrib2dvARB) - USE_GL_FUNC(glVertexAttrib2fARB) - USE_GL_FUNC(glVertexAttrib2fvARB) - USE_GL_FUNC(glVertexAttrib2sARB) - USE_GL_FUNC(glVertexAttrib2svARB) - USE_GL_FUNC(glVertexAttrib3dARB) - USE_GL_FUNC(glVertexAttrib3dvARB) - USE_GL_FUNC(glVertexAttrib3fARB) - USE_GL_FUNC(glVertexAttrib3fvARB) - USE_GL_FUNC(glVertexAttrib3sARB) - USE_GL_FUNC(glVertexAttrib3svARB) - USE_GL_FUNC(glVertexAttrib4NbvARB) - USE_GL_FUNC(glVertexAttrib4NivARB) - USE_GL_FUNC(glVertexAttrib4NsvARB) - USE_GL_FUNC(glVertexAttrib4NubARB) - USE_GL_FUNC(glVertexAttrib4NubvARB) - USE_GL_FUNC(glVertexAttrib4NuivARB) - USE_GL_FUNC(glVertexAttrib4NusvARB) - USE_GL_FUNC(glVertexAttrib4bvARB) - USE_GL_FUNC(glVertexAttrib4dARB) - USE_GL_FUNC(glVertexAttrib4dvARB) - USE_GL_FUNC(glVertexAttrib4fARB) - USE_GL_FUNC(glVertexAttrib4fvARB) - USE_GL_FUNC(glVertexAttrib4ivARB) - USE_GL_FUNC(glVertexAttrib4sARB) - USE_GL_FUNC(glVertexAttrib4svARB) - USE_GL_FUNC(glVertexAttrib4ubvARB) - USE_GL_FUNC(glVertexAttrib4uivARB) - USE_GL_FUNC(glVertexAttrib4usvARB) - USE_GL_FUNC(glVertexAttribPointerARB) - /* GL_ARB_viewport_array */ - USE_GL_FUNC(glDepthRangeArrayv) - USE_GL_FUNC(glDepthRangeIndexed) - USE_GL_FUNC(glGetDoublei_v) - USE_GL_FUNC(glGetFloati_v) - USE_GL_FUNC(glScissorArrayv) - USE_GL_FUNC(glScissorIndexed) - USE_GL_FUNC(glScissorIndexedv) - USE_GL_FUNC(glViewportArrayv) - USE_GL_FUNC(glViewportIndexedf) - USE_GL_FUNC(glViewportIndexedfv) - /* GL_ATI_fragment_shader */ - USE_GL_FUNC(glAlphaFragmentOp1ATI) - USE_GL_FUNC(glAlphaFragmentOp2ATI) - USE_GL_FUNC(glAlphaFragmentOp3ATI) - USE_GL_FUNC(glBeginFragmentShaderATI) - USE_GL_FUNC(glBindFragmentShaderATI) - USE_GL_FUNC(glColorFragmentOp1ATI) - USE_GL_FUNC(glColorFragmentOp2ATI) - USE_GL_FUNC(glColorFragmentOp3ATI) - USE_GL_FUNC(glDeleteFragmentShaderATI) - USE_GL_FUNC(glEndFragmentShaderATI) - USE_GL_FUNC(glGenFragmentShadersATI) - USE_GL_FUNC(glPassTexCoordATI) - USE_GL_FUNC(glSampleMapATI) - USE_GL_FUNC(glSetFragmentShaderConstantATI) - /* GL_ATI_separate_stencil */ - USE_GL_FUNC(glStencilOpSeparateATI) - USE_GL_FUNC(glStencilFuncSeparateATI) - /* GL_EXT_blend_color */ - USE_GL_FUNC(glBlendColorEXT) - /* GL_EXT_blend_equation_separate */ - USE_GL_FUNC(glBlendFuncSeparateEXT) - /* GL_EXT_blend_func_separate */ - USE_GL_FUNC(glBlendEquationSeparateEXT) - /* GL_EXT_blend_minmax */ - USE_GL_FUNC(glBlendEquationEXT) - /* GL_EXT_depth_bounds_test */ - USE_GL_FUNC(glDepthBoundsEXT) - /* GL_EXT_draw_buffers2 */ - USE_GL_FUNC(glColorMaskIndexedEXT) - USE_GL_FUNC(glDisableIndexedEXT) - USE_GL_FUNC(glEnableIndexedEXT) - USE_GL_FUNC(glGetBooleanIndexedvEXT) - USE_GL_FUNC(glGetIntegerIndexedvEXT) - USE_GL_FUNC(glIsEnabledIndexedEXT) - /* GL_EXT_fog_coord */ - USE_GL_FUNC(glFogCoordPointerEXT) - USE_GL_FUNC(glFogCoorddEXT) - USE_GL_FUNC(glFogCoorddvEXT) - USE_GL_FUNC(glFogCoordfEXT) - USE_GL_FUNC(glFogCoordfvEXT) - /* GL_EXT_framebuffer_blit */ - USE_GL_FUNC(glBlitFramebufferEXT) - /* GL_EXT_framebuffer_multisample */ - USE_GL_FUNC(glRenderbufferStorageMultisampleEXT) - /* GL_EXT_framebuffer_object */ - USE_GL_FUNC(glBindFramebufferEXT) - USE_GL_FUNC(glBindRenderbufferEXT) - USE_GL_FUNC(glCheckFramebufferStatusEXT) - USE_GL_FUNC(glDeleteFramebuffersEXT) - USE_GL_FUNC(glDeleteRenderbuffersEXT) - USE_GL_FUNC(glFramebufferRenderbufferEXT) - USE_GL_FUNC(glFramebufferTexture1DEXT) - USE_GL_FUNC(glFramebufferTexture2DEXT) - USE_GL_FUNC(glFramebufferTexture3DEXT) - USE_GL_FUNC(glGenFramebuffersEXT) - USE_GL_FUNC(glGenRenderbuffersEXT) - USE_GL_FUNC(glGenerateMipmapEXT) - USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT) - USE_GL_FUNC(glGetRenderbufferParameterivEXT) - USE_GL_FUNC(glIsFramebufferEXT) - USE_GL_FUNC(glIsRenderbufferEXT) - USE_GL_FUNC(glRenderbufferStorageEXT) - /* GL_EXT_gpu_program_parameters */ - USE_GL_FUNC(glProgramEnvParameters4fvEXT) - USE_GL_FUNC(glProgramLocalParameters4fvEXT) - /* GL_EXT_gpu_shader4 */ - USE_GL_FUNC(glBindFragDataLocationEXT) - USE_GL_FUNC(glGetFragDataLocationEXT) - USE_GL_FUNC(glGetUniformuivEXT) - USE_GL_FUNC(glGetVertexAttribIivEXT) - USE_GL_FUNC(glGetVertexAttribIuivEXT) - USE_GL_FUNC(glUniform1uiEXT) - USE_GL_FUNC(glUniform1uivEXT) - USE_GL_FUNC(glUniform2uiEXT) - USE_GL_FUNC(glUniform2uivEXT) - USE_GL_FUNC(glUniform3uiEXT) - USE_GL_FUNC(glUniform3uivEXT) - USE_GL_FUNC(glUniform4uiEXT) - USE_GL_FUNC(glUniform4uivEXT) - USE_GL_FUNC(glVertexAttribI1iEXT) - USE_GL_FUNC(glVertexAttribI1ivEXT) - USE_GL_FUNC(glVertexAttribI1uiEXT) - USE_GL_FUNC(glVertexAttribI1uivEXT) - USE_GL_FUNC(glVertexAttribI2iEXT) - USE_GL_FUNC(glVertexAttribI2ivEXT) - USE_GL_FUNC(glVertexAttribI2uiEXT) - USE_GL_FUNC(glVertexAttribI2uivEXT) - USE_GL_FUNC(glVertexAttribI3iEXT) - USE_GL_FUNC(glVertexAttribI3ivEXT) - USE_GL_FUNC(glVertexAttribI3uiEXT) - USE_GL_FUNC(glVertexAttribI3uivEXT) - USE_GL_FUNC(glVertexAttribI4bvEXT) - USE_GL_FUNC(glVertexAttribI4iEXT) - USE_GL_FUNC(glVertexAttribI4ivEXT) - USE_GL_FUNC(glVertexAttribI4svEXT) - USE_GL_FUNC(glVertexAttribI4ubvEXT) - USE_GL_FUNC(glVertexAttribI4uiEXT) - USE_GL_FUNC(glVertexAttribI4uivEXT) - USE_GL_FUNC(glVertexAttribI4usvEXT) - USE_GL_FUNC(glVertexAttribIPointerEXT) - /* GL_EXT_point_parameters */ - USE_GL_FUNC(glPointParameterfEXT) - USE_GL_FUNC(glPointParameterfvEXT) - /* GL_EXT_polygon_offset_clamp */ - USE_GL_FUNC(glPolygonOffsetClampEXT) - /* GL_EXT_provoking_vertex */ - USE_GL_FUNC(glProvokingVertexEXT) - /* GL_EXT_secondary_color */ - USE_GL_FUNC(glSecondaryColor3fEXT) - USE_GL_FUNC(glSecondaryColor3fvEXT) - USE_GL_FUNC(glSecondaryColor3ubEXT) - USE_GL_FUNC(glSecondaryColor3ubvEXT) - USE_GL_FUNC(glSecondaryColorPointerEXT) - /* GL_EXT_stencil_two_side */ - USE_GL_FUNC(glActiveStencilFaceEXT) - /* GL_EXT_texture3D */ - USE_GL_FUNC(glTexImage3D) - USE_GL_FUNC(glTexImage3DEXT) - USE_GL_FUNC(glTexSubImage3D) - USE_GL_FUNC(glTexSubImage3DEXT) - /* GL_NV_fence */ - USE_GL_FUNC(glDeleteFencesNV) - USE_GL_FUNC(glFinishFenceNV) - USE_GL_FUNC(glGenFencesNV) - USE_GL_FUNC(glGetFenceivNV) - USE_GL_FUNC(glIsFenceNV) - USE_GL_FUNC(glSetFenceNV) - USE_GL_FUNC(glTestFenceNV) - /* GL_NV_half_float */ - USE_GL_FUNC(glColor3hNV) - USE_GL_FUNC(glColor3hvNV) - USE_GL_FUNC(glColor4hNV) - USE_GL_FUNC(glColor4hvNV) - USE_GL_FUNC(glFogCoordhNV) - USE_GL_FUNC(glFogCoordhvNV) - USE_GL_FUNC(glMultiTexCoord1hNV) - USE_GL_FUNC(glMultiTexCoord1hvNV) - USE_GL_FUNC(glMultiTexCoord2hNV) - USE_GL_FUNC(glMultiTexCoord2hvNV) - USE_GL_FUNC(glMultiTexCoord3hNV) - USE_GL_FUNC(glMultiTexCoord3hvNV) - USE_GL_FUNC(glMultiTexCoord4hNV) - USE_GL_FUNC(glMultiTexCoord4hvNV) - USE_GL_FUNC(glNormal3hNV) - USE_GL_FUNC(glNormal3hvNV) - USE_GL_FUNC(glSecondaryColor3hNV) - USE_GL_FUNC(glSecondaryColor3hvNV) - USE_GL_FUNC(glTexCoord1hNV) - USE_GL_FUNC(glTexCoord1hvNV) - USE_GL_FUNC(glTexCoord2hNV) - USE_GL_FUNC(glTexCoord2hvNV) - USE_GL_FUNC(glTexCoord3hNV) - USE_GL_FUNC(glTexCoord3hvNV) - USE_GL_FUNC(glTexCoord4hNV) - USE_GL_FUNC(glTexCoord4hvNV) - USE_GL_FUNC(glVertex2hNV) - USE_GL_FUNC(glVertex2hvNV) - USE_GL_FUNC(glVertex3hNV) - USE_GL_FUNC(glVertex3hvNV) - USE_GL_FUNC(glVertex4hNV) - USE_GL_FUNC(glVertex4hvNV) - USE_GL_FUNC(glVertexAttrib1hNV) - USE_GL_FUNC(glVertexAttrib1hvNV) - USE_GL_FUNC(glVertexAttrib2hNV) - USE_GL_FUNC(glVertexAttrib2hvNV) - USE_GL_FUNC(glVertexAttrib3hNV) - USE_GL_FUNC(glVertexAttrib3hvNV) - USE_GL_FUNC(glVertexAttrib4hNV) - USE_GL_FUNC(glVertexAttrib4hvNV) - USE_GL_FUNC(glVertexAttribs1hvNV) - USE_GL_FUNC(glVertexAttribs2hvNV) - USE_GL_FUNC(glVertexAttribs3hvNV) - USE_GL_FUNC(glVertexAttribs4hvNV) - USE_GL_FUNC(glVertexWeighthNV) - USE_GL_FUNC(glVertexWeighthvNV) - /* GL_NV_point_sprite */ - USE_GL_FUNC(glPointParameteriNV) - USE_GL_FUNC(glPointParameterivNV) - /* GL_NV_register_combiners */ - USE_GL_FUNC(glCombinerInputNV) - USE_GL_FUNC(glCombinerOutputNV) - USE_GL_FUNC(glCombinerParameterfNV) - USE_GL_FUNC(glCombinerParameterfvNV) - USE_GL_FUNC(glCombinerParameteriNV) - USE_GL_FUNC(glCombinerParameterivNV) - USE_GL_FUNC(glFinalCombinerInputNV) - /* WGL extensions */ - USE_GL_FUNC(wglChoosePixelFormatARB) - USE_GL_FUNC(wglGetExtensionsStringARB) - USE_GL_FUNC(wglGetPixelFormatAttribfvARB) - USE_GL_FUNC(wglGetPixelFormatAttribivARB) - USE_GL_FUNC(wglQueryCurrentRendererIntegerWINE) - USE_GL_FUNC(wglQueryCurrentRendererStringWINE) - USE_GL_FUNC(wglQueryRendererIntegerWINE) - USE_GL_FUNC(wglQueryRendererStringWINE) - USE_GL_FUNC(wglSetPixelFormatWINE) - USE_GL_FUNC(wglSwapIntervalEXT) - - /* Newer core functions */ - USE_GL_FUNC(glActiveTexture) /* OpenGL 1.3 */ - USE_GL_FUNC(glAttachShader) /* OpenGL 2.0 */ - USE_GL_FUNC(glBeginQuery) /* OpenGL 1.5 */ - USE_GL_FUNC(glBeginTransformFeedback) /* OpenGL 3.0 */ - USE_GL_FUNC(glBindAttribLocation) /* OpenGL 2.0 */ - USE_GL_FUNC(glBindBuffer) /* OpenGL 1.5 */ - USE_GL_FUNC(glBindFragDataLocation) /* OpenGL 3.0 */ - USE_GL_FUNC(glBindVertexArray) /* OpenGL 3.0 */ - USE_GL_FUNC(glBlendColor) /* OpenGL 1.4 */ - USE_GL_FUNC(glBlendEquation) /* OpenGL 1.4 */ - USE_GL_FUNC(glBlendEquationSeparate) /* OpenGL 2.0 */ - USE_GL_FUNC(glBlendFuncSeparate) /* OpenGL 1.4 */ - USE_GL_FUNC(glBufferData) /* OpenGL 1.5 */ - USE_GL_FUNC(glBufferSubData) /* OpenGL 1.5 */ - USE_GL_FUNC(glColorMaski) /* OpenGL 3.0 */ - USE_GL_FUNC(glCompileShader) /* OpenGL 2.0 */ - USE_GL_FUNC(glCompressedTexImage2D) /* OpenGL 1.3 */ - USE_GL_FUNC(glCompressedTexImage3D) /* OpenGL 1.3 */ - USE_GL_FUNC(glCompressedTexSubImage2D) /* OpenGL 1.3 */ - USE_GL_FUNC(glCompressedTexSubImage3D) /* OpenGL 1.3 */ - USE_GL_FUNC(glCreateProgram) /* OpenGL 2.0 */ - USE_GL_FUNC(glCreateShader) /* OpenGL 2.0 */ - USE_GL_FUNC(glDebugMessageCallback) /* OpenGL 4.3 */ - USE_GL_FUNC(glDebugMessageControl) /* OpenGL 4.3 */ - USE_GL_FUNC(glDebugMessageInsert) /* OpenGL 4.3 */ - USE_GL_FUNC(glDeleteBuffers) /* OpenGL 1.5 */ - USE_GL_FUNC(glDeleteProgram) /* OpenGL 2.0 */ - USE_GL_FUNC(glDeleteQueries) /* OpenGL 1.5 */ - USE_GL_FUNC(glDeleteShader) /* OpenGL 2.0 */ - USE_GL_FUNC(glDeleteVertexArrays) /* OpenGL 3.0 */ - USE_GL_FUNC(glDetachShader) /* OpenGL 2.0 */ - USE_GL_FUNC(glDisablei) /* OpenGL 3.0 */ - USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */ - USE_GL_FUNC(glDrawArraysInstanced) /* OpenGL 3.1 */ - USE_GL_FUNC(glDrawBuffers) /* OpenGL 2.0 */ - USE_GL_FUNC(glDrawElementsInstanced) /* OpenGL 3.1 */ - USE_GL_FUNC(glEnablei) /* OpenGL 3.0 */ - USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */ - USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */ - USE_GL_FUNC(glEndTransformFeedback) /* OpenGL 3.0 */ - USE_GL_FUNC(glFramebufferTexture) /* OpenGL 3.2 */ - USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */ - USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */ - USE_GL_FUNC(glGenVertexArrays) /* OpenGL 3.0 */ - USE_GL_FUNC(glGetActiveUniform) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetAttachedShaders) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetAttribLocation) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetBooleani_v) /* OpenGL 3.0 */ - USE_GL_FUNC(glGetBufferSubData) /* OpenGL 1.5 */ - USE_GL_FUNC(glGetCompressedTexImage) /* OpenGL 1.3 */ - USE_GL_FUNC(glGetDebugMessageLog) /* OpenGL 4.3 */ - USE_GL_FUNC(glGetIntegeri_v) /* OpenGL 3.0 */ - USE_GL_FUNC(glGetProgramInfoLog) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetProgramiv) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetQueryiv) /* OpenGL 1.5 */ - USE_GL_FUNC(glGetQueryObjectuiv) /* OpenGL 1.5 */ - USE_GL_FUNC(glGetShaderInfoLog) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetShaderiv) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetShaderSource) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetStringi) /* OpenGL 3.0 */ - USE_GL_FUNC(glGetTextureLevelParameteriv) /* OpenGL 4.5 */ - USE_GL_FUNC(glGetTextureParameteriv) /* OpenGL 4.5 */ - USE_GL_FUNC(glGetUniformfv) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetUniformiv) /* OpenGL 2.0 */ - USE_GL_FUNC(glGetUniformLocation) /* OpenGL 2.0 */ - USE_GL_FUNC(glIsEnabledi) /* OpenGL 3.0 */ - USE_GL_FUNC(glLinkProgram) /* OpenGL 2.0 */ - USE_GL_FUNC(glMapBuffer) /* OpenGL 1.5 */ - USE_GL_FUNC(glPointParameteri) /* OpenGL 1.4 */ - USE_GL_FUNC(glPointParameteriv) /* OpenGL 1.4 */ - USE_GL_FUNC(glShaderSource) /* OpenGL 2.0 */ - USE_GL_FUNC(glStencilFuncSeparate) /* OpenGL 2.0 */ - USE_GL_FUNC(glStencilOpSeparate) /* OpenGL 2.0 */ - USE_GL_FUNC(glTexBuffer) /* OpenGL 3.1 */ - USE_GL_FUNC(glTexImage3D) /* OpenGL 1.2 */ - USE_GL_FUNC(glTexSubImage3D) /* OpenGL 1.2 */ - USE_GL_FUNC(glTransformFeedbackVaryings) /* OpenGL 3.0 */ - USE_GL_FUNC(glUniform1f) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform1fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform1i) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform1iv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform2f) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform2fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform2i) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform2iv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform3f) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform3fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform3i) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform3iv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform4f) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform4fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform4i) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniform4iv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniformMatrix2fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniformMatrix3fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUniformMatrix4fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glUnmapBuffer) /* OpenGL 1.5 */ - USE_GL_FUNC(glUseProgram) /* OpenGL 2.0 */ - USE_GL_FUNC(glValidateProgram) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib1f) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib1fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib2f) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib2fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib3f) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib3fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4f) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4fv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4Nsv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4Nub) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4Nubv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4Nusv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4sv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttrib4ubv) /* OpenGL 2.0 */ - USE_GL_FUNC(glVertexAttribDivisor) /* OpenGL 3.3 */ - USE_GL_FUNC(glVertexAttribIPointer) /* OpenGL 3.0 */ - USE_GL_FUNC(glVertexAttribPointer) /* OpenGL 2.0 */ -#undef USE_GL_FUNC - -#ifndef USE_WIN32_OPENGL - /* hack: use the functions directly from the TEB table to bypass the thunks */ - /* note that we still need the above wglGetProcAddress calls to initialize the table */ - gl_info->gl_ops.ext = ((struct opengl_funcs *)NtCurrentTeb()->glTable)->ext; -#endif - -#define MAP_GL_FUNCTION(core_func, ext_func) \ - do \ - { \ - if (!gl_info->gl_ops.ext.p_##core_func) \ - gl_info->gl_ops.ext.p_##core_func = gl_info->gl_ops.ext.p_##ext_func; \ - } while (0) -#define MAP_GL_FUNCTION_CAST(core_func, ext_func) \ - do \ - { \ - if (!gl_info->gl_ops.ext.p_##core_func) \ - gl_info->gl_ops.ext.p_##core_func = (void *)gl_info->gl_ops.ext.p_##ext_func; \ - } while (0) - - MAP_GL_FUNCTION(glActiveTexture, glActiveTextureARB); - MAP_GL_FUNCTION(glAttachShader, glAttachObjectARB); - MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB); - MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB); - MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB); - MAP_GL_FUNCTION(glBindFragDataLocation, glBindFragDataLocationEXT); - MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT); - MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT); - MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT); - MAP_GL_FUNCTION(glBlendFuncSeparate, glBlendFuncSeparateEXT); - MAP_GL_FUNCTION(glBufferData, glBufferDataARB); - MAP_GL_FUNCTION(glBufferSubData, glBufferSubDataARB); - MAP_GL_FUNCTION(glColorMaski, glColorMaskIndexedEXT); - MAP_GL_FUNCTION(glCompileShader, glCompileShaderARB); - MAP_GL_FUNCTION(glCompressedTexImage2D, glCompressedTexImage2DARB); - MAP_GL_FUNCTION(glCompressedTexImage3D, glCompressedTexImage3DARB); - MAP_GL_FUNCTION(glCompressedTexSubImage2D, glCompressedTexSubImage2DARB); - MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB); - MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB); - MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB); - MAP_GL_FUNCTION(glDebugMessageCallback, glDebugMessageCallbackARB); - MAP_GL_FUNCTION(glDebugMessageControl, glDebugMessageControlARB); - MAP_GL_FUNCTION(glDebugMessageInsert, glDebugMessageInsertARB); - MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB); - MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB); - MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB); - MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB); - MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB); - MAP_GL_FUNCTION(glDisablei, glDisableIndexedEXT); - MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB); - MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB); - MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB); - MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB); - MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT); - MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB); - MAP_GL_FUNCTION(glEndQuery, glEndQueryARB); - MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB); - MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB); - MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB); - MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB); - MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB); - MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB); - MAP_GL_FUNCTION(glGetBooleani_v, glGetBooleanIndexedvEXT); - MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB); - MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB); - MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB); - MAP_GL_FUNCTION(glGetIntegeri_v, glGetIntegerIndexedvEXT); - MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB); - MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB); - MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB); - MAP_GL_FUNCTION(glGetQueryObjectuiv, glGetQueryObjectuivARB); - MAP_GL_FUNCTION(glGetShaderInfoLog, glGetInfoLogARB); - MAP_GL_FUNCTION(glGetShaderiv, glGetObjectParameterivARB); - MAP_GL_FUNCTION(glGetShaderSource, glGetShaderSourceARB); - MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB); - MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB); - MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB); - MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT); - MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB); - MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB); - MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB); - MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB); - MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT); - MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT); - MAP_GL_FUNCTION(glUniform1f, glUniform1fARB); - MAP_GL_FUNCTION(glUniform1fv, glUniform1fvARB); - MAP_GL_FUNCTION(glUniform1i, glUniform1iARB); - MAP_GL_FUNCTION(glUniform1iv, glUniform1ivARB); - MAP_GL_FUNCTION(glUniform2f, glUniform2fARB); - MAP_GL_FUNCTION(glUniform2fv, glUniform2fvARB); - MAP_GL_FUNCTION(glUniform2i, glUniform2iARB); - MAP_GL_FUNCTION(glUniform2iv, glUniform2ivARB); - MAP_GL_FUNCTION(glUniform3f, glUniform3fARB); - MAP_GL_FUNCTION(glUniform3fv, glUniform3fvARB); - MAP_GL_FUNCTION(glUniform3i, glUniform3iARB); - MAP_GL_FUNCTION(glUniform3iv, glUniform3ivARB); - MAP_GL_FUNCTION(glUniform4f, glUniform4fARB); - MAP_GL_FUNCTION(glUniform4fv, glUniform4fvARB); - MAP_GL_FUNCTION(glUniform4i, glUniform4iARB); - MAP_GL_FUNCTION(glUniform4iv, glUniform4ivARB); - MAP_GL_FUNCTION(glUniformMatrix2fv, glUniformMatrix2fvARB); - MAP_GL_FUNCTION(glUniformMatrix3fv, glUniformMatrix3fvARB); - MAP_GL_FUNCTION(glUniformMatrix4fv, glUniformMatrix4fvARB); - MAP_GL_FUNCTION(glUnmapBuffer, glUnmapBufferARB); - MAP_GL_FUNCTION(glUseProgram, glUseProgramObjectARB); - MAP_GL_FUNCTION(glValidateProgram, glValidateProgramARB); - MAP_GL_FUNCTION(glVertexAttrib1f, glVertexAttrib1fARB); - MAP_GL_FUNCTION(glVertexAttrib1fv, glVertexAttrib1fvARB); - MAP_GL_FUNCTION(glVertexAttrib2f, glVertexAttrib2fARB); - MAP_GL_FUNCTION(glVertexAttrib2fv, glVertexAttrib2fvARB); - MAP_GL_FUNCTION(glVertexAttrib3f, glVertexAttrib3fARB); - MAP_GL_FUNCTION(glVertexAttrib3fv, glVertexAttrib3fvARB); - MAP_GL_FUNCTION(glVertexAttrib4f, glVertexAttrib4fARB); - MAP_GL_FUNCTION(glVertexAttrib4fv, glVertexAttrib4fvARB); - MAP_GL_FUNCTION(glVertexAttrib4Nsv, glVertexAttrib4NsvARB); - MAP_GL_FUNCTION(glVertexAttrib4Nub, glVertexAttrib4NubARB); - MAP_GL_FUNCTION(glVertexAttrib4Nubv, glVertexAttrib4NubvARB); - MAP_GL_FUNCTION(glVertexAttrib4Nusv, glVertexAttrib4NusvARB); - MAP_GL_FUNCTION(glVertexAttrib4sv, glVertexAttrib4svARB); - MAP_GL_FUNCTION(glVertexAttrib4ubv, glVertexAttrib4ubvARB); - MAP_GL_FUNCTION(glVertexAttribDivisor, glVertexAttribDivisorARB); - MAP_GL_FUNCTION(glVertexAttribIPointer, glVertexAttribIPointerEXT); - MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB); -#undef MAP_GL_FUNCTION -#undef MAP_GL_FUNCTION_CAST -} - -static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) -{ - unsigned int i, sampler_count; - GLfloat gl_floatv[2]; - GLint gl_max; - - gl_info->limits.blends = 1; - gl_info->limits.buffers = 1; - gl_info->limits.textures = 0; - gl_info->limits.texture_coords = 0; - for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) - { - gl_info->limits.uniform_blocks[i] = 0; - gl_info->limits.samplers[i] = 0; - } - gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = 1; - gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]; - gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers; - gl_info->limits.vertex_attribs = 16; - gl_info->limits.texture_buffer_offset_alignment = 1; - gl_info->limits.glsl_vs_float_constants = 0; - gl_info->limits.glsl_ps_float_constants = 0; - gl_info->limits.arb_vs_float_constants = 0; - gl_info->limits.arb_vs_native_constants = 0; - gl_info->limits.arb_vs_instructions = 0; - gl_info->limits.arb_vs_temps = 0; - gl_info->limits.arb_ps_float_constants = 0; - gl_info->limits.arb_ps_local_constants = 0; - gl_info->limits.arb_ps_instructions = 0; - gl_info->limits.arb_ps_temps = 0; - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max); - gl_info->limits.user_clip_distances = min(MAX_CLIP_DISTANCES, gl_max); - TRACE("Clip plane support - max planes %d.\n", gl_max); - - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max); - gl_info->limits.lights = gl_max; - TRACE("Light support - max lights %d.\n", gl_max); - } - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max); - gl_info->limits.texture_size = gl_max; - TRACE("Maximum texture size support - max texture size %d.\n", gl_max); - - gl_info->gl_ops.gl.p_glGetFloatv(gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] - ? GL_ALIASED_POINT_SIZE_RANGE : GL_POINT_SIZE_RANGE, gl_floatv); - gl_info->limits.pointsize_min = gl_floatv[0]; - gl_info->limits.pointsize_max = gl_floatv[1]; - TRACE("Maximum point size support - max point size %f.\n", gl_floatv[1]); - - if (gl_info->supported[ARB_MAP_BUFFER_ALIGNMENT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &gl_max); - TRACE("Minimum buffer map alignment: %d.\n", gl_max); - } - else - { - WARN_(d3d_perf)("Driver doesn't guarantee a minimum buffer map alignment.\n"); - } - if (gl_info->supported[NV_REGISTER_COMBINERS]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max); - gl_info->limits.general_combiners = gl_max; - TRACE("Max general combiners: %d.\n", gl_max); - } - if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max); - gl_info->limits.buffers = min(MAX_RENDER_TARGET_VIEWS, gl_max); - TRACE("Max draw buffers: %u.\n", gl_max); - } - if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &gl_max); - gl_info->limits.dual_buffers = gl_max; - TRACE("Max dual source draw buffers: %u.\n", gl_max); - } - if (gl_info->supported[ARB_MULTITEXTURE]) - { - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max); - gl_info->limits.textures = min(MAX_TEXTURES, gl_max); - TRACE("Max textures: %d.\n", gl_info->limits.textures); - - if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max); - gl_info->limits.texture_coords = min(MAX_TEXTURES, gl_max); - } - else - { - gl_info->limits.texture_coords = gl_info->limits.textures; - } - TRACE("Max texture coords: %d.\n", gl_info->limits.texture_coords); - } - - if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gl_max); - gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_max; - } - else - { - gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_info->limits.textures; - } - TRACE("Max fragment samplers: %d.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]); - - if (gl_info->supported[ARB_VERTEX_SHADER]) - { - unsigned int vertex_sampler_count; - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &gl_max); - vertex_sampler_count = gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = gl_max; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &gl_max); - gl_info->limits.combined_samplers = gl_max; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &gl_max); - gl_info->limits.vertex_attribs = gl_max; - - /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup - * is known at shader link time. In a vertex shader + pixel shader combination this isn't - * an issue because then the sampler setup only depends on the two shaders. If a pixel - * shader is used with fixed function vertex processing we're fine too because fixed function - * vertex processing doesn't use any samplers. If fixed function fragment processing is - * used we have to make sure that all vertex sampler setups are valid together with all - * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES - * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards). - * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and - * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have - * a fixed function pipeline anymore. - * - * So this is just a check to check that our assumption holds true. If not, write a warning - * and reduce the number of vertex samplers or probably disable vertex texture fetch. */ - if (vertex_sampler_count && gl_info->limits.combined_samplers < 12 - && MAX_TEXTURES + vertex_sampler_count > gl_info->limits.combined_samplers) - { - FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n", - vertex_sampler_count, gl_info->limits.combined_samplers); - FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n"); - if (gl_info->limits.combined_samplers > MAX_TEXTURES) - vertex_sampler_count = gl_info->limits.combined_samplers - MAX_TEXTURES; - else - vertex_sampler_count = 0; - gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = vertex_sampler_count; - } - } - else - { - gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]; - } - TRACE("Max vertex samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]); - TRACE("Max combined samplers: %u.\n", gl_info->limits.combined_samplers); - TRACE("Max vertex attributes: %u.\n", gl_info->limits.vertex_attribs); - } - else - { - gl_info->limits.textures = 1; - gl_info->limits.texture_coords = 1; - } - - if (gl_info->supported[ARB_VERTEX_BLEND]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max); - gl_info->limits.blends = gl_max; - TRACE("Max blends: %u.\n", gl_info->limits.blends); - } - if (gl_info->supported[EXT_TEXTURE3D]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max); - gl_info->limits.texture3d_size = gl_max; - TRACE("Max texture3D size: %d.\n", gl_info->limits.texture3d_size); - } - if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &gl_max); - gl_info->limits.anisotropy = gl_max; - TRACE("Max anisotropy: %d.\n", gl_info->limits.anisotropy); - } - if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) - { - GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); - gl_info->limits.arb_ps_float_constants = gl_max; - TRACE("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants); - GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max)); - gl_info->limits.arb_ps_native_constants = gl_max; - TRACE("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n", - gl_info->limits.arb_ps_native_constants); - GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max)); - gl_info->limits.arb_ps_temps = gl_max; - TRACE("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps); - GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max)); - gl_info->limits.arb_ps_instructions = gl_max; - TRACE("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions); - GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max)); - gl_info->limits.arb_ps_local_constants = gl_max; - TRACE("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions); - } - if (gl_info->supported[ARB_VERTEX_PROGRAM]) - { - GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); - gl_info->limits.arb_vs_float_constants = gl_max; - TRACE("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants); - GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max)); - gl_info->limits.arb_vs_native_constants = gl_max; - TRACE("Max ARB_VERTEX_PROGRAM native float constants: %d.\n", - gl_info->limits.arb_vs_native_constants); - GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max)); - gl_info->limits.arb_vs_temps = gl_max; - TRACE("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps); - GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max)); - gl_info->limits.arb_vs_instructions = gl_max; - TRACE("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions); - } - if (gl_info->supported[ARB_VERTEX_SHADER]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max); - gl_info->limits.glsl_vs_float_constants = gl_max / 4; - TRACE("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants); - - if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX] = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max vertex uniform blocks: %u (%d).\n", - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX], gl_max); - } - } - if (gl_info->supported[ARB_TESSELLATION_SHADER]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL] = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max hull uniform blocks: %u (%d).\n", - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL], gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, &gl_max); - gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL] = gl_max; - TRACE("Max hull samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL]); - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN] = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max domain uniform blocks: %u (%d).\n", - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN], gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, &gl_max); - gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN] = gl_max; - TRACE("Max domain samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN]); - } - if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY] = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max geometry uniform blocks: %u (%d).\n", - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY], gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &gl_max); - gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY] = gl_max; - TRACE("Max geometry samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY]); - } - if (gl_info->supported[ARB_FRAGMENT_SHADER]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max); - gl_info->limits.glsl_ps_float_constants = gl_max / 4; - TRACE("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max); - gl_info->limits.glsl_varyings = gl_max; - TRACE("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4); - - if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL] = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max fragment uniform blocks: %u (%d).\n", - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL], gl_max); - } - } - if (gl_info->supported[ARB_COMPUTE_SHADER]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE] = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max compute uniform blocks: %u (%d).\n", - gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE], gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &gl_max); - gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE] = gl_max; - TRACE("Max compute samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]); - } - if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &gl_max); - TRACE("Max combined uniform blocks: %d.\n", gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_max); - TRACE("Max uniform buffer bindings: %d.\n", gl_max); - } - if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_max); - gl_info->limits.texture_buffer_offset_alignment = gl_max; - TRACE("Minimum required texture buffer offset alignment %d.\n", gl_max); - } - if (gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS]) - { - GLint max_fragment_buffers, max_combined_buffers, max_bindings; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_fragment_buffers); - TRACE("Max fragment atomic counter buffers: %d.\n", max_fragment_buffers); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, &max_combined_buffers); - TRACE("Max combined atomic counter buffers: %d.\n", max_combined_buffers); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings); - TRACE("Max atomic counter buffer bindings: %d.\n", max_bindings); - if (max_fragment_buffers < MAX_UNORDERED_ACCESS_VIEWS - || max_combined_buffers < MAX_UNORDERED_ACCESS_VIEWS - || max_bindings < MAX_UNORDERED_ACCESS_VIEWS) - { - WARN("Disabling ARB_shader_atomic_counters.\n"); - gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS] = FALSE; - } - } - if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_STREAMS, &gl_max); - TRACE("Max vertex streams: %d.\n", gl_max); - } - - if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) - gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess); - else - gl_info->limits.shininess = 128.0f; - - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_SAMPLES, &gl_max); - gl_info->limits.samples = gl_max; - } - - if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &gl_max); - gl_info->limits.framebuffer_width = gl_max; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &gl_max); - gl_info->limits.framebuffer_height = gl_max; - } - else - { - gl_info->limits.framebuffer_width = gl_info->limits.texture_size; - gl_info->limits.framebuffer_height = gl_info->limits.texture_size; - } - - gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = - min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS); - sampler_count = 0; - for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) - sampler_count += gl_info->limits.samplers[i]; - if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->limits.combined_samplers < sampler_count) - { - /* The minimum value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS in OpenGL - * 3.2 is 48 (16 per stage). When tessellation shaders are supported - * the minimum value is increased to 80. */ - WARN("Graphics pipeline sampler count %u is greater than combined sampler count %u.\n", - sampler_count, gl_info->limits.combined_samplers); - for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) - gl_info->limits.samplers[i] = min(gl_info->limits.samplers[i], 16); - } - - /* A majority of OpenGL implementations allow us to statically partition - * the set of texture bindings into six separate sets. */ - gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers; - sampler_count = 0; - for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) - sampler_count += gl_info->limits.samplers[i]; - if (gl_info->limits.combined_samplers >= sampler_count) - gl_info->limits.graphics_samplers -= gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]; -} - -/* Context activation is done by the caller. */ -static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, - struct wined3d_caps_gl_ctx *caps_gl_ctx, DWORD wined3d_creation_flags) -{ - static const struct - { - enum wined3d_gl_extension extension; - DWORD min_gl_version; - } - core_extensions[] = - { - {EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2)}, - {ARB_MULTISAMPLE, MAKEDWORD_VERSION(1, 3)}, - {ARB_MULTITEXTURE, MAKEDWORD_VERSION(1, 3)}, - {ARB_TEXTURE_BORDER_CLAMP, MAKEDWORD_VERSION(1, 3)}, - {ARB_TEXTURE_COMPRESSION, MAKEDWORD_VERSION(1, 3)}, - {ARB_TEXTURE_CUBE_MAP, MAKEDWORD_VERSION(1, 3)}, - {ARB_DEPTH_TEXTURE, MAKEDWORD_VERSION(1, 4)}, - {ARB_POINT_PARAMETERS, MAKEDWORD_VERSION(1, 4)}, - {ARB_SHADOW, MAKEDWORD_VERSION(1, 4)}, - {ARB_TEXTURE_MIRRORED_REPEAT, MAKEDWORD_VERSION(1, 4)}, - {EXT_BLEND_COLOR, MAKEDWORD_VERSION(1, 4)}, - {EXT_BLEND_FUNC_SEPARATE, MAKEDWORD_VERSION(1, 4)}, - {EXT_BLEND_MINMAX, MAKEDWORD_VERSION(1, 4)}, - {EXT_BLEND_SUBTRACT, MAKEDWORD_VERSION(1, 4)}, - {EXT_STENCIL_WRAP, MAKEDWORD_VERSION(1, 4)}, - {NV_POINT_SPRITE, MAKEDWORD_VERSION(1, 4)}, - {ARB_OCCLUSION_QUERY, MAKEDWORD_VERSION(1, 5)}, - {ARB_VERTEX_BUFFER_OBJECT, MAKEDWORD_VERSION(1, 5)}, - {ARB_DRAW_BUFFERS, MAKEDWORD_VERSION(2, 0)}, - {ARB_FRAGMENT_SHADER, MAKEDWORD_VERSION(2, 0)}, - {ARB_SHADING_LANGUAGE_100, MAKEDWORD_VERSION(2, 0)}, - {ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0)}, - {ARB_VERTEX_SHADER, MAKEDWORD_VERSION(2, 0)}, - {EXT_BLEND_EQUATION_SEPARATE, MAKEDWORD_VERSION(2, 0)}, - {ARB_PIXEL_BUFFER_OBJECT, MAKEDWORD_VERSION(2, 1)}, - {EXT_TEXTURE_SRGB, MAKEDWORD_VERSION(2, 1)}, - {ARB_COLOR_BUFFER_FLOAT, MAKEDWORD_VERSION(3, 0)}, - {ARB_DEPTH_BUFFER_FLOAT, MAKEDWORD_VERSION(3, 0)}, - {ARB_FRAMEBUFFER_OBJECT, MAKEDWORD_VERSION(3, 0)}, - {ARB_FRAMEBUFFER_SRGB, MAKEDWORD_VERSION(3, 0)}, - {ARB_HALF_FLOAT_PIXEL, MAKEDWORD_VERSION(3, 0)}, - {ARB_HALF_FLOAT_VERTEX, MAKEDWORD_VERSION(3, 0)}, - {ARB_MAP_BUFFER_RANGE, MAKEDWORD_VERSION(3, 0)}, - {ARB_TEXTURE_COMPRESSION_RGTC, MAKEDWORD_VERSION(3, 0)}, - {ARB_TEXTURE_FLOAT, MAKEDWORD_VERSION(3, 0)}, - {ARB_TEXTURE_RG, MAKEDWORD_VERSION(3, 0)}, - {EXT_DRAW_BUFFERS2, MAKEDWORD_VERSION(3, 0)}, - {EXT_PACKED_FLOAT, MAKEDWORD_VERSION(3, 0)}, - {EXT_TEXTURE_ARRAY, MAKEDWORD_VERSION(3, 0)}, - {EXT_TEXTURE_INTEGER, MAKEDWORD_VERSION(3, 0)}, - {EXT_TEXTURE_SHARED_EXPONENT, MAKEDWORD_VERSION(3, 0)}, - /* We don't want to enable EXT_GPU_SHADER4: even though similar - * functionality is available in core GL 3.0 / GLSL 1.30, it's different - * enough that reusing the same flag for the new features hurts more - * than it helps. */ - /* EXT_framebuffer_object, EXT_framebuffer_blit, - * EXT_framebuffer_multisample and EXT_packed_depth_stencil - * are integrated into ARB_framebuffer_object. */ - - {ARB_COPY_BUFFER, MAKEDWORD_VERSION(3, 1)}, - {ARB_DRAW_INSTANCED, MAKEDWORD_VERSION(3, 1)}, - {ARB_TEXTURE_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)}, - {ARB_UNIFORM_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)}, - {EXT_TEXTURE_SNORM, MAKEDWORD_VERSION(3, 1)}, - /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */ - - {ARB_DRAW_ELEMENTS_BASE_VERTEX, MAKEDWORD_VERSION(3, 2)}, - /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2 - * core geometry shaders so it's not really correct to expose the - * extension for core-only support. */ - {ARB_FRAGMENT_COORD_CONVENTIONS, MAKEDWORD_VERSION(3, 2)}, - {ARB_PROVOKING_VERTEX, MAKEDWORD_VERSION(3, 2)}, - {ARB_SEAMLESS_CUBE_MAP, MAKEDWORD_VERSION(3, 2)}, - {ARB_SYNC, MAKEDWORD_VERSION(3, 2)}, - {ARB_TEXTURE_MULTISAMPLE, MAKEDWORD_VERSION(3, 2)}, - {ARB_VERTEX_ARRAY_BGRA, MAKEDWORD_VERSION(3, 2)}, - - {ARB_BLEND_FUNC_EXTENDED, MAKEDWORD_VERSION(3, 3)}, - {ARB_EXPLICIT_ATTRIB_LOCATION, MAKEDWORD_VERSION(3, 3)}, - {ARB_INSTANCED_ARRAYS, MAKEDWORD_VERSION(3, 3)}, - {ARB_SAMPLER_OBJECTS, MAKEDWORD_VERSION(3, 3)}, - {ARB_SHADER_BIT_ENCODING, MAKEDWORD_VERSION(3, 3)}, - {ARB_TEXTURE_RGB10_A2UI, MAKEDWORD_VERSION(3, 3)}, - {ARB_TEXTURE_SWIZZLE, MAKEDWORD_VERSION(3, 3)}, - {ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)}, - {ARB_VERTEX_TYPE_2_10_10_10_REV, MAKEDWORD_VERSION(3, 3)}, - - {ARB_DRAW_INDIRECT, MAKEDWORD_VERSION(4, 0)}, - {ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)}, - {ARB_TESSELLATION_SHADER, MAKEDWORD_VERSION(4, 0)}, - {ARB_TEXTURE_CUBE_MAP_ARRAY, MAKEDWORD_VERSION(4, 0)}, - {ARB_TEXTURE_GATHER, MAKEDWORD_VERSION(4, 0)}, - {ARB_TRANSFORM_FEEDBACK2, MAKEDWORD_VERSION(4, 0)}, - {ARB_TRANSFORM_FEEDBACK3, MAKEDWORD_VERSION(4, 0)}, - - {ARB_ES2_COMPATIBILITY, MAKEDWORD_VERSION(4, 1)}, - {ARB_VIEWPORT_ARRAY, MAKEDWORD_VERSION(4, 1)}, - - {ARB_BASE_INSTANCE, MAKEDWORD_VERSION(4, 2)}, - {ARB_CONSERVATIVE_DEPTH, MAKEDWORD_VERSION(4, 2)}, - {ARB_INTERNALFORMAT_QUERY, MAKEDWORD_VERSION(4, 2)}, - {ARB_MAP_BUFFER_ALIGNMENT, MAKEDWORD_VERSION(4, 2)}, - {ARB_SHADER_ATOMIC_COUNTERS, MAKEDWORD_VERSION(4, 2)}, - {ARB_SHADER_IMAGE_LOAD_STORE, MAKEDWORD_VERSION(4, 2)}, - {ARB_SHADING_LANGUAGE_420PACK, MAKEDWORD_VERSION(4, 2)}, - {ARB_SHADING_LANGUAGE_PACKING, MAKEDWORD_VERSION(4, 2)}, - {ARB_TEXTURE_COMPRESSION_BPTC, MAKEDWORD_VERSION(4, 2)}, - {ARB_TEXTURE_STORAGE, MAKEDWORD_VERSION(4, 2)}, - - {ARB_CLEAR_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)}, - {ARB_COMPUTE_SHADER, MAKEDWORD_VERSION(4, 3)}, - {ARB_COPY_IMAGE, MAKEDWORD_VERSION(4, 3)}, - {ARB_DEBUG_OUTPUT, MAKEDWORD_VERSION(4, 3)}, - {ARB_ES3_COMPATIBILITY, MAKEDWORD_VERSION(4, 3)}, - {ARB_FRAGMENT_LAYER_VIEWPORT, MAKEDWORD_VERSION(4, 3)}, - {ARB_FRAMEBUFFER_NO_ATTACHMENTS, MAKEDWORD_VERSION(4, 3)}, - {ARB_INTERNALFORMAT_QUERY2, MAKEDWORD_VERSION(4, 3)}, - {ARB_SHADER_IMAGE_SIZE, MAKEDWORD_VERSION(4, 3)}, - {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)}, - {ARB_STENCIL_TEXTURING, MAKEDWORD_VERSION(4, 3)}, - {ARB_TEXTURE_BUFFER_RANGE, MAKEDWORD_VERSION(4, 3)}, - {ARB_TEXTURE_QUERY_LEVELS, MAKEDWORD_VERSION(4, 3)}, - {ARB_TEXTURE_STORAGE_MULTISAMPLE, MAKEDWORD_VERSION(4, 2)}, - {ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)}, - - {ARB_CLEAR_TEXTURE, MAKEDWORD_VERSION(4, 4)}, - - {ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)}, - {ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)}, - {ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)}, - - {ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)}, - {ARB_TEXTURE_FILTER_ANISOTROPIC, MAKEDWORD_VERSION(4, 6)}, - }; - struct wined3d_driver_info *driver_info = &adapter->driver_info; - const char *gl_vendor_str, *gl_renderer_str, *gl_version_str; - struct wined3d_gl_info *gl_info = &adapter->gl_info; - const struct gpu_description *gpu_description; - struct wined3d_vertex_caps vertex_caps; - struct fragment_caps fragment_caps; - struct shader_caps shader_caps; - const char *WGL_Extensions = NULL; - enum wined3d_gl_vendor gl_vendor; - DWORD gl_version, gl_ext_emul_mask; - UINT64 vram_bytes = 0; - HDC hdc; - unsigned int i, j; - GLint context_profile = 0; - - TRACE("adapter %p.\n", adapter); - - gl_renderer_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER); - TRACE("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str)); - if (!gl_renderer_str) - { - ERR("Received a NULL GL_RENDERER.\n"); - return FALSE; - } - - gl_vendor_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR); - TRACE("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str)); - if (!gl_vendor_str) - { - ERR("Received a NULL GL_VENDOR.\n"); - return FALSE; - } - - /* Parse the GL_VERSION field into major and minor information */ - gl_version_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VERSION); - TRACE("GL_VERSION: %s.\n", debugstr_a(gl_version_str)); - if (!gl_version_str) - { - ERR("Received a NULL GL_VERSION.\n"); - return FALSE; - } - gl_version = wined3d_parse_gl_version(gl_version_str); - - load_gl_funcs(gl_info); - - memset(gl_info->supported, 0, sizeof(gl_info->supported)); - gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE; - - if (gl_version >= MAKEDWORD_VERSION(3, 2)) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile); - checkGLcall("Querying context profile"); - } - if (context_profile & GL_CONTEXT_CORE_PROFILE_BIT) - TRACE("Got a core profile context.\n"); - else - gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] = TRUE; - - TRACE("GL extensions reported:\n"); - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS); - - if (!gl_extensions) - { - ERR("Received a NULL GL_EXTENSIONS.\n"); - return FALSE; - } - parse_extension_string(gl_info, gl_extensions, gl_extension_map, ARRAY_SIZE(gl_extension_map)); - } - else - { - enumerate_gl_extensions(gl_info, gl_extension_map, ARRAY_SIZE(gl_extension_map)); - } - - hdc = wglGetCurrentDC(); - /* Not all GL drivers might offer WGL extensions e.g. VirtualBox. */ - if (GL_EXTCALL(wglGetExtensionsStringARB)) - WGL_Extensions = (const char *)GL_EXTCALL(wglGetExtensionsStringARB(hdc)); - if (!WGL_Extensions) - WARN("WGL extensions not supported.\n"); - else - parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map, ARRAY_SIZE(wgl_extension_map)); - - for (i = 0; i < ARRAY_SIZE(core_extensions); ++i) - { - if (!gl_info->supported[core_extensions[i].extension] - && gl_version >= core_extensions[i].min_gl_version) - { - for (j = 0; j < ARRAY_SIZE(gl_extension_map); ++j) - if (gl_extension_map[j].extension == core_extensions[i].extension) - break; - - if (j < ARRAY_SIZE(gl_extension_map)) - { - TRACE("GL CORE: %s support.\n", gl_extension_map[j].extension_string); - gl_info->supported[core_extensions[i].extension] = TRUE; - } - else - { - FIXME("GL extension %u not in the GL extensions map.\n", core_extensions[i].extension); - } - } - } - - if (gl_info->supported[EXT_BLEND_MINMAX] || gl_info->supported[EXT_BLEND_SUBTRACT]) - gl_info->supported[WINED3D_GL_BLEND_EQUATION] = TRUE; - - if (gl_version >= MAKEDWORD_VERSION(2, 0)) - gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE; - if (gl_version >= MAKEDWORD_VERSION(3, 2)) - gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE; - - /* All the points are actually point sprites in core contexts, the APIs from - * ARB_point_sprite are not supported anymore. */ - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - gl_info->supported[ARB_POINT_SPRITE] = FALSE; - - if (gl_info->supported[APPLE_FENCE]) - { - /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically. - * The apple extension interacts with some other apple exts. Disable the NV - * extension if the apple one is support to prevent confusion in other parts - * of the code. */ - gl_info->supported[NV_FENCE] = FALSE; - } - if (gl_info->supported[APPLE_FLOAT_PIXELS]) - { - /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel - * - * The enums are the same: - * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881a - * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881b - * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814 - * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815 - * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140b - */ - if (!gl_info->supported[ARB_TEXTURE_FLOAT]) - { - TRACE(" IMPLIED: GL_ARB_texture_float support (by GL_APPLE_float_pixels).\n"); - gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE; - } - if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) - { - TRACE(" IMPLIED: GL_ARB_half_float_pixel support (by GL_APPLE_float_pixels).\n"); - gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE; - } - } - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same - * functionality. Prefer the ARB extension */ - gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE; - } - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - TRACE(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n"); - gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE; - } - if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA]) - { - TRACE(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n"); - gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE; - } - if (!gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC]) - { - TRACE(" IMPLIED: EXT_texture_compression_rgtc support (by ARB_texture_compression_rgtc).\n"); - gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC] = TRUE; - } - if (!gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC]) - { - TRACE(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n"); - gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = TRUE; - } - if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && !gl_info->supported[ARB_TEXTURE_RG]) - { - TRACE("ARB_texture_rg not supported, disabling ARB_texture_compression_rgtc.\n"); - gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = FALSE; - } - if (gl_info->supported[NV_TEXTURE_SHADER2]) - { - if (gl_info->supported[NV_REGISTER_COMBINERS]) - { - /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2 - * are supported. The nv extensions provide the same functionality as the - * ATI one, and a bit more(signed pixelformats). */ - gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE; - } - } - if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) - { - /* If we have full NP2 texture support, disable - * GL_ARB_texture_rectangle because we will never use it. - * This saves a few redundant glDisable calls. */ - gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE; - } - if (gl_info->supported[ATI_FRAGMENT_SHADER]) - { - /* Disable NV_register_combiners and fragment shader if this is supported. - * generally the NV extensions are preferred over the ATI ones, and this - * extension is disabled if register_combiners and texture_shader2 are both - * supported. So we reach this place only if we have incomplete NV dxlevel 8 - * fragment processing support. */ - gl_info->supported[NV_REGISTER_COMBINERS] = FALSE; - gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE; - gl_info->supported[NV_TEXTURE_SHADER] = FALSE; - gl_info->supported[NV_TEXTURE_SHADER2] = FALSE; - } - if (gl_info->supported[NV_HALF_FLOAT]) - { - /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */ - gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE; - } - if (gl_info->supported[ARB_FRAMEBUFFER_SRGB] && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - { - /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode - * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode - * we never render to sRGB surfaces). */ - TRACE("EXT_texture_sRGB_decode is not supported, disabling ARB_framebuffer_sRGB.\n"); - gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE; - } - if (gl_info->supported[ARB_OCCLUSION_QUERY]) - { - GLint counter_bits; + break; - GL_EXTCALL(glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &counter_bits)); - TRACE("Occlusion query counter has %d bits.\n", counter_bits); - if (!counter_bits) - gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE; - } - if (gl_info->supported[ARB_TIMER_QUERY]) - { - GLint counter_bits; + case 10: + driver_os_version = 10; + driver_model = DRIVER_MODEL_NT6X; + break; - GL_EXTCALL(glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &counter_bits)); - TRACE("Timestamp query counter has %d bits.\n", counter_bits); - if (!counter_bits) - gl_info->supported[ARB_TIMER_QUERY] = FALSE; + default: + FIXME("Unhandled OS version %u.%u, reporting Windows 7.\n", + os_version.dwMajorVersion, os_version.dwMinorVersion); + driver_os_version = 8; + driver_model = DRIVER_MODEL_NT6X; + break; + } } - if (gl_version >= MAKEDWORD_VERSION(3, 0)) - { - GLint counter_bits; - - gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = TRUE; - GL_EXTCALL(glGetQueryiv(GL_PRIMITIVES_GENERATED, GL_QUERY_COUNTER_BITS, &counter_bits)); - TRACE("Primitives query counter has %d bits.\n", counter_bits); - if (!counter_bits) - gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE; - - GL_EXTCALL(glGetQueryiv(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_QUERY_COUNTER_BITS, &counter_bits)); - TRACE("Transform feedback primitives query counter has %d bits.\n", counter_bits); - if (!counter_bits) - gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE; - } - if (gl_info->supported[ARB_VIEWPORT_ARRAY]) - { - GLint subpixel_bits; + driver_info->vendor = gpu_desc->vendor; + driver_info->device = gpu_desc->device; + wined3d_copy_name(driver_info->description, gpu_desc->description, ARRAY_SIZE(driver_info->description)); + driver_info->vram_bytes = vram_bytes ? vram_bytes : (UINT64)gpu_desc->vidmem * 1024 * 1024; + driver = gpu_desc->driver; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &subpixel_bits); - TRACE("Viewport supports %d subpixel bits.\n", subpixel_bits); - if (subpixel_bits < 8 && gl_info->supported[ARB_CLIP_CONTROL]) - { - TRACE("Disabling ARB_clip_control because viewport subpixel bits < 8.\n"); - gl_info->supported[ARB_CLIP_CONTROL] = FALSE; - } - } - if (gl_info->supported[ARB_CLIP_CONTROL] && !gl_info->supported[ARB_VIEWPORT_ARRAY]) - { - /* When using ARB_clip_control we need the float viewport parameters - * introduced by ARB_viewport_array to take care of the shifted pixel - * coordinates. */ - TRACE("Disabling ARB_clip_control because ARB_viewport_array is not supported.\n"); - gl_info->supported[ARB_CLIP_CONTROL] = FALSE; - } - if (gl_info->supported[ARB_STENCIL_TEXTURING] && !gl_info->supported[ARB_TEXTURE_SWIZZLE]) - { - /* The stencil value needs to be placed in the green channel. */ - TRACE("Disabling ARB_stencil_texturing because ARB_texture_swizzle is not supported.\n"); - gl_info->supported[ARB_STENCIL_TEXTURING] = FALSE; - } - if (!gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] && gl_info->supported[EXT_TEXTURE_MIRROR_CLAMP]) + if (wined3d_settings.emulated_textureram) { - TRACE(" IMPLIED: ATI_texture_mirror_once support (by EXT_texture_mirror_clamp).\n"); - gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE; + driver_info->vram_bytes = wined3d_settings.emulated_textureram; + TRACE("Overriding amount of video memory with 0x%s bytes.\n", + wine_dbgstr_longlong(driver_info->vram_bytes)); } - if (!gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] && gl_info->supported[ATI_TEXTURE_MIRROR_ONCE]) + + /** + * Diablo 2 crashes when the amount of video memory is greater than 0x7fffffff. + * In order to avoid this application bug we limit the amount of video memory + * to LONG_MAX for older Windows versions. + */ + if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX) { - TRACE(" IMPLIED: ARB_texture_mirror_clamp_to_edge support (by ATI_texture_mirror_once).\n"); - gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] = TRUE; + TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX); + driver_info->vram_bytes = LONG_MAX; } - if (gl_info->supported[ARB_TEXTURE_STORAGE] && gl_info->supported[APPLE_YCBCR_422]) + + if (!(driver_info->sysmem_bytes = sysmem_bytes)) { - /* AFAIK APPLE_ycbcr_422 is only available in legacy contexts so we shouldn't ever hit this. */ - ERR("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n"); - gl_info->supported[APPLE_YCBCR_422] = FALSE; + driver_info->sysmem_bytes = 64 * 1024 * 1024; + memory_status.dwLength = sizeof(memory_status); + if (GlobalMemoryStatusEx(&memory_status)) + driver_info->sysmem_bytes = max(memory_status.ullTotalPhys / 2, driver_info->sysmem_bytes); + else + ERR("Failed to get global memory status.\n"); } - if (gl_info->supported[ARB_DRAW_INDIRECT] && !gl_info->supported[ARB_BASE_INSTANCE]) + + /* Try to obtain driver version information for the current Windows version. This fails in + * some cases: + * - the gpu is not available on the currently selected OS version: + * - Geforce GTX480 on Win98. When running applications in compatibility mode on Windows, + * version information for the current Windows version is returned instead of faked info. + * We do the same and assume the default Windows version to emulate is WinXP. + * + * - Videocard is a Riva TNT but winver is set to win7 (there are no drivers for this beast) + * For now return the XP driver info. Perhaps later on we should return VESA. + * + * - the gpu is not in our database (can happen when the user overrides the vendor_id / device_id) + * This could be an indication that our database is not up to date, so this should be fixed. + */ + if ((version_info = get_driver_version_info(driver, driver_model)) + || (version_info = get_driver_version_info(driver, DRIVER_MODEL_GENERIC))) { - /* If ARB_base_instance is not supported the baseInstance field - * in indirect draw parameters must be 0 or behavior is undefined. - */ - WARN("Disabling ARB_draw_indirect because ARB_base_instance is not supported.\n"); - gl_info->supported[ARB_DRAW_INDIRECT] = FALSE; + driver_info->name = version_info->driver_name; + driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version); + driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build); } - if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !wined3d_settings.multisample_textures) - gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE; - if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !gl_info->supported[ARB_TEXTURE_STORAGE_MULTISAMPLE]) + else { - WARN("Disabling ARB_texture_multisample because immutable storage is not supported.\n"); - gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE; + ERR("No driver version info found for device %04x:%04x, driver model %#x.\n", + driver_info->vendor, driver_info->device, driver_model); + driver_info->name = "Display"; + driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15); + driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* NVIDIA RIVA TNT, arbitrary */ } +} - wined3d_adapter_init_limits(gl_info); - - if (gl_info->supported[ARB_VERTEX_PROGRAM] && test_arb_vs_offset_limit(gl_info)) - gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT; - - if (gl_info->supported[ARB_SHADING_LANGUAGE_100]) +enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *vendor, + enum wined3d_feature_level feature_level) +{ + static const struct wined3d_fallback_card { - const char *str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); - unsigned int major, minor; - - TRACE("GLSL version string: %s.\n", debugstr_a(str)); - - /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */ - sscanf(str, "%u.%u", &major, &minor); - gl_info->glsl_version = MAKEDWORD_VERSION(major, minor); - if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30)) - gl_info->supported[WINED3D_GLSL_130] = TRUE; + enum wined3d_feature_level feature_level; + enum wined3d_pci_device device_id; } - - checkGLcall("extension detection"); - - adapter->shader_backend = select_shader_backend(gl_info); - adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend); - adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend); - - adapter->shader_backend->shader_get_caps(gl_info, &shader_caps); - adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING; - adapter->d3d_info.limits.vs_version = shader_caps.vs_version; - adapter->d3d_info.limits.hs_version = shader_caps.hs_version; - adapter->d3d_info.limits.ds_version = shader_caps.ds_version; - adapter->d3d_info.limits.gs_version = shader_caps.gs_version; - adapter->d3d_info.limits.ps_version = shader_caps.ps_version; - adapter->d3d_info.limits.cs_version = shader_caps.cs_version; - adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count; - adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count; - adapter->d3d_info.limits.varying_count = shader_caps.varying_count; - adapter->d3d_info.shader_double_precision = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION; - - adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps); - adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw; - adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes; - adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; - adapter->d3d_info.limits.active_light_count = vertex_caps.max_active_lights; - adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading; - - adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); - adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages; - adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures; - adapter->d3d_info.shader_color_key = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY; - adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags; - TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages); - - adapter->d3d_info.valid_rt_mask = 0; - for (i = 0; i < gl_info->limits.buffers; ++i) - adapter->d3d_info.valid_rt_mask |= (1u << i); - - adapter->d3d_info.valid_dual_rt_mask = 0; - for (i = 0; i < gl_info->limits.dual_buffers; ++i) - adapter->d3d_info.valid_dual_rt_mask |= (1u << i); - - if (!adapter->d3d_info.shader_color_key) + card_fallback_nvidia[] = { - /* We do not want to deal with re-creating immutable texture storage for color keying emulation. */ - WARN("Disabling ARB_texture_storage because fragment pipe doesn't support color keying.\n"); - gl_info->supported[ARB_TEXTURE_STORAGE] = FALSE; - } + {WINED3D_FEATURE_LEVEL_5, CARD_NVIDIA_RIVA_128}, + {WINED3D_FEATURE_LEVEL_6, CARD_NVIDIA_RIVA_TNT}, + {WINED3D_FEATURE_LEVEL_7, CARD_NVIDIA_GEFORCE}, + {WINED3D_FEATURE_LEVEL_8, CARD_NVIDIA_GEFORCE3}, + {WINED3D_FEATURE_LEVEL_9_2, CARD_NVIDIA_GEFORCEFX_5800}, + {WINED3D_FEATURE_LEVEL_9_3, CARD_NVIDIA_GEFORCE_6800}, + {WINED3D_FEATURE_LEVEL_10, CARD_NVIDIA_GEFORCE_8800GTX}, + {WINED3D_FEATURE_LEVEL_11, CARD_NVIDIA_GEFORCE_GTX470}, + {WINED3D_FEATURE_LEVEL_NONE}, + }, + card_fallback_amd[] = + { + {WINED3D_FEATURE_LEVEL_5, CARD_AMD_RAGE_128PRO}, + {WINED3D_FEATURE_LEVEL_7, CARD_AMD_RADEON_7200}, + {WINED3D_FEATURE_LEVEL_8, CARD_AMD_RADEON_8500}, + {WINED3D_FEATURE_LEVEL_9_1, CARD_AMD_RADEON_9500}, + {WINED3D_FEATURE_LEVEL_9_3, CARD_AMD_RADEON_X1600}, + {WINED3D_FEATURE_LEVEL_10, CARD_AMD_RADEON_HD2900}, + {WINED3D_FEATURE_LEVEL_11, CARD_AMD_RADEON_HD5600}, + {WINED3D_FEATURE_LEVEL_NONE}, + }, + card_fallback_intel[] = + { + {WINED3D_FEATURE_LEVEL_5, CARD_INTEL_845G}, + {WINED3D_FEATURE_LEVEL_8, CARD_INTEL_915G}, + {WINED3D_FEATURE_LEVEL_9_3, CARD_INTEL_945G}, + {WINED3D_FEATURE_LEVEL_10, CARD_INTEL_G45}, + {WINED3D_FEATURE_LEVEL_11, CARD_INTEL_IVBD}, + {WINED3D_FEATURE_LEVEL_NONE}, + }; - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) + static const struct { - gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbuffer; - gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbuffer; - gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffers; - gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffers; - gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorage; - gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisample; - gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameteriv; - gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebuffer; - gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebuffer; - gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffers; - gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffers; - gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatus; - gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D; - gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D; - gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3D; - gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayer; - gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer; - gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv - = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv; - gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer; - gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap; - gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture; + enum wined3d_pci_vendor vendor; + const struct wined3d_fallback_card *cards; } - else + fallbacks[] = { - if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) - { - gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbufferEXT; - gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbufferEXT; - gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffersEXT; - gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffersEXT; - gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorageEXT; - gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameterivEXT; - gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebufferEXT; - gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebufferEXT; - gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffersEXT; - gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffersEXT; - gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatusEXT; - gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1DEXT; - gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2DEXT; - gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3DEXT; - gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbufferEXT; - gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv - = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameterivEXT; - gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmapEXT; - } - else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n"); - wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; - } - - if (gl_info->supported[ARB_GEOMETRY_SHADER4]) - { - gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB; - gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB; - } - if (gl_info->supported[EXT_FRAMEBUFFER_BLIT]) - { - gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT; - } - if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) - { - gl_info->fbo_ops.glRenderbufferStorageMultisample - = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisampleEXT; - } - } + {HW_VENDOR_AMD, card_fallback_amd}, + {HW_VENDOR_NVIDIA, card_fallback_nvidia}, + {HW_VENDOR_VMWARE, card_fallback_amd}, + {HW_VENDOR_INTEL, card_fallback_intel}, + }; - gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT; - gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] = - gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT; - gl_info->wrap_lookup[WINED3D_TADDRESS_CLAMP - WINED3D_TADDRESS_WRAP] = GL_CLAMP_TO_EDGE; - gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] = - gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT; - gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] = - gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] ? GL_MIRROR_CLAMP_TO_EDGE : GL_REPEAT; + const struct wined3d_fallback_card *cards; + enum wined3d_pci_device device_id; + unsigned int i; - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + cards = NULL; + for (i = 0; i < ARRAY_SIZE(fallbacks); ++i) { - GLuint vao; - - GL_EXTCALL(glGenVertexArrays(1, &vao)); - GL_EXTCALL(glBindVertexArray(vao)); - checkGLcall("creating VAO"); + if (*vendor == fallbacks[i].vendor) + cards = fallbacks[i].cards; } - - gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str, gl_version_str); - TRACE("Guessed GL vendor %#x.\n", gl_vendor); - - if (!(gpu_description = query_gpu_description(gl_info, &vram_bytes))) + if (!cards) { - enum wined3d_pci_vendor vendor; - enum wined3d_pci_device device; - - vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str); - TRACE("Guessed vendor PCI ID 0x%04x.\n", vendor); - - device = wined3d_guess_card(&shader_caps, &fragment_caps, gl_info->glsl_version, - gl_renderer_str, &gl_vendor, &vendor); - TRACE("Guessed device PCI ID 0x%04x.\n", device); - - if (!(gpu_description = get_gpu_description(vendor, device))) - { - ERR("Card %04x:%04x not found in driver DB.\n", vendor, device); - return FALSE; - } + *vendor = HW_VENDOR_NVIDIA; + cards = card_fallback_nvidia; } - fixup_extensions(gl_info, caps_gl_ctx, gl_renderer_str, gl_vendor, - gpu_description->vendor, gpu_description->card); - init_driver_info(driver_info, gpu_description, vram_bytes); - - gl_ext_emul_mask = adapter->vertex_pipe->vp_get_emul_mask(gl_info) - | adapter->fragment_pipe->get_emul_mask(gl_info); - if (gl_ext_emul_mask & GL_EXT_EMUL_ARB_MULTITEXTURE) - install_gl_compat_wrapper(gl_info, ARB_MULTITEXTURE); - if (gl_ext_emul_mask & GL_EXT_EMUL_EXT_FOG_COORD) - install_gl_compat_wrapper(gl_info, EXT_FOG_COORD); - return TRUE; + device_id = cards->device_id; + for (i = 0; cards[i].feature_level; ++i) + { + if (feature_level >= cards[i].feature_level) + device_id = cards[i].device_id; + } + return device_id; } UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d) @@ -4510,14 +808,14 @@ HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned in if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; + adapter = wined3d->adapters[adapter_idx]; if (!(monitor = MonitorFromPoint(adapter->monitor_position, MONITOR_DEFAULTTOPRIMARY))) return WINED3DERR_INVALIDCALL; if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, &rotation))) return hr; - memcpy(desc->device_name, adapter->DeviceName, sizeof(desc->device_name)); + memcpy(desc->device_name, adapter->device_name, sizeof(desc->device_name)); SetRect(&desc->desktop_rect, 0, 0, mode.width, mode.height); OffsetRect(&desc->desktop_rect, adapter->monitor_position.x, adapter->monitor_position.y); /* FIXME: We should get this from EnumDisplayDevices() when the adapters @@ -4549,14 +847,14 @@ UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT ad if (adapter_idx >= wined3d->adapter_count) return 0; - adapter = &wined3d->adapters[adapter_idx]; - format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET); + adapter = wined3d->adapters[adapter_idx]; + format = wined3d_get_format(adapter, format_id, WINED3D_BIND_RENDER_TARGET); format_bits = format->byte_count * CHAR_BIT; memset(&mode, 0, sizeof(mode)); mode.dmSize = sizeof(mode); - while (EnumDisplaySettingsExW(adapter->DeviceName, j++, &mode, 0)) + while (EnumDisplaySettingsExW(adapter->device_name, j++, &mode, 0)) { if (mode.dmFields & DM_DISPLAYFLAGS) { @@ -4603,8 +901,8 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada if (!mode || adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; - format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET); + adapter = wined3d->adapters[adapter_idx]; + format = wined3d_get_format(adapter, format_id, WINED3D_BIND_RENDER_TARGET); format_bits = format->byte_count * CHAR_BIT; memset(&m, 0, sizeof(m)); @@ -4612,7 +910,7 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada while (i <= mode_idx) { - if (!EnumDisplaySettingsExW(adapter->DeviceName, j++, &m, 0)) + if (!EnumDisplaySettingsExW(adapter->device_name, j++, &m, 0)) { WARN("Invalid mode_idx %u.\n", mode_idx); return WINED3DERR_INVALIDCALL; @@ -4776,12 +1074,12 @@ HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UI if (!mode || adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; + adapter = wined3d->adapters[adapter_idx]; memset(&m, 0, sizeof(m)); m.dmSize = sizeof(m); - EnumDisplaySettingsExW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &m, 0); + EnumDisplaySettingsExW(adapter->device_name, ENUM_CURRENT_SETTINGS, &m, 0); mode->width = m.dmPelsWidth; mode->height = m.dmPelsHeight; mode->refresh_rate = DEFAULT_REFRESH_RATE; @@ -4850,7 +1148,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; + adapter = wined3d->adapters[adapter_idx]; memset(&new_mode, 0, sizeof(new_mode)); new_mode.dmSize = sizeof(new_mode); @@ -4863,7 +1161,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, TRACE("mode %ux%u@%u %s %#x.\n", mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id), mode->scanline_ordering); - format = wined3d_get_format(&adapter->gl_info, mode->format_id, WINED3DUSAGE_RENDERTARGET); + format = wined3d_get_format(adapter, mode->format_id, WINED3D_BIND_RENDER_TARGET); new_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; new_mode.dmBitsPerPel = format->byte_count * CHAR_BIT; @@ -4884,7 +1182,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, } else { - if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_REGISTRY_SETTINGS, &new_mode)) + if (!EnumDisplaySettingsW(adapter->device_name, ENUM_REGISTRY_SETTINGS, &new_mode)) { ERR("Failed to read mode from registry.\n"); return WINED3DERR_NOTAVAILABLE; @@ -4893,7 +1191,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, } /* Only change the mode if necessary. */ - if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, ¤t_mode)) + if (!EnumDisplaySettingsW(adapter->device_name, ENUM_CURRENT_SETTINGS, ¤t_mode)) { ERR("Failed to get current display mode.\n"); } @@ -4910,7 +1208,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, return WINED3D_OK; } - ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL); + ret = ChangeDisplaySettingsExW(adapter->device_name, &new_mode, NULL, CDS_FULLSCREEN, NULL); if (ret != DISP_CHANGE_SUCCESSFUL) { if (new_mode.dmFields & DM_DISPLAYFREQUENCY) @@ -4918,7 +1216,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n"); new_mode.dmFields &= ~DM_DISPLAYFREQUENCY; new_mode.dmDisplayFrequency = 0; - ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL); + ret = ChangeDisplaySettingsExW(adapter->device_name, &new_mode, NULL, CDS_FULLSCREEN, NULL); } if (ret != DISP_CHANGE_SUCCESSFUL) return WINED3DERR_NOTAVAILABLE; @@ -4934,46 +1232,32 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, return WINED3D_OK; } -/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER, - and fields being inserted in the middle, a new structure is used in place */ HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d, UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier) { const struct wined3d_adapter *adapter; - size_t len; TRACE("wined3d %p, adapter_idx %u, flags %#x, identifier %p.\n", wined3d, adapter_idx, flags, identifier); - if (adapter_idx >= wined3d->adapter_count) - return WINED3DERR_INVALIDCALL; + wined3d_mutex_lock(); - adapter = &wined3d->adapters[adapter_idx]; + if (adapter_idx >= wined3d->adapter_count) + goto fail; - if (identifier->driver_size) - { - const char *name = adapter->driver_info.name; - len = min(strlen(name), identifier->driver_size - 1); - memcpy(identifier->driver, name, len); - memset(&identifier->driver[len], 0, identifier->driver_size - len); - } + adapter = wined3d->adapters[adapter_idx]; - if (identifier->description_size) - { - const char *description = adapter->driver_info.description; - len = min(strlen(description), identifier->description_size - 1); - memcpy(identifier->description, description, len); - memset(&identifier->description[len], 0, identifier->description_size - len); - } + wined3d_copy_name(identifier->driver, adapter->driver_info.name, identifier->driver_size); + wined3d_copy_name(identifier->description, adapter->driver_info.description, identifier->description_size); /* Note that d3d8 doesn't supply a device name. */ if (identifier->device_name_size) { - if (!WideCharToMultiByte(CP_ACP, 0, adapter->DeviceName, -1, identifier->device_name, + if (!WideCharToMultiByte(CP_ACP, 0, adapter->device_name, -1, identifier->device_name, identifier->device_name_size, NULL, NULL)) { ERR("Failed to convert device name, last error %#x.\n", GetLastError()); - return WINED3DERR_INVALIDCALL; + goto fail; } } @@ -4983,12 +1267,21 @@ HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d, identifier->device_id = adapter->driver_info.device; identifier->subsystem_id = 0; identifier->revision = 0; - memcpy(&identifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(identifier->device_identifier)); + identifier->device_identifier = IID_D3DDEVICE_D3DUID; + identifier->driver_uuid = adapter->driver_uuid; + identifier->device_uuid = adapter->device_uuid; identifier->whql_level = (flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1; - memcpy(&identifier->adapter_luid, &adapter->luid, sizeof(identifier->adapter_luid)); - identifier->video_memory = min(~(SIZE_T)0, adapter->vram_bytes); + identifier->adapter_luid = adapter->luid; + identifier->video_memory = min(~(SIZE_T)0, adapter->driver_info.vram_bytes); + identifier->shared_system_memory = min(~(SIZE_T)0, adapter->driver_info.sysmem_bytes); + + wined3d_mutex_unlock(); return WINED3D_OK; + +fail: + wined3d_mutex_unlock(); + return WINED3DERR_INVALIDCALL; } HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx, @@ -5038,56 +1331,6 @@ HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, U return WINED3D_OK; } -static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info, - const struct wined3d_pixel_format *cfg, const struct wined3d_format *format) -{ - /* Float formats need FBOs. If FBOs are used this function isn't called */ - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) - return FALSE; - - /* Probably a RGBA_float or color index mode. */ - if (cfg->iPixelType != WGL_TYPE_RGBA_ARB) - return FALSE; - - if (cfg->redSize < format->red_size - || cfg->greenSize < format->green_size - || cfg->blueSize < format->blue_size - || cfg->alphaSize < format->alpha_size) - return FALSE; - - return TRUE; -} - -static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_info, - const struct wined3d_pixel_format *cfg, const struct wined3d_format *format) -{ - BOOL lockable = FALSE; - - /* Float formats need FBOs. If FBOs are used this function isn't called */ - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) - return FALSE; - - if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT)) - lockable = TRUE; - - /* On some modern cards like the Geforce8/9, GLX doesn't offer some - * depth/stencil formats which D3D9 reports. We can safely report - * "compatible" formats (e.g. D24 can be used for D16) as long as we - * aren't dealing with a lockable format. This also helps D3D <= 7 as they - * expect D16 which isn't offered without this on Geforce8 cards. */ - if (!(cfg->depthSize == format->depth_size || (!lockable && cfg->depthSize > format->depth_size))) - return FALSE; - - /* Some cards like Intel i915 ones only offer D24S8 but lots of games also - * need a format without stencil. We can allow a mismatch if the format - * doesn't have any stencil bits. If it does have stencil bits the size - * must match, or stencil wrapping would break. */ - if (format->stencil_size && cfg->stencilSize != format->stencil_size) - return FALSE; - - return TRUE; -} - HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id) @@ -5096,7 +1339,7 @@ HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d, const struct wined3d_format *ds_format; const struct wined3d_adapter *adapter; - TRACE("wined3d %p, adapter_idx %u, device_type %s,\n" + TRACE("wined3d %p, adapter_idx %u, device_type %s, " "adapter_format %s, render_target_format %s, depth_stencil_format %s.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id), debug_d3dformat(render_target_format_id), debug_d3dformat(depth_stencil_format_id)); @@ -5104,35 +1347,26 @@ HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d, if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; - rt_format = wined3d_get_format(&adapter->gl_info, render_target_format_id, WINED3DUSAGE_RENDERTARGET); - ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id, WINED3DUSAGE_DEPTHSTENCIL); - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + adapter = wined3d->adapters[adapter_idx]; + + rt_format = wined3d_get_format(adapter, render_target_format_id, WINED3D_BIND_RENDER_TARGET); + ds_format = wined3d_get_format(adapter, depth_stencil_format_id, WINED3D_BIND_DEPTH_STENCIL); + + if (!(rt_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)) { - if ((rt_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET) - && (ds_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) - { - TRACE("Formats match.\n"); - return WINED3D_OK; - } + WARN("Format %s is not render target format.\n", debug_d3dformat(rt_format->id)); + return WINED3DERR_NOTAVAILABLE; } - else + if (!(ds_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) { - const struct wined3d_pixel_format *cfgs; - unsigned int cfg_count; - unsigned int i; + WARN("Format %s is not depth/stencil format.\n", debug_d3dformat(ds_format->id)); + return WINED3DERR_NOTAVAILABLE; + } - cfgs = adapter->cfgs; - cfg_count = adapter->cfg_count; - for (i = 0; i < cfg_count; ++i) - { - if (wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], rt_format) - && wined3d_check_pixel_format_depth(&adapter->gl_info, &cfgs[i], ds_format)) - { - TRACE("Formats match.\n"); - return WINED3D_OK; - } - } + if (adapter->adapter_ops->adapter_check_format(adapter, NULL, rt_format, ds_format)) + { + TRACE("Formats match.\n"); + return WINED3D_OK; } TRACE("Unsupported format pair: %s and %s.\n", @@ -5146,8 +1380,8 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3 enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed, enum wined3d_multisample_type multisample_type, DWORD *quality_levels) { - const struct wined3d_gl_info *gl_info = &wined3d->adapters[adapter_idx].gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id, 0); + const struct wined3d_adapter *adapter; + const struct wined3d_format *format; HRESULT hr = WINED3D_OK; TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s, " @@ -5167,6 +1401,9 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3 return WINED3DERR_NOTAVAILABLE; } + adapter = wined3d->adapters[adapter_idx]; + format = wined3d_get_format(adapter, surface_format_id, 0); + if (multisample_type && !(format->multisample_types & 1u << (multisample_type - 1))) hr = WINED3DERR_NOTAVAILABLE; @@ -5186,140 +1423,35 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3 return hr; } -/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */ -static BOOL CheckDepthStencilCapability(const struct wined3d_adapter *adapter, - const struct wined3d_format *display_format, const struct wined3d_format *ds_format, +static BOOL wined3d_check_depth_stencil_format(const struct wined3d_adapter *adapter, + const struct wined3d_format *adapter_format, const struct wined3d_format *ds_format, enum wined3d_gl_resource_type gl_type) { - /* Only allow depth/stencil formats */ - if (!(ds_format->depth_size || ds_format->stencil_size)) return FALSE; + if (!ds_format->depth_size && !ds_format->stencil_size) + return FALSE; + if (!(ds_format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) + return FALSE; /* Blacklist formats not supported on Windows */ - switch (ds_format->id) + if (ds_format->id == WINED3DFMT_S1_UINT_D15_UNORM /* Breaks the shadowvol2 dx7 sdk sample */ + || ds_format->id == WINED3DFMT_S4X4_UINT_D24_UNORM) { - case WINED3DFMT_S1_UINT_D15_UNORM: /* Breaks the shadowvol2 dx7 sdk sample */ - case WINED3DFMT_S4X4_UINT_D24_UNORM: - TRACE("[FAILED] - not supported on windows.\n"); - return FALSE; - - default: - break; - } - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */ - if (ds_format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) - return TRUE; - } - else - { - unsigned int i; - - /* Walk through all WGL pixel formats to find a match */ - for (i = 0; i < adapter->cfg_count; ++i) - { - const struct wined3d_pixel_format *cfg = &adapter->cfgs[i]; - if (wined3d_check_pixel_format_color(&adapter->gl_info, cfg, display_format) - && wined3d_check_pixel_format_depth(&adapter->gl_info, cfg, ds_format)) - return TRUE; - } - } - - return FALSE; -} - -/* Check the render target capabilities of a format */ -static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter, - const struct wined3d_format *adapter_format, const struct wined3d_format *check_format, - enum wined3d_gl_resource_type gl_type) -{ - /* Filter out non-RT formats */ - if (!(check_format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET)) + TRACE("Format %s is blacklisted.\n", debug_d3dformat(ds_format->id)); return FALSE; - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - return TRUE; - if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) - { - const struct wined3d_pixel_format *cfgs = adapter->cfgs; - unsigned int i; - - /* In backbuffer mode the front and backbuffer share the same WGL - * pixelformat. The format must match in RGB, alpha is allowed to be - * different. (Only the backbuffer can have alpha.) */ - if (adapter_format->red_size != check_format->red_size - || adapter_format->green_size != check_format->green_size - || adapter_format->blue_size != check_format->blue_size) - { - TRACE("[FAILED]\n"); - return FALSE; - } - - /* Check if there is a WGL pixel format matching the requirements, the format should also be window - * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */ - for (i = 0; i < adapter->cfg_count; ++i) - { - if (cfgs[i].windowDrawable - && wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], check_format)) - { - TRACE("Pixel format %d is compatible with format %s.\n", - cfgs[i].iPixelFormat, debug_d3dformat(check_format->id)); - return TRUE; - } - } } - return FALSE; + + return adapter->adapter_ops->adapter_check_format(adapter, adapter_format, NULL, ds_format); } -static BOOL wined3d_check_surface_capability(const struct wined3d_format *format, BOOL no3d) +static BOOL wined3d_check_surface_format(const struct wined3d_format *format) { - if (no3d) - { - switch (format->id) - { - case WINED3DFMT_B8G8R8_UNORM: - TRACE("[FAILED] - Not enumerated on Windows.\n"); - return FALSE; - case WINED3DFMT_B8G8R8A8_UNORM: - case WINED3DFMT_B8G8R8X8_UNORM: - case WINED3DFMT_B5G6R5_UNORM: - case WINED3DFMT_B5G5R5X1_UNORM: - case WINED3DFMT_B5G5R5A1_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - case WINED3DFMT_B2G3R3_UNORM: - case WINED3DFMT_A8_UNORM: - case WINED3DFMT_B2G3R3A8_UNORM: - case WINED3DFMT_B4G4R4X4_UNORM: - case WINED3DFMT_R10G10B10A2_UNORM: - case WINED3DFMT_R8G8B8A8_UNORM: - case WINED3DFMT_R8G8B8X8_UNORM: - case WINED3DFMT_R16G16_UNORM: - case WINED3DFMT_B10G10R10A2_UNORM: - case WINED3DFMT_R16G16B16A16_UNORM: - case WINED3DFMT_P8_UINT: - TRACE("[OK]\n"); - return TRUE; - default: - TRACE("[FAILED] - Not available on GDI surfaces.\n"); - return FALSE; - } - } - - if (format->glInternal) - { - TRACE("[OK]\n"); + if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] | format->flags[WINED3D_GL_RES_TYPE_RB]) & WINED3DFMT_FLAG_BLIT) return TRUE; - } if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_EXTENSION | WINED3DFMT_FLAG_TEXTURE)) == (WINED3DFMT_FLAG_EXTENSION | WINED3DFMT_FLAG_TEXTURE)) - { - TRACE("[OK]\n"); return TRUE; - } - /* Reject other formats */ - TRACE("[FAILED]\n"); return FALSE; } @@ -5333,61 +1465,64 @@ static BOOL wined3d_check_surface_capability(const struct wined3d_format *format * restrict it to some should applications need that. */ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage, - enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id) + unsigned int bind_flags, enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id) { - const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx]; - const struct wined3d_gl_info *gl_info = &adapter->gl_info; const struct wined3d_format *adapter_format, *format; enum wined3d_gl_resource_type gl_type, gl_type_end; + const struct wined3d_adapter *adapter; BOOL mipmap_gen_supported = TRUE; + unsigned int allowed_bind_flags; DWORD format_flags = 0; DWORD allowed_usage; TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s, " - "resource_type %s, check_format %s.\n", + "bind_flags %s, resource_type %s, check_format %s.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id), - debug_d3dusage(usage), debug_d3dusagequery(usage), debug_d3dresourcetype(resource_type), - debug_d3dformat(check_format_id)); + debug_d3dusage(usage), debug_d3dusagequery(usage), wined3d_debug_bind_flags(bind_flags), + debug_d3dresourcetype(resource_type), debug_d3dformat(check_format_id)); if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter_format = wined3d_get_format(gl_info, adapter_format_id, WINED3DUSAGE_RENDERTARGET); - format = wined3d_get_format(gl_info, check_format_id, usage); + adapter = wined3d->adapters[adapter_idx]; + adapter_format = wined3d_get_format(adapter, adapter_format_id, WINED3D_BIND_RENDER_TARGET); + format = wined3d_get_format(adapter, check_format_id, bind_flags); switch (resource_type) { case WINED3D_RTYPE_NONE: - allowed_usage = WINED3DUSAGE_DEPTHSTENCIL - | WINED3DUSAGE_RENDERTARGET; - gl_type = WINED3D_GL_RES_TYPE_TEX_1D; + allowed_usage = 0; + allowed_bind_flags = WINED3D_BIND_RENDER_TARGET + | WINED3D_BIND_DEPTH_STENCIL; + gl_type = WINED3D_GL_RES_TYPE_TEX_2D; gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D; break; case WINED3D_RTYPE_TEXTURE_1D: allowed_usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_SOFTWAREPROCESSING - | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER + | WINED3DUSAGE_QUERY_GENMIPMAP | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING | WINED3DUSAGE_QUERY_SRGBREAD | WINED3DUSAGE_QUERY_SRGBWRITE | WINED3DUSAGE_QUERY_VERTEXTEXTURE | WINED3DUSAGE_QUERY_WRAPANDMIP; + allowed_bind_flags = WINED3D_BIND_SHADER_RESOURCE; gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_1D; break; case WINED3D_RTYPE_TEXTURE_2D: - allowed_usage = WINED3DUSAGE_DEPTHSTENCIL - | WINED3DUSAGE_RENDERTARGET - | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - if (usage & WINED3DUSAGE_RENDERTARGET) + allowed_usage = WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + if (bind_flags & WINED3D_BIND_RENDER_TARGET) allowed_usage |= WINED3DUSAGE_QUERY_SRGBWRITE; - if (!(usage & WINED3DUSAGE_TEXTURE)) + allowed_bind_flags = WINED3D_BIND_RENDER_TARGET + | WINED3D_BIND_DEPTH_STENCIL; + if (!(bind_flags & WINED3D_BIND_SHADER_RESOURCE)) { - if (!wined3d_check_surface_capability(format, wined3d->flags & WINED3D_NO3D)) + if (!wined3d_check_surface_format(format)) { - TRACE("[FAILED] - Not supported for plain surfaces.\n"); + TRACE("%s is not supported for plain surfaces.\n", debug_d3dformat(format->id)); return WINED3DERR_NOTAVAILABLE; } @@ -5397,7 +1532,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad allowed_usage |= WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_SOFTWAREPROCESSING - | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER | WINED3DUSAGE_QUERY_GENMIPMAP | WINED3DUSAGE_QUERY_LEGACYBUMPMAP @@ -5405,40 +1539,29 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad | WINED3DUSAGE_QUERY_SRGBWRITE | WINED3DUSAGE_QUERY_VERTEXTEXTURE | WINED3DUSAGE_QUERY_WRAPANDMIP; + allowed_bind_flags |= WINED3D_BIND_SHADER_RESOURCE; gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_2D; if (usage & WINED3DUSAGE_LEGACY_CUBEMAP) { - allowed_usage &= ~(WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_QUERY_LEGACYBUMPMAP); + allowed_usage &= ~WINED3DUSAGE_QUERY_LEGACYBUMPMAP; + allowed_bind_flags &= ~WINED3D_BIND_DEPTH_STENCIL; gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_CUBE; } - else if ((usage & WINED3DUSAGE_DEPTHSTENCIL) - && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW) - && !gl_info->supported[ARB_SHADOW]) - { - TRACE("[FAILED] - No shadow sampler support.\n"); - return WINED3DERR_NOTAVAILABLE; - } break; case WINED3D_RTYPE_TEXTURE_3D: allowed_usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_SOFTWAREPROCESSING - | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING | WINED3DUSAGE_QUERY_SRGBREAD | WINED3DUSAGE_QUERY_SRGBWRITE | WINED3DUSAGE_QUERY_VERTEXTEXTURE | WINED3DUSAGE_QUERY_WRAPANDMIP; + allowed_bind_flags = WINED3D_BIND_SHADER_RESOURCE; gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D; break; - case WINED3D_RTYPE_BUFFER: - allowed_usage = WINED3DUSAGE_DYNAMIC - | WINED3DUSAGE_QUERY_VERTEXTEXTURE; - gl_type = gl_type_end = WINED3D_GL_RES_TYPE_BUFFER; - break; - default: FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type)); return WINED3DERR_NOTAVAILABLE; @@ -5451,8 +1574,18 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; } - if (usage & WINED3DUSAGE_TEXTURE) + if ((bind_flags & allowed_bind_flags) != bind_flags) + { + TRACE("Requested bind flags %s, but resource type %s only allows %s.\n", + wined3d_debug_bind_flags(bind_flags), debug_d3dresourcetype(resource_type), + wined3d_debug_bind_flags(allowed_bind_flags)); + return WINED3DERR_NOTAVAILABLE; + } + + if (bind_flags & WINED3D_BIND_SHADER_RESOURCE) format_flags |= WINED3DFMT_FLAG_TEXTURE; + if (bind_flags & WINED3D_BIND_RENDER_TARGET) + format_flags |= WINED3DFMT_FLAG_RENDERTARGET; if (usage & WINED3DUSAGE_QUERY_FILTER) format_flags |= WINED3DFMT_FLAG_FILTERING; if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) @@ -5481,22 +1614,22 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; } - if ((usage & WINED3DUSAGE_RENDERTARGET) - && !CheckRenderTargetCapability(adapter, adapter_format, format, gl_type)) + if ((bind_flags & WINED3D_BIND_RENDER_TARGET) + && !adapter->adapter_ops->adapter_check_format(adapter, adapter_format, format, NULL)) { - TRACE("Requested WINED3DUSAGE_RENDERTARGET, but format %s is not supported for render targets.\n", + TRACE("Requested WINED3D_BIND_RENDER_TARGET, but format %s is not supported for render targets.\n", debug_d3dformat(check_format_id)); return WINED3DERR_NOTAVAILABLE; } /* 3D depth / stencil textures are never supported. */ - if (usage == WINED3DUSAGE_DEPTHSTENCIL && gl_type == WINED3D_GL_RES_TYPE_TEX_3D) + if (bind_flags == WINED3D_BIND_DEPTH_STENCIL && gl_type == WINED3D_GL_RES_TYPE_TEX_3D) continue; - if ((usage & WINED3DUSAGE_DEPTHSTENCIL) - && !CheckDepthStencilCapability(adapter, adapter_format, format, gl_type)) + if ((bind_flags & WINED3D_BIND_DEPTH_STENCIL) + && !wined3d_check_depth_stencil_format(adapter, adapter_format, format, gl_type)) { - TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n", + TRACE("Requested WINED3D_BIND_DEPTH_STENCIL, but format %s is not supported for depth/stencil buffers.\n", debug_d3dformat(check_format_id)); return WINED3DERR_NOTAVAILABLE; } @@ -5517,7 +1650,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_format_id format_id, UINT width) { - const struct wined3d_gl_info *gl_info; + const struct wined3d_adapter *adapter; unsigned int row_pitch, slice_pitch; TRACE("wined3d %p, adapter_idx %u, format_id %s, width %u.\n", @@ -5526,8 +1659,8 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad if (adapter_idx >= wined3d->adapter_count) return ~0u; - gl_info = &wined3d->adapters[adapter_idx].gl_info; - wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id, 0), + adapter = wined3d->adapters[adapter_idx]; + wined3d_format_calculate_pitch(wined3d_get_format(adapter, format_id, 0), 1, width, 1, &row_pitch, &slice_pitch); return row_pitch; @@ -5647,7 +1780,7 @@ HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adap /* Validate that the back buffer format is usable for render targets. */ if (FAILED(wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format, - WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_TEXTURE_2D, backbuffer_format))) + 0, WINED3D_BIND_RENDER_TARGET, WINED3D_RTYPE_TEXTURE_2D, backbuffer_format))) { TRACE("Format %s not allowed for render targets.\n", debug_d3dformat(backbuffer_format)); return WINED3DERR_NOTAVAILABLE; @@ -5656,13 +1789,12 @@ HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adap return WINED3D_OK; } -HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx, - enum wined3d_device_type device_type, WINED3DCAPS *caps) +HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, unsigned int adapter_idx, + enum wined3d_device_type device_type, struct wined3d_caps *caps) { - const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx]; - const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; - const struct wined3d_gl_info *gl_info = &adapter->gl_info; + const struct wined3d_d3d_info *d3d_info; struct wined3d_vertex_caps vertex_caps; + const struct wined3d_adapter *adapter; DWORD ckey_caps, blit_caps, fx_caps; struct fragment_caps fragment_caps; struct shader_caps shader_caps; @@ -5673,6 +1805,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; + adapter = wined3d->adapters[adapter_idx]; + d3d_info = &adapter->d3d_info; + caps->DeviceType = (device_type == WINED3D_DEVICE_TYPE_HAL) ? WINED3D_DEVICE_TYPE_HAL : WINED3D_DEVICE_TYPE_REF; caps->AdapterOrdinal = adapter_idx; @@ -5680,16 +1815,11 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED | WINED3DCAPS2_FULLSCREENGAMMA | WINED3DCAPS2_DYNAMICTEXTURES; - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) - caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP; caps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | WINED3DCAPS3_COPY_TO_VIDMEM | WINED3DCAPS3_COPY_TO_SYSTEMMEM; - caps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE | - WINED3DPRESENT_INTERVAL_ONE; - caps->CursorCaps = WINED3DCURSORCAPS_COLOR | WINED3DCURSORCAPS_LOWRES; @@ -5719,18 +1849,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte /* TODO: WINED3DPMISCCAPS_NULLREFERENCE WINED3DPMISCCAPS_FOGANDSPECULARALPHA - WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS WINED3DPMISCCAPS_FOGVERTEXCLAMPED */ - if (gl_info->supported[WINED3D_GL_BLEND_EQUATION]) - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_BLENDOP; - if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND; - if (gl_info->supported[EXT_DRAW_BUFFERS2]) - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS; - if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT; - caps->RasterCaps = WINED3DPRASTERCAPS_DITHER | WINED3DPRASTERCAPS_PAT | WINED3DPRASTERCAPS_WFOG | @@ -5744,13 +1864,6 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS | WINED3DPRASTERCAPS_DEPTHBIAS; - if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) - { - caps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY | - WINED3DPRASTERCAPS_ZBIAS | - WINED3DPRASTERCAPS_MIPMAPLODBIAS; - } - caps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS | WINED3DPCMPCAPS_EQUAL | WINED3DPCMPCAPS_GREATER | @@ -5787,16 +1900,6 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DPBLENDCAPS_SRCCOLOR | WINED3DPBLENDCAPS_ZERO; - if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) - caps->DestBlendCaps |= WINED3DPBLENDCAPS_SRCALPHASAT; - - if (gl_info->supported[EXT_BLEND_COLOR]) - { - caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR; - caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR; - } - - caps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS | WINED3DPCMPCAPS_EQUAL | WINED3DPCMPCAPS_GREATER | @@ -5823,137 +1926,34 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DPTEXTURECAPS_PROJECTED | WINED3DPTEXTURECAPS_PERSPECTIVE; - if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + if (!d3d_info->texture_npot) { caps->TextureCaps |= WINED3DPTEXTURECAPS_POW2; - if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] || gl_info->supported[ARB_TEXTURE_RECTANGLE]) + if (d3d_info->texture_npot_conditional) caps->TextureCaps |= WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL; } - if (gl_info->supported[EXT_TEXTURE3D]) - { - caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP | - WINED3DPTEXTURECAPS_MIPVOLUMEMAP; - if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) - { - caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP_POW2; - } - } - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP | - WINED3DPTEXTURECAPS_MIPCUBEMAP; - if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) - { - caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP_POW2; - } - } - caps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR | WINED3DPTFILTERCAPS_MAGFPOINT | WINED3DPTFILTERCAPS_MINFLINEAR | WINED3DPTFILTERCAPS_MINFPOINT | - WINED3DPTFILTERCAPS_MIPFLINEAR | - WINED3DPTFILTERCAPS_MIPFPOINT | - WINED3DPTFILTERCAPS_LINEAR | - WINED3DPTFILTERCAPS_LINEARMIPLINEAR | - WINED3DPTFILTERCAPS_LINEARMIPNEAREST | - WINED3DPTFILTERCAPS_MIPLINEAR | - WINED3DPTFILTERCAPS_MIPNEAREST | - WINED3DPTFILTERCAPS_NEAREST; - - if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) - { - caps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC | - WINED3DPTFILTERCAPS_MINFANISOTROPIC; - } - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - caps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR | - WINED3DPTFILTERCAPS_MAGFPOINT | - WINED3DPTFILTERCAPS_MINFLINEAR | - WINED3DPTFILTERCAPS_MINFPOINT | - WINED3DPTFILTERCAPS_MIPFLINEAR | - WINED3DPTFILTERCAPS_MIPFPOINT | - WINED3DPTFILTERCAPS_LINEAR | - WINED3DPTFILTERCAPS_LINEARMIPLINEAR | - WINED3DPTFILTERCAPS_LINEARMIPNEAREST | - WINED3DPTFILTERCAPS_MIPLINEAR | - WINED3DPTFILTERCAPS_MIPNEAREST | - WINED3DPTFILTERCAPS_NEAREST; - - if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) - { - caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC | - WINED3DPTFILTERCAPS_MINFANISOTROPIC; - } - } - else - { - caps->CubeTextureFilterCaps = 0; - } + WINED3DPTFILTERCAPS_MIPFLINEAR | + WINED3DPTFILTERCAPS_MIPFPOINT | + WINED3DPTFILTERCAPS_LINEAR | + WINED3DPTFILTERCAPS_LINEARMIPLINEAR | + WINED3DPTFILTERCAPS_LINEARMIPNEAREST | + WINED3DPTFILTERCAPS_MIPLINEAR | + WINED3DPTFILTERCAPS_MIPNEAREST | + WINED3DPTFILTERCAPS_NEAREST; - if (gl_info->supported[EXT_TEXTURE3D]) - { - caps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR | - WINED3DPTFILTERCAPS_MAGFPOINT | - WINED3DPTFILTERCAPS_MINFLINEAR | - WINED3DPTFILTERCAPS_MINFPOINT | - WINED3DPTFILTERCAPS_MIPFLINEAR | - WINED3DPTFILTERCAPS_MIPFPOINT | - WINED3DPTFILTERCAPS_LINEAR | - WINED3DPTFILTERCAPS_LINEARMIPLINEAR | - WINED3DPTFILTERCAPS_LINEARMIPNEAREST | - WINED3DPTFILTERCAPS_MIPLINEAR | - WINED3DPTFILTERCAPS_MIPNEAREST | - WINED3DPTFILTERCAPS_NEAREST; - } - else - { - caps->VolumeTextureFilterCaps = 0; - } + caps->CubeTextureFilterCaps = 0; + caps->VolumeTextureFilterCaps = 0; caps->TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV | WINED3DPTADDRESSCAPS_CLAMP | WINED3DPTADDRESSCAPS_WRAP; - if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP]) - { - caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER; - } - if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT]) - { - caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR; - } - if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]) - { - caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE; - } - - if (gl_info->supported[EXT_TEXTURE3D]) - { - caps->VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV | - WINED3DPTADDRESSCAPS_CLAMP | - WINED3DPTADDRESSCAPS_WRAP; - if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP]) - { - caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER; - } - if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT]) - { - caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR; - } - if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]) - { - caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE; - } - } - else - { - caps->VolumeTextureAddressCaps = 0; - } + caps->VolumeTextureAddressCaps = 0; caps->LineCaps = WINED3DLINECAPS_TEXTURE | WINED3DLINECAPS_ZTEST | @@ -5964,17 +1964,14 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte * idea how generating the smoothing alpha values works; the result is different */ - caps->MaxTextureWidth = gl_info->limits.texture_size; - caps->MaxTextureHeight = gl_info->limits.texture_size; + caps->MaxTextureWidth = d3d_info->limits.texture_size; + caps->MaxTextureHeight = d3d_info->limits.texture_size; - if (gl_info->supported[EXT_TEXTURE3D]) - caps->MaxVolumeExtent = gl_info->limits.texture3d_size; - else - caps->MaxVolumeExtent = 0; + caps->MaxVolumeExtent = 0; caps->MaxTextureRepeat = 32768; - caps->MaxTextureAspectRatio = gl_info->limits.texture_size; - caps->MaxVertexW = 1.0f; + caps->MaxTextureAspectRatio = d3d_info->limits.texture_size; + caps->MaxVertexW = 1e10f; caps->GuardBandLeft = 0.0f; caps->GuardBandTop = 0.0f; @@ -5989,23 +1986,13 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DSTENCILCAPS_KEEP | WINED3DSTENCILCAPS_REPLACE | WINED3DSTENCILCAPS_ZERO; - if (gl_info->supported[EXT_STENCIL_WRAP]) - { - caps->StencilCaps |= WINED3DSTENCILCAPS_DECR | - WINED3DSTENCILCAPS_INCR; - } - if (gl_info->supported[WINED3D_GL_VERSION_2_0] || gl_info->supported[EXT_STENCIL_TWO_SIDE] - || gl_info->supported[ATI_SEPARATE_STENCIL]) - { - caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED; - } - caps->MaxAnisotropy = gl_info->limits.anisotropy; - caps->MaxPointSize = gl_info->limits.pointsize_max; + caps->MaxAnisotropy = 0; + caps->MaxPointSize = d3d_info->limits.pointsize_max; caps->MaxPrimitiveCount = 0x555555; /* Taken from an AMD Radeon HD 5700 (Evergreen) GPU. */ caps->MaxVertexIndex = 0xffffff; /* Taken from an AMD Radeon HD 5700 (Evergreen) GPU. */ - caps->MaxStreams = MAX_STREAMS; + caps->MaxStreams = WINED3D_MAX_STREAMS; caps->MaxStreamStride = 1024; /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */ @@ -6016,7 +2003,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->AdapterOrdinalInGroup = 0; caps->NumberOfAdaptersInGroup = 1; - caps->NumSimultaneousRTs = gl_info->limits.buffers; + caps->NumSimultaneousRTs = d3d_info->limits.max_rt_count; caps->StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT | WINED3DPTFILTERCAPS_MAGFPOINT | @@ -6024,9 +2011,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DPTFILTERCAPS_MAGFLINEAR; caps->VertexTextureFilterCaps = 0; - adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); - adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps); - adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps); + adapter->shader_backend->shader_get_caps(adapter, &shader_caps); + adapter->fragment_pipe->get_caps(adapter, &fragment_caps); + adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */ caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps; @@ -6044,10 +2031,9 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->MaxUserClipPlanes = vertex_caps.max_user_clip_planes; caps->MaxActiveLights = vertex_caps.max_active_lights; caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices; - if (device_type == WINED3D_DEVICE_TYPE_HAL) - caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; - else - caps->MaxVertexBlendMatrixIndex = 255; + caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; + if (caps->DeviceType == WINED3D_DEVICE_TYPE_HAL) + caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps; caps->FVFCaps = vertex_caps.fvf_caps; caps->RasterCaps |= vertex_caps.raster_caps; @@ -6065,26 +2051,26 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->VS20Caps.caps = WINED3DVS20CAPS_PREDICATION; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */ caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; - caps->VS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_vs_temps); + caps->VS20Caps.temp_count = 32; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */ caps->VS20Caps.static_flow_control_depth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH; caps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */ - caps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions); + caps->MaxVertexShader30InstructionSlots = WINED3DMIN30SHADERINSTRUCTIONS; caps->VertexTextureFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT | WINED3DPTFILTERCAPS_MAGFPOINT; } else if (caps->VertexShaderVersion == 2) { caps->VS20Caps.caps = 0; caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH; - caps->VS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_vs_temps); + caps->VS20Caps.temp_count = WINED3DVS20_MIN_NUMTEMPS; caps->VS20Caps.static_flow_control_depth = 1; caps->MaxVShaderInstructionsExecuted = 65535; caps->MaxVertexShader30InstructionSlots = 0; } - else - { /* VS 1.x */ + else /* VS 1.x */ + { caps->VS20Caps.caps = 0; caps->VS20Caps.dynamic_flow_control_depth = 0; caps->VS20Caps.temp_count = 0; @@ -6111,22 +2097,21 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */ caps->PS20Caps.dynamic_flow_control_depth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; - caps->PS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_ps_temps); + caps->PS20Caps.temp_count = 32; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */ caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */ caps->PS20Caps.instruction_slot_count = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; caps->MaxPShaderInstructionsExecuted = 65535; - caps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS, - adapter->gl_info.limits.arb_ps_instructions); + caps->MaxPixelShader30InstructionSlots = WINED3DMIN30SHADERINSTRUCTIONS; } - else if(caps->PixelShaderVersion == 2) + else if (caps->PixelShaderVersion == 2) { /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */ caps->PS20Caps.caps = 0; caps->PS20Caps.dynamic_flow_control_depth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */ - caps->PS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_ps_temps); + caps->PS20Caps.temp_count = WINED3DPS20_MIN_NUMTEMPS; caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */ /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */ caps->PS20Caps.instruction_slot_count = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; @@ -6159,11 +2144,6 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DDTCAPS_UBYTE4N | WINED3DDTCAPS_SHORT2N | WINED3DDTCAPS_SHORT4N; - if (gl_info->supported[ARB_HALF_FLOAT_VERTEX]) - { - caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 | - WINED3DDTCAPS_FLOAT16_4; - } } else { @@ -6216,600 +2196,562 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->ddraw_caps.ssb_color_key_caps = ckey_caps; caps->ddraw_caps.ssb_fx_caps = fx_caps; - caps->ddraw_caps.dds_caps = WINEDDSCAPS_ALPHA | - WINEDDSCAPS_BACKBUFFER | - WINEDDSCAPS_FLIP | - WINEDDSCAPS_FRONTBUFFER | - WINEDDSCAPS_OFFSCREENPLAIN | - WINEDDSCAPS_PALETTE | - WINEDDSCAPS_PRIMARYSURFACE | - WINEDDSCAPS_SYSTEMMEMORY | - WINEDDSCAPS_VIDEOMEMORY | - WINEDDSCAPS_VISIBLE; - - if (!(wined3d->flags & WINED3D_NO3D)) - { - caps->ddraw_caps.dds_caps |= WINEDDSCAPS_3DDEVICE | - WINEDDSCAPS_MIPMAP | - WINEDDSCAPS_TEXTURE | - WINEDDSCAPS_ZBUFFER; - caps->ddraw_caps.caps |= WINEDDCAPS_3D; - } + caps->ddraw_caps.dds_caps = WINEDDSCAPS_OFFSCREENPLAIN + | WINEDDSCAPS_PALETTE + | WINEDDSCAPS_PRIMARYSURFACE + | WINEDDSCAPS_TEXTURE + | WINEDDSCAPS_ZBUFFER + | WINEDDSCAPS_MIPMAP; caps->shader_double_precision = d3d_info->shader_double_precision; + caps->viewport_array_index_any_shader = d3d_info->viewport_array_index_any_shader; + + caps->max_feature_level = d3d_info->feature_level; + + adapter->adapter_ops->adapter_get_wined3d_caps(adapter, caps); return WINED3D_OK; } -HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, - HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent, - struct wined3d_device **device) +HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, unsigned int adapter_idx, + enum wined3d_device_type device_type, HWND focus_window, DWORD flags, BYTE surface_alignment, + const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count, + struct wined3d_device_parent *device_parent, struct wined3d_device **device) { + const struct wined3d_adapter *adapter; struct wined3d_device *object; HRESULT hr; - TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, surface_alignment %u, device_parent %p, device %p.\n", - wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment, device_parent, device); + TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, " + "surface_alignment %u, feature_levels %p, feature_level_count %u, device_parent %p, device %p.\n", + wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment, + feature_levels, feature_level_count, device_parent, device); - /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter - * number and create a device without a 3D adapter for 2D only operation. */ - if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count) + if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) + adapter = wined3d->adapters[adapter_idx]; + if (FAILED(hr = adapter->adapter_ops->adapter_create_device(wined3d, adapter, + device_type, focus_window, flags, surface_alignment, + feature_levels, feature_level_count, device_parent, &object))) + return hr; + + TRACE("Created device %p.\n", object); + *device = object; + + device_parent->ops->wined3d_device_created(device_parent, *device); + + return WINED3D_OK; +} + +static void adapter_no3d_destroy(struct wined3d_adapter *adapter) +{ + wined3d_adapter_cleanup(adapter); + heap_free(adapter); +} + +static HRESULT adapter_no3d_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter, + enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, + const enum wined3d_feature_level *levels, unsigned int level_count, + struct wined3d_device_parent *device_parent, struct wined3d_device **device) +{ + struct wined3d_device_no3d *device_no3d; + HRESULT hr; + + if (!(device_no3d = heap_alloc_zero(sizeof(*device_no3d)))) return E_OUTOFMEMORY; - hr = device_init(object, wined3d, adapter_idx, device_type, - focus_window, flags, surface_alignment, device_parent); - if (FAILED(hr)) + if (FAILED(hr = wined3d_device_init(&device_no3d->d, wined3d, adapter->ordinal, device_type, + focus_window, flags, surface_alignment, levels, level_count, device_parent))) { WARN("Failed to initialize device, hr %#x.\n", hr); - heap_free(object); + heap_free(device_no3d); return hr; } - TRACE("Created device %p.\n", object); - *device = object; - - device_parent->ops->wined3d_device_created(device_parent, *device); + *device = &device_no3d->d; return WINED3D_OK; } -static void WINE_GLAPI invalid_func(const void *data) +static void adapter_no3d_destroy_device(struct wined3d_device *device) { - ERR("Invalid vertex attribute function called.\n"); - DebugBreak(); + wined3d_device_cleanup(device); + heap_free(device); } -static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data) +struct wined3d_context *adapter_no3d_acquire_context(struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx) { - ERR("Invalid texcoord function called.\n"); - DebugBreak(); + TRACE("device %p, texture %p, sub_resource_idx %u.\n", device, texture, sub_resource_idx); + + wined3d_from_cs(device->cs); + + if (!device->context_count) + return NULL; + + return &wined3d_device_no3d(device)->context_no3d; } -static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data) +void adapter_no3d_release_context(struct wined3d_context *context) { - ERR("Invalid attribute function called.\n"); - DebugBreak(); + TRACE("context %p.\n", context); } -/* Helper functions for providing vertex data to OpenGL. The arrays are - * initialised based on the extension detection and are used in - * draw_primitive_immediate_mode(). */ -static void WINE_GLAPI position_d3dcolor(const void *data) +static void adapter_no3d_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps) { - DWORD pos = *((const DWORD *)data); +} - FIXME("Add a test for fixed function position from d3dcolor type.\n"); - context_get_current()->gl_info->gl_ops.gl.p_glVertex4s(D3DCOLOR_B_R(pos), - D3DCOLOR_B_G(pos), - D3DCOLOR_B_B(pos), - D3DCOLOR_B_A(pos)); +static BOOL adapter_no3d_check_format(const struct wined3d_adapter *adapter, + const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format, + const struct wined3d_format *ds_format) +{ + return TRUE; } -static void WINE_GLAPI position_float4(const void *data) +static HRESULT adapter_no3d_init_3d(struct wined3d_device *device) { - const GLfloat *pos = data; + struct wined3d_context *context_no3d; + HRESULT hr; - if (pos[3] != 0.0f && pos[3] != 1.0f) + TRACE("device %p.\n", device); + + context_no3d = &wined3d_device_no3d(device)->context_no3d; + if (FAILED(hr = wined3d_context_no3d_init(context_no3d, device->swapchains[0]))) { - float w = 1.0f / pos[3]; + WARN("Failed to initialise context.\n"); + return hr; + } - context_get_current()->gl_info->gl_ops.gl.p_glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w); + if (!device_context_add(device, context_no3d)) + { + ERR("Failed to add the newly created context to the context list.\n"); + wined3d_context_cleanup(context_no3d); + return E_FAIL; } - else + + TRACE("Initialised context %p.\n", context_no3d); + + if (!(device->blitter = wined3d_cpu_blitter_create())) { - context_get_current()->gl_info->gl_ops.gl.p_glVertex3fv(pos); + ERR("Failed to create CPU blitter.\n"); + device_context_remove(device, context_no3d); + wined3d_context_cleanup(context_no3d); + return E_FAIL; } + + return WINED3D_OK; } -static void WINE_GLAPI diffuse_d3dcolor(const void *data) +static void adapter_no3d_uninit_3d(struct wined3d_device *device) { - DWORD diffuseColor = *((const DWORD *)data); + struct wined3d_context *context_no3d; + + TRACE("device %p.\n", device); - context_get_current()->gl_info->gl_ops.gl.p_glColor4ub(D3DCOLOR_B_R(diffuseColor), - D3DCOLOR_B_G(diffuseColor), - D3DCOLOR_B_B(diffuseColor), - D3DCOLOR_B_A(diffuseColor)); + context_no3d = &wined3d_device_no3d(device)->context_no3d; + device->blitter->ops->blitter_destroy(device->blitter, NULL); + device_context_remove(device, context_no3d); + wined3d_context_cleanup(context_no3d); } -static void WINE_GLAPI specular_d3dcolor(const void *data) +static void *adapter_no3d_map_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, size_t size, uint32_t bind_flags, uint32_t map_flags) { - DWORD specularColor = *((const DWORD *)data); - GLubyte d[] = + if (data->buffer_object) { - D3DCOLOR_B_R(specularColor), - D3DCOLOR_B_G(specularColor), - D3DCOLOR_B_B(specularColor) - }; + ERR("Unsupported buffer object %#lx.\n", data->buffer_object); + return NULL; + } - context_get_current()->gl_info->gl_ops.ext.p_glSecondaryColor3ubvEXT(d); + return data->addr; } -static void WINE_GLAPI warn_no_specular_func(const void *data) +static void adapter_no3d_unmap_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, + uint32_t bind_flags, unsigned int range_count, const struct wined3d_map_range *ranges) { - WARN("GL_EXT_secondary_color not supported.\n"); + if (data->buffer_object) + ERR("Unsupported buffer object %#lx.\n", data->buffer_object); } -static void WINE_GLAPI generic_d3dcolor(GLuint idx, const void *data) +static void adapter_no3d_copy_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *dst, uint32_t dst_bind_flags, + const struct wined3d_bo_address *src, uint32_t src_bind_flags, size_t size) { - DWORD color = *((const DWORD *)data); - - context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nub(idx, - D3DCOLOR_B_R(color), D3DCOLOR_B_G(color), - D3DCOLOR_B_B(color), D3DCOLOR_B_A(color)); + if (dst->buffer_object) + ERR("Unsupported dst buffer object %#lx.\n", dst->buffer_object); + if (src->buffer_object) + ERR("Unsupported src buffer object %#lx.\n", src->buffer_object); + if (dst->buffer_object || src->buffer_object) + return; + memcpy(dst->addr, src->addr, size); } -static void WINE_GLAPI generic_short2n(GLuint idx, const void *data) +static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) { - const GLshort s[] = {((const GLshort *)data)[0], ((const GLshort *)data)[1], 0, 1}; + struct wined3d_swapchain *swapchain_no3d; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", + device, desc, parent, parent_ops, swapchain); + + if (!(swapchain_no3d = heap_alloc_zero(sizeof(*swapchain_no3d)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_no3d_init(swapchain_no3d, device, desc, parent, parent_ops))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(swapchain_no3d); + return hr; + } + + TRACE("Created swapchain %p.\n", swapchain_no3d); + *swapchain = swapchain_no3d; - context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nsv(idx, s); + return hr; } -static void WINE_GLAPI generic_ushort2n(GLuint idx, const void *data) +static void adapter_no3d_destroy_swapchain(struct wined3d_swapchain *swapchain) { - const GLushort s[] = {((const GLushort *)data)[0], ((const GLushort *)data)[1], 0, 1}; - - context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nusv(idx, s); + wined3d_swapchain_cleanup(swapchain); + heap_free(swapchain); } -static void WINE_GLAPI generic_float16_2(GLuint idx, const void *data) +static HRESULT adapter_no3d_create_buffer(struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer) { - float x = float_16_to_32(((const unsigned short *)data) + 0); - float y = float_16_to_32(((const unsigned short *)data) + 1); + struct wined3d_buffer *buffer_no3d; + HRESULT hr; + + TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n", + device, desc, data, parent, parent_ops, buffer); + + if (!(buffer_no3d = heap_alloc_zero(sizeof(*buffer_no3d)))) + return E_OUTOFMEMORY; - context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib2f(idx, x, y); + if (FAILED(hr = wined3d_buffer_no3d_init(buffer_no3d, device, desc, data, parent, parent_ops))) + { + WARN("Failed to initialise buffer, hr %#x.\n", hr); + heap_free(buffer_no3d); + return hr; + } + + TRACE("Created buffer %p.\n", buffer_no3d); + *buffer = buffer_no3d; + + return hr; } -static void WINE_GLAPI generic_float16_4(GLuint idx, const void *data) +static void adapter_no3d_destroy_buffer(struct wined3d_buffer *buffer) { - float x = float_16_to_32(((const unsigned short *)data) + 0); - float y = float_16_to_32(((const unsigned short *)data) + 1); - float z = float_16_to_32(((const unsigned short *)data) + 2); - float w = float_16_to_32(((const unsigned short *)data) + 3); + struct wined3d_device *device = buffer->resource.device; + unsigned int swapchain_count = device->swapchain_count; - context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4f(idx, x, y, z, w); + TRACE("buffer %p.\n", buffer); + + /* Take a reference to the device, in case releasing the buffer would + * cause the device to be destroyed. However, swapchain resources don't + * take a reference to the device, and we wouldn't want to increment the + * refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_buffer_cleanup(buffer); + wined3d_cs_destroy_object(device->cs, heap_free, buffer); + if (swapchain_count) + wined3d_device_decref(device); } -static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter) +static HRESULT adapter_no3d_create_texture(struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; - struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops; - unsigned int i; + struct wined3d_texture *texture_no3d; + HRESULT hr; - for (i = 0; i < WINED3D_FFP_EMIT_COUNT; ++i) - { - ops->position[i] = invalid_func; - ops->diffuse[i] = invalid_func; - ops->specular[i] = invalid_func; - ops->normal[i] = invalid_func; - ops->texcoord[i] = invalid_texcoord_func; - ops->generic[i] = invalid_generic_attrib_func; - } + TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n", + device, desc, layer_count, level_count, flags, parent, parent_ops, texture); - ops->position[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex3fv; - if (!d3d_info->xyzrhw) - ops->position[WINED3D_FFP_EMIT_FLOAT4] = position_float4; - else - ops->position[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex4fv; - ops->position[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor; - ops->position[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex2sv; - - ops->diffuse[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor3fv; - ops->diffuse[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4fv; - ops->diffuse[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor; - ops->diffuse[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4ubv; - ops->diffuse[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4sv; - ops->diffuse[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4usv; - - /* No 4 component entry points here. */ - if (gl_info->supported[EXT_SECONDARY_COLOR]) - ops->specular[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)GL_EXTCALL(glSecondaryColor3fvEXT); - else - ops->specular[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func; - if (gl_info->supported[EXT_SECONDARY_COLOR]) - ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor; - else - ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func; - - /* Only 3 component entry points here. Test how others behave. Float4 - * normals are used by one of our tests, trying to pass it to the pixel - * shader, which fails on Windows. */ - ops->normal[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv; - /* Just ignore the 4th value. */ - ops->normal[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv; - - ops->texcoord[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB; - ops->texcoord[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB; - ops->texcoord[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB; - ops->texcoord[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB; - ops->texcoord[WINED3D_FFP_EMIT_SHORT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2svARB; - ops->texcoord[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4svARB; - if (gl_info->supported[NV_HALF_FLOAT]) - { - /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT. */ - ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_2] = - (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2hvNV; - ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] = - (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4hvNV; - } + if (!(texture_no3d = wined3d_texture_allocate_object_memory(sizeof(*texture_no3d), level_count, layer_count))) + return E_OUTOFMEMORY; - ops->generic[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib1fv; - ops->generic[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2fv; - ops->generic[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib3fv; - ops->generic[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4fv; - if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) - ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = generic_d3dcolor; - else - ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = - (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv; - ops->generic[WINED3D_FFP_EMIT_UBYTE4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4ubv; - ops->generic[WINED3D_FFP_EMIT_SHORT2] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2sv; - ops->generic[WINED3D_FFP_EMIT_SHORT4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4sv; - ops->generic[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv; - ops->generic[WINED3D_FFP_EMIT_SHORT2N] = generic_short2n; - ops->generic[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nsv; - ops->generic[WINED3D_FFP_EMIT_USHORT2N] = generic_ushort2n; - ops->generic[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nusv; - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = - (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2hvNV; - ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = - (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4hvNV; - } - else + if (FAILED(hr = wined3d_texture_no3d_init(texture_no3d, device, desc, + layer_count, level_count, flags, parent, parent_ops))) { - ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = generic_float16_2; - ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = generic_float16_4; + WARN("Failed to initialise texture, hr %#x.\n", hr); + heap_free(texture_no3d); + return hr; } + + TRACE("Created texture %p.\n", texture_no3d); + *texture = texture_no3d; + + return hr; } -static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc) +static void adapter_no3d_destroy_texture(struct wined3d_texture *texture) { - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - int i; + struct wined3d_device *device = texture->resource.device; + unsigned int swapchain_count = device->swapchain_count; - if (gl_info->supported[WGL_ARB_PIXEL_FORMAT]) - { - UINT attrib_count = 0; - GLint cfg_count; - int attribs[11]; - int values[11]; - int attribute; - - attribute = WGL_NUMBER_PIXEL_FORMATS_ARB; - GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count)); - - adapter->cfgs = heap_calloc(cfg_count, sizeof(*adapter->cfgs)); - attribs[attrib_count++] = WGL_RED_BITS_ARB; - attribs[attrib_count++] = WGL_GREEN_BITS_ARB; - attribs[attrib_count++] = WGL_BLUE_BITS_ARB; - attribs[attrib_count++] = WGL_ALPHA_BITS_ARB; - attribs[attrib_count++] = WGL_COLOR_BITS_ARB; - attribs[attrib_count++] = WGL_DEPTH_BITS_ARB; - attribs[attrib_count++] = WGL_STENCIL_BITS_ARB; - attribs[attrib_count++] = WGL_DRAW_TO_WINDOW_ARB; - attribs[attrib_count++] = WGL_PIXEL_TYPE_ARB; - attribs[attrib_count++] = WGL_DOUBLE_BUFFER_ARB; - attribs[attrib_count++] = WGL_AUX_BUFFERS_ARB; - - for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i) - { - struct wined3d_pixel_format *cfg = &adapter->cfgs[adapter->cfg_count]; - int format_id = i + 1; + TRACE("texture %p.\n", texture); - if (!GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, attrib_count, attribs, values))) - continue; + /* Take a reference to the device, in case releasing the texture would + * cause the device to be destroyed. However, swapchain resources don't + * take a reference to the device, and we wouldn't want to increment the + * refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); - cfg->iPixelFormat = format_id; - cfg->redSize = values[0]; - cfg->greenSize = values[1]; - cfg->blueSize = values[2]; - cfg->alphaSize = values[3]; - cfg->colorSize = values[4]; - cfg->depthSize = values[5]; - cfg->stencilSize = values[6]; - cfg->windowDrawable = values[7]; - cfg->iPixelType = values[8]; - cfg->doubleBuffer = values[9]; - cfg->auxBuffers = values[10]; - - cfg->numSamples = 0; - /* Check multisample support. */ - if (gl_info->supported[ARB_MULTISAMPLE]) - { - int attribs[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB}; - int values[2]; + wined3d_texture_sub_resources_destroyed(texture); + texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); - if (GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, 2, attribs, values))) - { - /* values[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether - * multisampling is supported. values[1] = number of - * multisample buffers. */ - if (values[0]) - cfg->numSamples = values[1]; - } - } + wined3d_texture_cleanup(texture); + wined3d_cs_destroy_object(device->cs, heap_free, texture); - TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " - "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n", - cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer, - cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize, - cfg->depthSize, cfg->stencilSize, cfg->numSamples, cfg->windowDrawable); + if (swapchain_count) + wined3d_device_decref(device); +} - ++adapter->cfg_count; - } - } - else - { - int cfg_count; +static HRESULT adapter_no3d_create_rendertarget_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_rendertarget_view **view) +{ + struct wined3d_rendertarget_view *view_no3d; + HRESULT hr; - cfg_count = DescribePixelFormat(dc, 0, 0, 0); - adapter->cfgs = heap_calloc(cfg_count, sizeof(*adapter->cfgs)); + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); - for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i) - { - struct wined3d_pixel_format *cfg = &adapter->cfgs[adapter->cfg_count]; - PIXELFORMATDESCRIPTOR pfd; - int format_id = i + 1; + if (!(view_no3d = heap_alloc_zero(sizeof(*view_no3d)))) + return E_OUTOFMEMORY; - if (!DescribePixelFormat(dc, format_id, sizeof(pfd), &pfd)) - continue; + if (FAILED(hr = wined3d_rendertarget_view_no3d_init(view_no3d, desc, resource, parent, parent_ops))) + { + WARN("Failed to initialise view, hr %#x.\n", hr); + heap_free(view_no3d); + return hr; + } - /* We only want HW acceleration using an OpenGL ICD driver. - * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering. - * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD - * driver (e.g. 3dfx minigl). */ - if (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) - { - TRACE("Skipping format %d because it isn't ICD accelerated.\n", format_id); - continue; - } + TRACE("Created render target view %p.\n", view_no3d); + *view = view_no3d; - cfg->iPixelFormat = format_id; - cfg->redSize = pfd.cRedBits; - cfg->greenSize = pfd.cGreenBits; - cfg->blueSize = pfd.cBlueBits; - cfg->alphaSize = pfd.cAlphaBits; - cfg->colorSize = pfd.cColorBits; - cfg->depthSize = pfd.cDepthBits; - cfg->stencilSize = pfd.cStencilBits; - cfg->windowDrawable = (pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0; - cfg->iPixelType = (pfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB; - cfg->doubleBuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0; - cfg->auxBuffers = pfd.cAuxBuffers; - cfg->numSamples = 0; - - TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " - "depth=%d, stencil=%d, windowDrawable=%d\n", - cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer, - cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize, - cfg->depthSize, cfg->stencilSize, cfg->windowDrawable); - - ++adapter->cfg_count; - } - } + return hr; } -static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD flags) +static void adapter_no3d_destroy_rendertarget_view(struct wined3d_rendertarget_view *view) { - const char *gl_vendor, *gl_renderer; + struct wined3d_device *device = view->resource->device; + unsigned int swapchain_count = device->swapchain_count; - if (wined3d_settings.explicit_gl_version || (flags & WINED3D_PIXEL_CENTER_INTEGER)) - return wined3d_settings.max_gl_version; + TRACE("view %p.\n", view); - gl_vendor = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR); - gl_renderer = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER); - if (!gl_vendor || !gl_renderer - || wined3d_guess_card_vendor(gl_vendor, gl_renderer) == HW_VENDOR_NVIDIA) - return wined3d_settings.max_gl_version; + /* Take a reference to the device, in case releasing the view's resource + * would cause the device to be destroyed. However, swapchain resources + * don't take a reference to the device, and we wouldn't want to increment + * the refcount on a device that's in the process of being destroyed. */ + if (swapchain_count) + wined3d_device_incref(device); + wined3d_rendertarget_view_cleanup(view); + wined3d_cs_destroy_object(device->cs, heap_free, view); + if (swapchain_count) + wined3d_device_decref(device); +} + +static HRESULT adapter_no3d_create_shader_resource_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view) +{ + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); - return MAKEDWORD_VERSION(4, 4); + return E_NOTIMPL; } -static BOOL has_extension(const char *list, const char *ext) +static void adapter_no3d_destroy_shader_resource_view(struct wined3d_shader_resource_view *view) { - size_t len = strlen(ext); - while (list) - { - while (*list == ' ') list++; - if (!strncmp(list, ext, len) && (!list[len] || list[len] == ' ')) return TRUE; - list = strchr(list, ' '); - } - return FALSE; + TRACE("view %p.\n", view); } -static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags) +static HRESULT adapter_no3d_create_unordered_access_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view) { - static const DWORD supported_gl_versions[] = - { - MAKEDWORD_VERSION(4, 4), - MAKEDWORD_VERSION(3, 2), - MAKEDWORD_VERSION(1, 0), - }; - struct wined3d_gl_info *gl_info = &adapter->gl_info; - struct wined3d_caps_gl_ctx caps_gl_ctx = {0}; - unsigned int i; - DISPLAY_DEVICEW display_device; - DWORD max_gl_version; + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); - TRACE("adapter %p, ordinal %u.\n", adapter, ordinal); + return E_NOTIMPL; +} - adapter->ordinal = ordinal; +static void adapter_no3d_destroy_unordered_access_view(struct wined3d_unordered_access_view *view) +{ + TRACE("view %p.\n", view); +} -/* Dynamically load all GL core functions */ -#ifdef USE_WIN32_OPENGL - { - HMODULE mod_gl = GetModuleHandleA("opengl32.dll"); -#define USE_GL_FUNC(f) gl_info->gl_ops.gl.p_##f = (void *)GetProcAddress(mod_gl, #f); - ALL_WGL_FUNCS -#undef USE_GL_FUNC - gl_info->gl_ops.wgl.p_wglSwapBuffers = (void *)GetProcAddress(mod_gl, "wglSwapBuffers"); - gl_info->gl_ops.wgl.p_wglGetPixelFormat = (void *)GetProcAddress(mod_gl, "wglGetPixelFormat"); - } -#else - /* To bypass the opengl32 thunks retrieve functions from the WGL driver instead of opengl32 */ - { - HDC hdc = GetDC( 0 ); - const struct opengl_funcs *wgl_driver = __wine_get_wgl_driver( hdc, WINE_WGL_DRIVER_VERSION ); - ReleaseDC( 0, hdc ); - if (!wgl_driver || wgl_driver == (void *)-1) return FALSE; - gl_info->gl_ops.wgl = wgl_driver->wgl; - gl_info->gl_ops.gl = wgl_driver->gl; - } -#endif +static HRESULT adapter_no3d_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler) +{ + TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n", + device, desc, parent, parent_ops, sampler); - glEnableWINE = gl_info->gl_ops.gl.p_glEnable; - glDisableWINE = gl_info->gl_ops.gl.p_glDisable; + return E_NOTIMPL; +} - if (!AllocateLocallyUniqueId(&adapter->luid)) - { - ERR("Failed to set adapter LUID (%#x).\n", GetLastError()); - return FALSE; - } - TRACE("Allocated LUID %08x:%08x for adapter %p.\n", - adapter->luid.HighPart, adapter->luid.LowPart, adapter); +static void adapter_no3d_destroy_sampler(struct wined3d_sampler *sampler) +{ + TRACE("sampler %p.\n", sampler); +} - if (!wined3d_caps_gl_ctx_create(adapter, &caps_gl_ctx)) - { - ERR("Failed to get a GL context for adapter %p.\n", adapter); - return FALSE; - } +static HRESULT adapter_no3d_create_query(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) +{ + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); - max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags); + return WINED3DERR_NOTAVAILABLE; +} - if (wined3d_creation_flags & WINED3D_REQUEST_D3D10) - { - const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS); - if (!has_extension(gl_extensions, "GL_ARB_compatibility")) - { - ERR_(winediag)("GL_ARB_compatibility not supported, requesting context with GL version 3.2.\n"); - max_gl_version = MAKEDWORD_VERSION(3, 2); - } - } +static void adapter_no3d_destroy_query(struct wined3d_query *query) +{ + TRACE("query %p.\n", query); +} - for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i) - { - if (supported_gl_versions[i] <= max_gl_version) - break; - } - if (i == ARRAY_SIZE(supported_gl_versions)) - { - ERR_(winediag)("Requested invalid GL version %u.%u.\n", - max_gl_version >> 16, max_gl_version & 0xffff); - i = ARRAY_SIZE(supported_gl_versions) - 1; - } +static void adapter_no3d_flush_context(struct wined3d_context *context) +{ + TRACE("context %p.\n", context); +} - for (; i < ARRAY_SIZE(supported_gl_versions); ++i) - { - gl_info->selected_gl_version = supported_gl_versions[i]; +void adapter_no3d_clear_uav(struct wined3d_context *context, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) +{ + ERR("context %p, view %p, clear_value %s.\n", context, view, debug_uvec4(clear_value)); +} - if (wined3d_caps_gl_ctx_create_attribs(&caps_gl_ctx, gl_info)) - break; +static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops = +{ + adapter_no3d_destroy, + adapter_no3d_create_device, + adapter_no3d_destroy_device, + adapter_no3d_acquire_context, + adapter_no3d_release_context, + adapter_no3d_get_wined3d_caps, + adapter_no3d_check_format, + adapter_no3d_init_3d, + adapter_no3d_uninit_3d, + adapter_no3d_map_bo_address, + adapter_no3d_unmap_bo_address, + adapter_no3d_copy_bo_address, + adapter_no3d_create_swapchain, + adapter_no3d_destroy_swapchain, + adapter_no3d_create_buffer, + adapter_no3d_destroy_buffer, + adapter_no3d_create_texture, + adapter_no3d_destroy_texture, + adapter_no3d_create_rendertarget_view, + adapter_no3d_destroy_rendertarget_view, + adapter_no3d_create_shader_resource_view, + adapter_no3d_destroy_shader_resource_view, + adapter_no3d_create_unordered_access_view, + adapter_no3d_destroy_unordered_access_view, + adapter_no3d_create_sampler, + adapter_no3d_destroy_sampler, + adapter_no3d_create_query, + adapter_no3d_destroy_query, + adapter_no3d_flush_context, + adapter_no3d_clear_uav, +}; - WARN("Couldn't create an OpenGL %u.%u context, trying fallback to a lower version.\n", - supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff); - } +static void wined3d_adapter_no3d_init_d3d_info(struct wined3d_adapter *adapter, unsigned int wined3d_creation_flags) +{ + struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; + + d3d_info->wined3d_creation_flags = wined3d_creation_flags; + d3d_info->texture_npot = TRUE; + d3d_info->feature_level = WINED3D_FEATURE_LEVEL_5; +} + +static struct wined3d_adapter *wined3d_adapter_no3d_create(unsigned int ordinal, unsigned int wined3d_creation_flags) +{ + struct wined3d_adapter *adapter; - if (!wined3d_adapter_init_gl_caps(adapter, &caps_gl_ctx, wined3d_creation_flags)) + static const struct wined3d_gpu_description gpu_description = { - ERR("Failed to initialize GL caps for adapter %p.\n", adapter); - wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); - return FALSE; - } + HW_VENDOR_SOFTWARE, CARD_WINE, "WineD3D DirectDraw Emulation", DRIVER_WINE, 128, + }; + + TRACE("ordinal %u, wined3d_creation_flags %#x.\n", ordinal, wined3d_creation_flags); - if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) - ERR_(winediag)("You are using the backbuffer for offscreen rendering. " - "This is unsupported, and will be removed in a future version.\n"); + if (!(adapter = heap_alloc_zero(sizeof(*adapter)))) + return NULL; + + wined3d_driver_info_init(&adapter->driver_info, &gpu_description, 0, 0); + adapter->vram_bytes_used = 0; + TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->driver_info.vram_bytes)); - wined3d_adapter_init_fb_cfgs(adapter, caps_gl_ctx.dc); - /* We haven't found any suitable formats. This should only happen in - * case of GDI software rendering, which is pretty useless anyway. */ - if (!adapter->cfg_count) + if (!wined3d_adapter_init(adapter, ordinal, &wined3d_adapter_no3d_ops)) { - WARN("No suitable pixel formats found.\n"); - wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); - heap_free(adapter->cfgs); - return FALSE; + heap_free(adapter); + return NULL; } - if (!wined3d_adapter_init_format_info(adapter, &caps_gl_ctx)) + if (!wined3d_adapter_no3d_init_format_info(adapter)) { - ERR("Failed to initialize GL format info.\n"); - wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); - heap_free(adapter->cfgs); - return FALSE; + heap_free(adapter); + return NULL; } - adapter->vram_bytes = adapter->driver_info.vram_bytes; - adapter->vram_bytes_used = 0; - TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->vram_bytes)); - - display_device.cb = sizeof(display_device); - EnumDisplayDevicesW(NULL, ordinal, &display_device, 0); - TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName)); - strcpyW(adapter->DeviceName, display_device.DeviceName); + adapter->vertex_pipe = &none_vertex_pipe; + adapter->fragment_pipe = &none_fragment_pipe; + adapter->shader_backend = &none_shader_backend; - wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); + wined3d_adapter_no3d_init_d3d_info(adapter, wined3d_creation_flags); - wined3d_adapter_init_ffp_attrib_ops(adapter); + TRACE("Created adapter %p.\n", adapter); - return TRUE; + return adapter; } -static BOOL wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordinal) +BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal, + const struct wined3d_adapter_ops *adapter_ops) { DISPLAY_DEVICEW display_device; - memset(adapter, 0, sizeof(*adapter)); adapter->ordinal = ordinal; - adapter->driver_info.name = "Display"; - adapter->driver_info.description = "WineD3D DirectDraw Emulation"; - if (wined3d_settings.emulated_textureram) - adapter->vram_bytes = wined3d_settings.emulated_textureram; - else - adapter->vram_bytes = 128 * 1024 * 1024; + display_device.cb = sizeof(display_device); + EnumDisplayDevicesW(NULL, ordinal, &display_device, 0); + TRACE("Display device: %s.\n", debugstr_w(display_device.DeviceName)); + strcpyW(adapter->device_name, display_device.DeviceName); - if (!wined3d_adapter_init_format_info(adapter, NULL)) + if (!AllocateLocallyUniqueId(&adapter->luid)) + { + ERR("Failed to set adapter LUID (%#x).\n", GetLastError()); return FALSE; + } + TRACE("Allocated LUID %08x:%08x for adapter %p.\n", + adapter->luid.HighPart, adapter->luid.LowPart, adapter); - adapter->vertex_pipe = &none_vertex_pipe; - adapter->fragment_pipe = &none_fragment_pipe; - adapter->shader_backend = &none_shader_backend; + memset(&adapter->driver_uuid, 0, sizeof(adapter->driver_uuid)); + memset(&adapter->device_uuid, 0, sizeof(adapter->device_uuid)); - display_device.cb = sizeof(display_device); - EnumDisplayDevicesW(NULL, ordinal, &display_device, 0); - TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName)); - strcpyW(adapter->DeviceName, display_device.DeviceName); + adapter->formats = NULL; + adapter->adapter_ops = adapter_ops; return TRUE; } +static struct wined3d_adapter *wined3d_adapter_create(unsigned int ordinal, DWORD wined3d_creation_flags) +{ + if (wined3d_creation_flags & WINED3D_NO3D) + return wined3d_adapter_no3d_create(ordinal, wined3d_creation_flags); + + if (wined3d_settings.renderer == WINED3D_RENDERER_VULKAN) + return wined3d_adapter_vk_create(ordinal, wined3d_creation_flags); + + return wined3d_adapter_gl_create(ordinal, wined3d_creation_flags); +} + static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {} const struct wined3d_parent_ops wined3d_null_parent_ops = @@ -6819,20 +2761,14 @@ const struct wined3d_parent_ops wined3d_null_parent_ops = HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) { - BOOL ret; - wined3d->ref = 1; wined3d->flags = flags; - TRACE("Initializing adapters.\n"); + TRACE("Initialising adapters.\n"); - if (flags & WINED3D_NO3D) - ret = wined3d_adapter_init_nogl(&wined3d->adapters[0], 0); - else - ret = wined3d_adapter_init(&wined3d->adapters[0], 0, flags); - if (!ret) + if (!(wined3d->adapters[0] = wined3d_adapter_create(0, flags))) { - WARN("Failed to initialize adapter.\n"); + WARN("Failed to create adapter.\n"); return E_FAIL; } wined3d->adapter_count = 1; diff --git a/dll/directx/wine/wined3d/gl_compat.c b/dll/directx/wine/wined3d/gl_compat.c index 7e6b5101bc4..b8323b7e226 100644 --- a/dll/directx/wine/wined3d/gl_compat.c +++ b/dll/directx/wine/wined3d/gl_compat.c @@ -32,84 +32,104 @@ WINE_DEFAULT_DEBUG_CHANNEL(gl_compat); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); /* Start GL_ARB_multitexture emulation */ -static void WINE_GLAPI wine_glMultiTexCoord1fARB(GLenum target, GLfloat s) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord1fARB(GLenum target, GLfloat s) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord1f(s); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord1f(s); } -static void WINE_GLAPI wine_glMultiTexCoord1fvARB(GLenum target, const GLfloat *v) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord1fvARB(GLenum target, const GLfloat *v) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord1fv(v); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord1fv(v); } -static void WINE_GLAPI wine_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord2f(s, t); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord2f(s, t); } -static void WINE_GLAPI wine_glMultiTexCoord2fvARB(GLenum target, const GLfloat *v) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord2fvARB(GLenum target, const GLfloat *v) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord2fv(v); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord2fv(v); } -static void WINE_GLAPI wine_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord3f(s, t, r); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord3f(s, t, r); } -static void WINE_GLAPI wine_glMultiTexCoord3fvARB(GLenum target, const GLfloat *v) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord3fvARB(GLenum target, const GLfloat *v) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord3fv(v); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord3fv(v); } -static void WINE_GLAPI wine_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4f(s, t, r, q); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord4f(s, t, r, q); } -static void WINE_GLAPI wine_glMultiTexCoord4fvARB(GLenum target, const GLfloat *v) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord4fvARB(GLenum target, const GLfloat *v) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4fv(v); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord4fv(v); } -static void WINE_GLAPI wine_glMultiTexCoord2svARB(GLenum target, const GLshort *v) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord2svARB(GLenum target, const GLshort *v) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord2sv(v); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord2sv(v); } -static void WINE_GLAPI wine_glMultiTexCoord4svARB(GLenum target, const GLshort *v) { - if(target != GL_TEXTURE0) { - ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n"); +static void WINE_GLAPI wine_glMultiTexCoord4svARB(GLenum target, const GLshort *v) +{ + if (target != GL_TEXTURE0) + { + ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported.\n"); return; } - context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4sv(v); + wined3d_context_gl_get_current()->gl_info->gl_ops.gl.p_glTexCoord4sv(v); } static void WINE_GLAPI wine_glActiveTexture(GLenum texture) @@ -149,141 +169,191 @@ static void WINE_GLAPI wine_glGetDoublev(GLenum pname, GLdouble* params) { } /* Start GL_EXT_fogcoord emulation */ -static void (WINE_GLAPI *old_fogcoord_glEnable) (GLenum cap) = NULL; -static void WINE_GLAPI wine_glEnable(GLenum cap) { - if(cap == GL_FOG) { - struct wined3d_context *ctx = context_get_current(); +static void (WINE_GLAPI *old_fogcoord_glEnable)(GLenum cap); +static void WINE_GLAPI wine_glEnable(GLenum cap) +{ + if (cap == GL_FOG) + { + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); + ctx->fog_enabled = 1; - if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return; + if (ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) + return; } old_fogcoord_glEnable(cap); } -static void (WINE_GLAPI *old_fogcoord_glDisable) (GLenum cap) = NULL; -static void WINE_GLAPI wine_glDisable(GLenum cap) { - if(cap == GL_FOG) { - struct wined3d_context *ctx = context_get_current(); +static void (WINE_GLAPI *old_fogcoord_glDisable)(GLenum cap); +static void WINE_GLAPI wine_glDisable(GLenum cap) +{ + if (cap == GL_FOG) + { + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); + ctx->fog_enabled = 0; - if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return; + if (ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) + return; } old_fogcoord_glDisable(cap); } -static void (WINE_GLAPI *old_fogcoord_glFogi) (GLenum pname, GLint param) = NULL; -static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) { - struct wined3d_context *ctx = context_get_current(); +static void (WINE_GLAPI *old_fogcoord_glFogi)(GLenum pname, GLint param); +static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) +{ + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); - if(pname == GL_FOG_COORDINATE_SOURCE_EXT) { + if (pname == GL_FOG_COORDINATE_SOURCE_EXT) + { ctx->gl_fog_source = param; - if(param == GL_FRAGMENT_DEPTH_EXT) { - if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG); - } else { - WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n"); - old_fogcoord_glDisable(GL_FOG); + if (param == GL_FRAGMENT_DEPTH_EXT) + { + if (ctx->fog_enabled) + old_fogcoord_glEnable(GL_FOG); } - } else { - if(pname == GL_FOG_START) { - ctx->fogstart = (float) param; - } else if(pname == GL_FOG_END) { - ctx->fogend = (float) param; + else + { + WARN_(d3d_perf)("Fog coordinates activated, but not supported. Using slow emulation.\n"); + old_fogcoord_glDisable(GL_FOG); } + } + else + { + if (pname == GL_FOG_START) + ctx->fog_start = (float)param; + else if (pname == GL_FOG_END) + ctx->fog_end = (float)param; old_fogcoord_glFogi(pname, param); } } -static void (WINE_GLAPI *old_fogcoord_glFogiv) (GLenum pname, const GLint *param) = NULL; -static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) { - struct wined3d_context *ctx = context_get_current(); - if(pname == GL_FOG_COORDINATE_SOURCE_EXT) { +static void (WINE_GLAPI *old_fogcoord_glFogiv)(GLenum pname, const GLint *param); +static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) +{ + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); + + if (pname == GL_FOG_COORDINATE_SOURCE_EXT) + { ctx->gl_fog_source = *param; - if(*param == GL_FRAGMENT_DEPTH_EXT) { - if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG); - } else { - WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n"); - old_fogcoord_glDisable(GL_FOG); + if (*param == GL_FRAGMENT_DEPTH_EXT) + { + if (ctx->fog_enabled) + old_fogcoord_glEnable(GL_FOG); } - } else { - if(pname == GL_FOG_START) { - ctx->fogstart = (float) *param; - } else if(pname == GL_FOG_END) { - ctx->fogend = (float) *param; + else + { + WARN_(d3d_perf)("Fog coordinates activated, but not supported. Using slow emulation.\n"); + old_fogcoord_glDisable(GL_FOG); } + } + else + { + if (pname == GL_FOG_START) + ctx->fog_start = (float)*param; + else if (pname == GL_FOG_END) + ctx->fog_end = (float)*param; old_fogcoord_glFogiv(pname, param); } } -static void (WINE_GLAPI *old_fogcoord_glFogf) (GLenum pname, GLfloat param) = NULL; -static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) { - struct wined3d_context *ctx = context_get_current(); - if(pname == GL_FOG_COORDINATE_SOURCE_EXT) { - ctx->gl_fog_source = (GLint) param; - if(param == GL_FRAGMENT_DEPTH_EXT) { - if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG); - } else { - WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n"); - old_fogcoord_glDisable(GL_FOG); +static void (WINE_GLAPI *old_fogcoord_glFogf)(GLenum pname, GLfloat param); +static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) +{ + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); + + if (pname == GL_FOG_COORDINATE_SOURCE_EXT) + { + ctx->gl_fog_source = (GLint)param; + if (param == GL_FRAGMENT_DEPTH_EXT) + { + if (ctx->fog_enabled) + old_fogcoord_glEnable(GL_FOG); } - } else { - if(pname == GL_FOG_START) { - ctx->fogstart = param; - } else if(pname == GL_FOG_END) { - ctx->fogend = param; + else + { + WARN_(d3d_perf)("Fog coordinates activated, but not supported. Using slow emulation.\n"); + old_fogcoord_glDisable(GL_FOG); } + } + else + { + if (pname == GL_FOG_START) + ctx->fog_start = param; + else if (pname == GL_FOG_END) + ctx->fog_end = param; old_fogcoord_glFogf(pname, param); } } -static void (WINE_GLAPI *old_fogcoord_glFogfv) (GLenum pname, const GLfloat *param) = NULL; -static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) { - struct wined3d_context *ctx = context_get_current(); - if(pname == GL_FOG_COORDINATE_SOURCE_EXT) { - ctx->gl_fog_source = (GLint) *param; - if(*param == GL_FRAGMENT_DEPTH_EXT) { - if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG); - } else { - WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n"); +static void (WINE_GLAPI *old_fogcoord_glFogfv)(GLenum pname, const GLfloat *param); +static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) +{ + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); + + if (pname == GL_FOG_COORDINATE_SOURCE_EXT) + { + ctx->gl_fog_source = (GLint)*param; + if (*param == GL_FRAGMENT_DEPTH_EXT) + { + if (ctx->fog_enabled) + old_fogcoord_glEnable(GL_FOG); + } + else + { + WARN_(d3d_perf)("Fog coordinates activated, but not supported. Using slow emulation.\n"); old_fogcoord_glDisable(GL_FOG); } - } else { - if(pname == GL_FOG_COLOR) { - ctx->fogcolor[0] = param[0]; - ctx->fogcolor[1] = param[1]; - ctx->fogcolor[2] = param[2]; - ctx->fogcolor[3] = param[3]; - } else if(pname == GL_FOG_START) { - ctx->fogstart = *param; - } else if(pname == GL_FOG_END) { - ctx->fogend = *param; + } + else + { + if (pname == GL_FOG_COLOR) + { + ctx->fog_colour[0] = param[0]; + ctx->fog_colour[1] = param[1]; + ctx->fog_colour[2] = param[2]; + ctx->fog_colour[3] = param[3]; + } + else if (pname == GL_FOG_START) + { + ctx->fog_start = *param; + } + else if (pname == GL_FOG_END) + { + ctx->fog_end = *param; } old_fogcoord_glFogfv(pname, param); } } -static void (WINE_GLAPI *old_fogcoord_glVertex4f) (GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL; -static void (WINE_GLAPI *old_fogcoord_glColor4f) (GLfloat r, GLfloat g, GLfloat b, GLfloat a) = NULL; +static void (WINE_GLAPI *old_fogcoord_glVertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +static void (WINE_GLAPI *old_fogcoord_glColor4f)(GLfloat r, GLfloat g, GLfloat b, GLfloat a); -static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - struct wined3d_context *ctx = context_get_current(); +static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + const struct wined3d_context_gl *ctx_gl = wined3d_context_gl_get_current(); /* This can be called from draw_test_quad() and at that point there is no * wined3d_context current. */ - if (!ctx) + if (!ctx_gl) { old_fogcoord_glVertex4f(x, y, z, w); return; } - if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) { - GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]}; + + if (ctx_gl->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx_gl->fog_enabled) + { + GLfloat c[4] = {ctx_gl->colour[0], ctx_gl->colour[1], ctx_gl->colour[2], ctx_gl->colour[3]}; GLfloat i; - i = (ctx->fogend - ctx->fog_coord_value) / (ctx->fogend - ctx->fogstart); - c[0] = i * c[0] + (1.0f - i) * ctx->fogcolor[0]; - c[1] = i * c[1] + (1.0f - i) * ctx->fogcolor[1]; - c[2] = i * c[2] + (1.0f - i) * ctx->fogcolor[2]; + i = (ctx_gl->fog_end - ctx_gl->fog_coord_value) / (ctx_gl->fog_end - ctx_gl->fog_start); + c[0] = i * c[0] + (1.0f - i) * ctx_gl->fog_colour[0]; + c[1] = i * c[1] + (1.0f - i) * ctx_gl->fog_colour[1]; + c[2] = i * c[2] + (1.0f - i) * ctx_gl->fog_colour[2]; old_fogcoord_glColor4f(c[0], c[1], c[2], c[3]); old_fogcoord_glVertex4f(x, y, z, w); - } else { + } + else + { old_fogcoord_glVertex4f(x, y, z, w); } } @@ -300,20 +370,22 @@ static void WINE_GLAPI wine_glVertex3fv(const GLfloat *pos) { wine_glVertex4f(pos[0], pos[1], pos[2], 1.0f); } -static void WINE_GLAPI wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { - struct wined3d_context *ctx = context_get_current(); +static void WINE_GLAPI wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) +{ + struct wined3d_context_gl *ctx_gl = wined3d_context_gl_get_current(); /* This can be called from draw_test_quad() and at that point there is no * wined3d_context current. */ - if (!ctx) + if (!ctx_gl) { old_fogcoord_glColor4f(r, g, b, a); return; } - ctx->color[0] = r; - ctx->color[1] = g; - ctx->color[2] = b; - ctx->color[3] = a; + + ctx_gl->colour[0] = r; + ctx_gl->colour[1] = g; + ctx_gl->colour[2] = b; + ctx_gl->colour[3] = a; old_fogcoord_glColor4f(r, g, b, a); } @@ -333,11 +405,12 @@ static void WINE_GLAPI wine_glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte wine_glColor4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); } -/* In D3D the fog coord is a UBYTE, so there's no problem with using the single - * precision function - */ -static void WINE_GLAPI wine_glFogCoordfEXT(GLfloat f) { - struct wined3d_context *ctx = context_get_current(); +/* In D3D the fog coord is a UBYTE, so there's no problem with using the + * single precision function. */ +static void WINE_GLAPI wine_glFogCoordfEXT(GLfloat f) +{ + struct wined3d_context_gl *ctx = wined3d_context_gl_get_current(); + ctx->fog_coord_value = f; } static void WINE_GLAPI wine_glFogCoorddEXT(GLdouble f) { @@ -437,10 +510,10 @@ void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_ gl_info->gl_ops.gl.p_glFogf = wine_glFogf; old_fogcoord_glFogfv = gl_info->gl_ops.gl.p_glFogfv; gl_info->gl_ops.gl.p_glFogfv = wine_glFogfv; - old_fogcoord_glEnable = glEnableWINE; - glEnableWINE = wine_glEnable; - old_fogcoord_glDisable = glDisableWINE; - glDisableWINE = wine_glDisable; + old_fogcoord_glEnable = gl_info->p_glEnableWINE; + gl_info->p_glEnableWINE = wine_glEnable; + old_fogcoord_glDisable = gl_info->p_glDisableWINE; + gl_info->p_glDisableWINE = wine_glDisable; old_fogcoord_glVertex4f = gl_info->gl_ops.gl.p_glVertex4f; gl_info->gl_ops.gl.p_glVertex4f = wine_glVertex4f; diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c index 4c879f9fc5e..7785ea9d50f 100644 --- a/dll/directx/wine/wined3d/glsl_shader.c +++ b/dll/directx/wine/wined3d/glsl_shader.c @@ -71,6 +71,20 @@ resource_type_info[] = {4, 3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ }; +static const struct +{ + enum wined3d_data_type data_type; + const char *glsl_scalar_type; + const char *glsl_vector_type; +} +component_type_info[] = +{ + {WINED3D_DATA_FLOAT, "float", "vec"}, /* WINED3D_TYPE_UNKNOWN */ + {WINED3D_DATA_UINT, "uint", "uvec"}, /* WINED3D_TYPE_UINT */ + {WINED3D_DATA_INT, "int", "ivec"}, /* WINED3D_TYPE_INT */ + {WINED3D_DATA_FLOAT, "float", "vec"}, /* WINED3D_TYPE_FLOAT */ +}; + struct glsl_dst_param { char reg_name[150]; @@ -79,7 +93,6 @@ struct glsl_dst_param struct glsl_src_param { - char reg_name[150]; char param_str[200]; }; @@ -91,7 +104,6 @@ struct glsl_sample_function enum wined3d_data_type data_type; BOOL output_single_component; unsigned int offset_size; - enum wined3d_shader_resource_type emulate_lod; }; enum heap_node_op @@ -126,12 +138,21 @@ struct shader_glsl_priv unsigned char *stack; UINT next_constant_version; + BOOL consts_ubo; + GLuint ubo_vs_c; + BOOL prev_device_swvp; + struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F_SWVP]; + unsigned int max_vs_consts_f; + const struct wined3d_vertex_pipe_ops *vertex_pipe; - const struct fragment_pipeline *fragment_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; struct wine_rb_tree ffp_vertex_shaders; struct wine_rb_tree ffp_fragment_shaders; BOOL ffp_proj_control; BOOL legacy_lighting; + + GLuint ubo_modelview; + struct wined3d_matrix *modelview_buffer; }; struct glsl_vs_program @@ -139,15 +160,17 @@ struct glsl_vs_program struct list shader_entry; GLuint id; GLenum vertex_color_clamp; - GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F]; + GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F_SWVP]; GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; GLint pos_fixup_location; + GLint base_vertex_id_location; - GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS]; - GLint normal_matrix_location[MAX_VERTEX_INDEX_BLENDS]; + GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; + GLint modelview_block_index; GLint projection_matrix_location; - GLint texture_matrix_location[MAX_TEXTURES]; + GLint normal_matrix_location; + GLint texture_matrix_location[WINED3D_MAX_TEXTURES]; GLint material_ambient_location; GLint material_diffuse_location; GLint material_specular_location; @@ -168,7 +191,7 @@ struct glsl_vs_program GLint q_att; GLint cos_htheta; GLint cos_hphi; - } light_location[MAX_ACTIVE_LIGHTS]; + } light_location[WINED3D_MAX_ACTIVE_LIGHTS]; GLint pointsize_location; GLint pointsize_min_location; GLint pointsize_max_location; @@ -176,6 +199,7 @@ struct glsl_vs_program GLint pointsize_l_att_location; GLint pointsize_q_att_location; GLint clip_planes_location; + GLint vs_c_block_index; }; struct glsl_hs_program @@ -207,10 +231,10 @@ struct glsl_ps_program GLint uniform_f_locations[WINED3D_MAX_PS_CONSTS_F]; GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; - GLint bumpenv_mat_location[MAX_TEXTURES]; - GLint bumpenv_lum_scale_location[MAX_TEXTURES]; - GLint bumpenv_lum_offset_location[MAX_TEXTURES]; - GLint tss_constant_location[MAX_TEXTURES]; + GLint bumpenv_mat_location[WINED3D_MAX_TEXTURES]; + GLint bumpenv_lum_scale_location[WINED3D_MAX_TEXTURES]; + GLint bumpenv_lum_offset_location[WINED3D_MAX_TEXTURES]; + GLint tss_constant_location[WINED3D_MAX_TEXTURES]; GLint tex_factor_location; GLint specular_enable_location; GLint fog_color_location; @@ -244,7 +268,7 @@ struct glsl_shader_prog_link DWORD constant_update_mask; unsigned int constant_version; DWORD shader_controlled_clip_distances : 1; - DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */ + DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */ DWORD padding : 23; }; @@ -271,6 +295,7 @@ struct glsl_context_data struct glsl_shader_prog_link *glsl_program; GLenum vertex_color_clamp; BOOL rasterization_disabled; + BOOL ubo_bound; }; struct glsl_ps_compiled_shader @@ -339,7 +364,7 @@ struct glsl_ffp_fragment_shader struct glsl_ffp_destroy_ctx { struct shader_glsl_priv *priv; - const struct wined3d_gl_info *gl_info; + const struct wined3d_context_gl *context_gl; }; static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_context *ctx); @@ -407,15 +432,51 @@ static void shader_glsl_add_version_declaration(struct wined3d_string_buffer *bu shader_addline(buffer, "#version %u\n", shader_glsl_get_version(gl_info)); } -static void shader_glsl_append_imm_vec4(struct wined3d_string_buffer *buffer, const float *values) +unsigned int shader_glsl_full_ffp_varyings(const struct wined3d_gl_info *gl_info) +{ + /* On core profile we have to also count diffuse and specular colours and + * the fog coordinate. */ + return gl_info->limits.glsl_varyings >= (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + ? WINED3D_MAX_TEXTURES * 4 : (WINED3D_MAX_TEXTURES + 2) * 4 + 1); +} + +static void shader_glsl_append_imm_vec(struct wined3d_string_buffer *buffer, + const float *values, unsigned int size, const struct wined3d_gl_info *gl_info) { - char str[4][17]; + const int *int_values = (const int *)values; + unsigned int i; + char str[17]; + + if (!gl_info->supported[ARB_SHADER_BIT_ENCODING]) + { + if (size > 1) + shader_addline(buffer, "vec%u(", size); + + for (i = 0; i < size; ++i) + { + wined3d_ftoa(values[i], str); + shader_addline(buffer, i ? ", %s" : "%s", str); + } + + if (size > 1) + shader_addline(buffer, ")"); + + return; + } - wined3d_ftoa(values[0], str[0]); - wined3d_ftoa(values[1], str[1]); - wined3d_ftoa(values[2], str[2]); - wined3d_ftoa(values[3], str[3]); - shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]); + shader_addline(buffer, "intBitsToFloat("); + if (size > 1) + shader_addline(buffer, "ivec%u(", size); + + for (i = 0; i < size; ++i) + { + wined3d_ftoa(values[i], str); + shader_addline(buffer, i ? ", %#x /* %s */" : "%#x /* %s */", int_values[i], str); + } + + if (size > 1) + shader_addline(buffer, ")"); + shader_addline(buffer, ")"); } static void shader_glsl_append_imm_ivec(struct wined3d_string_buffer *buffer, @@ -664,10 +725,11 @@ static void shader_glsl_load_samplers_range(const struct wined3d_gl_info *gl_inf static unsigned int shader_glsl_map_tex_unit(const struct wined3d_context *context, const struct wined3d_shader_version *shader_version, unsigned int sampler_idx) { - const DWORD *tex_unit_map; + const struct wined3d_context_gl *context_gl = wined3d_context_gl_const(context); + const unsigned int *tex_unit_map; unsigned int base, count; - tex_unit_map = context_get_tex_unit_mapping(context, shader_version, &base, &count); + tex_unit_map = wined3d_context_gl_get_tex_unit_mapping(context_gl, shader_version, &base, &count); if (sampler_idx >= count) return WINED3D_UNMAPPED_STAGE; if (!tex_unit_map) @@ -690,9 +752,10 @@ static void shader_glsl_append_sampler_binding_qualifier(struct wined3d_string_b static void shader_glsl_load_samplers(const struct wined3d_context *context, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_context_gl *context_gl = wined3d_context_gl_const(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_shader_version *shader_version; - const DWORD *tex_unit_map; + const unsigned int *tex_unit_map; unsigned int base, count; const char *prefix; @@ -701,7 +764,7 @@ static void shader_glsl_load_samplers(const struct wined3d_context *context, shader_version = reg_maps ? ®_maps->shader_version : NULL; prefix = shader_glsl_get_prefix(shader_version ? shader_version->type : WINED3D_SHADER_TYPE_PIXEL); - tex_unit_map = context_get_tex_unit_mapping(context, shader_version, &base, &count); + tex_unit_map = wined3d_context_gl_get_tex_unit_mapping(context_gl, shader_version, &base, &count); shader_glsl_load_samplers_range(gl_info, priv, program_id, prefix, base, count, tex_unit_map); } @@ -756,16 +819,16 @@ static void shader_glsl_load_images(const struct wined3d_gl_info *gl_info, struc } /* Context activation is done by the caller. */ -static void shader_glsl_load_program_resources(const struct wined3d_context *context, +static void shader_glsl_load_program_resources(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - shader_glsl_init_uniform_block_bindings(context->gl_info, priv, program_id, reg_maps); - shader_glsl_load_icb(context->gl_info, priv, program_id, reg_maps); + shader_glsl_init_uniform_block_bindings(context_gl->gl_info, priv, program_id, reg_maps); + shader_glsl_load_icb(context_gl->gl_info, priv, program_id, reg_maps); /* Texture unit mapping is set up to be the same each time the shader * program is used so we can hardcode the sampler uniform values. */ - shader_glsl_load_samplers(context, priv, program_id, reg_maps); + shader_glsl_load_samplers(&context_gl->c, priv, program_id, reg_maps); } static void append_transform_feedback_varying(const char **varyings, unsigned int *varying_count, @@ -805,11 +868,14 @@ static void append_transform_feedback_skip_components(const char **varyings, } } -static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc, - struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count, - char *strings, unsigned int *strings_length, GLenum buffer_mode) +static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_string_buffer *buffer, + const char **varyings, unsigned int *varying_count, char *strings, unsigned int *strings_length, + GLenum buffer_mode, struct wined3d_shader *shader) { - unsigned int i, buffer_idx, count, length, highest_output_slot, stride; + const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; + unsigned int buffer_idx, count, length, highest_output_slot, stride; + unsigned int i, register_idx, component_idx; + BOOL have_varyings_to_record = FALSE; count = length = 0; highest_output_slot = 0; @@ -833,32 +899,37 @@ static void shader_glsl_generate_transform_feedback_varyings(const struct wined3 stride += e->component_count; - if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP) + if (!e->semantic_name) { append_transform_feedback_skip_components(varyings, &count, &strings, &length, buffer, e->component_count); continue; } - if (e->component_idx || e->component_count != 4) + if (!shader_get_stream_output_register_info(shader, e, ®ister_idx, &component_idx)) + continue; + + if (component_idx || e->component_count != 4) { if (so_desc->rasterizer_stream_idx != WINED3D_NO_RASTERIZER_STREAM) { - FIXME("Unsupported component range %u-%u.\n", e->component_idx, e->component_count); + FIXME("Unsupported component range %u-%u.\n", component_idx, e->component_count); append_transform_feedback_skip_components(varyings, &count, &strings, &length, buffer, e->component_count); continue; } string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u", - e->register_idx, e->component_idx, e->component_idx + e->component_count - 1); + register_idx, component_idx, component_idx + e->component_count - 1); append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); } else { - string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx); + string_buffer_sprintf(buffer, "shader_in_out.reg%u", register_idx); append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); } + + have_varyings_to_record = TRUE; } if (buffer_idx < so_desc->buffer_stride_count @@ -883,13 +954,15 @@ static void shader_glsl_generate_transform_feedback_varyings(const struct wined3 *varying_count = count; if (strings_length) *strings_length = length; + + return have_varyings_to_record; } -static void shader_glsl_init_transform_feedback(const struct wined3d_context *context, - struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader) +static void shader_glsl_init_transform_feedback(const struct wined3d_context_gl *context_gl, + struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader) { const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_string_buffer *buffer; unsigned int i, count, length; const char **varyings; @@ -909,7 +982,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co for (i = 0; i < so_desc->element_count; ++i) { - if (so_desc->elements[i].register_idx == WINED3D_STREAM_OUTPUT_GAP) + if (!so_desc->elements[i].semantic_name) { FIXME("ARB_transform_feedback3 is needed for stream output gaps.\n"); return; @@ -942,7 +1015,13 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co buffer = string_buffer_get(&priv->string_buffers); - shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode); + if (!shader_glsl_generate_transform_feedback_varyings(buffer, NULL, &count, NULL, &length, mode, shader)) + { + FIXME("No varyings to record, disabling transform feedback.\n"); + shader->u.gs.so_desc.element_count = 0; + string_buffer_release(&priv->string_buffers, buffer); + return; + } if (!(varyings = heap_calloc(count, sizeof(*varyings)))) { @@ -958,7 +1037,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co return; } - shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, varyings, NULL, strings, NULL, mode); + shader_glsl_generate_transform_feedback_varyings(buffer, varyings, NULL, strings, NULL, mode, shader); GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode)); checkGLcall("glTransformFeedbackVaryings"); @@ -1116,12 +1195,66 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i checkGLcall("walk_constant_heap_clamped()"); } +static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv) +{ + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); +} + /* Context activation is done by the caller. */ static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, - unsigned char *stack, unsigned int version) + unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv, BOOL device_swvp) { const struct wined3d_shader_lconst *lconst; + BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX; + + if (is_vertex_shader && priv->consts_ubo) + { + BOOL zero_sw_constants = !device_swvp && priv->prev_device_swvp; + const struct wined3d_vec4 *data; + unsigned int const_count; + unsigned max_const_used; + + if (priv->ubo_vs_c == -1) + { + ERR("UBO is not initialized.\n"); + return; + } + + bind_and_orphan_consts_ubo(gl_info, priv); + const_count = device_swvp ? priv->max_vs_consts_f : WINED3D_MAX_VS_CONSTS_F; + max_const_used = shader->reg_maps.usesrelconstF ? const_count : shader->reg_maps.constant_float_count; + if (shader->load_local_constsF || (zero_sw_constants && shader->reg_maps.usesrelconstF)) + { + data = priv->vs_c_buffer; + memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants)); + if (zero_sw_constants) + { + memset(&priv->vs_c_buffer[const_count], 0, (priv->max_vs_consts_f - WINED3D_MAX_VS_CONSTS_F) + * sizeof(*constants)); + priv->prev_device_swvp = FALSE; + } + if (shader->load_local_constsF) + { + LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) + { + priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; + } + } + } + else + { + data = constants; + } + GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) + * (zero_sw_constants ? priv->max_vs_consts_f : max_const_used), data)); + checkGLcall("glBufferSubData"); + return; + } /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */ if (shader->reg_maps.shader_version.major == 1 @@ -1215,7 +1348,7 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps { float sx, sy; } - np2fixup_constants[MAX_FRAGMENT_SAMPLERS]; + np2fixup_constants[WINED3D_MAX_FRAGMENT_SAMPLERS]; UINT fixup = ps->np2_fixup_info->active; UINT i; @@ -1237,26 +1370,55 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx)); } -static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context, +void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) +{ + struct wined3d_matrix temp; + unsigned int i, j; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j]; + + *out = temp; +} + +static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context_gl *context_gl, + const struct wined3d_state *state, struct glsl_shader_prog_link *prog) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_matrix mv; + float mat[3 * 3]; + + if (prog->vs.normal_matrix_location == -1) + return; + + get_modelview_matrix(&context_gl->c, state, 0, &mv); + compute_normal_matrix(mat, context_gl->c.d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING, &mv); + + GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat)); + checkGLcall("glUniformMatrix3fv"); +} + +static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_matrix mat; - if (tex >= MAX_TEXTURES) + if (tex >= WINED3D_MAX_TEXTURES) return; if (prog->vs.texture_matrix_location[tex] == -1) return; - get_texture_matrix(context, state, tex, &mat); + get_texture_matrix(&context_gl->c, state, tex, &mat); GL_EXTCALL(glUniformMatrix4fv(prog->vs.texture_matrix_location[tex], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); } -static void shader_glsl_ffp_vertex_material_uniform(const struct wined3d_context *context, +static void shader_glsl_ffp_vertex_material_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (state->render_states[WINED3D_RS_SPECULARENABLE]) { @@ -1275,10 +1437,10 @@ static void shader_glsl_ffp_vertex_material_uniform(const struct wined3d_context checkGLcall("setting FFP material uniforms"); } -static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_context *context, +static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_color color; wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_AMBIENT]); @@ -1286,25 +1448,12 @@ static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_con checkGLcall("glUniform3fv"); } -static void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1, - const struct wined3d_matrix *src2) -{ - struct wined3d_vec4 temp; - - temp.x = (src1->x * src2->_11) + (src1->y * src2->_21) + (src1->z * src2->_31) + (src1->w * src2->_41); - temp.y = (src1->x * src2->_12) + (src1->y * src2->_22) + (src1->z * src2->_32) + (src1->w * src2->_42); - temp.z = (src1->x * src2->_13) + (src1->y * src2->_23) + (src1->z * src2->_33) + (src1->w * src2->_43); - temp.w = (src1->x * src2->_14) + (src1->y * src2->_24) + (src1->z * src2->_34) + (src1->w * src2->_44); - - *dest = temp; -} - -static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *context, +static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int light, const struct wined3d_light_info *light_info, struct glsl_shader_prog_link *prog) { const struct wined3d_matrix *view = &state->transforms[WINED3D_TS_VIEW]; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_vec4 vec4; GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].diffuse, 1, &light_info->OriginalParms.diffuse.r)); @@ -1314,7 +1463,7 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c switch (light_info->OriginalParms.type) { case WINED3D_LIGHT_POINT: - multiply_vector_matrix(&vec4, &light_info->position, view); + wined3d_vec4_transform(&vec4, &light_info->position, view); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x)); GL_EXTCALL(glUniform1f(prog->vs.light_location[light].range, light_info->OriginalParms.range)); GL_EXTCALL(glUniform1f(prog->vs.light_location[light].c_att, light_info->OriginalParms.attenuation0)); @@ -1323,10 +1472,10 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c break; case WINED3D_LIGHT_SPOT: - multiply_vector_matrix(&vec4, &light_info->position, view); + wined3d_vec4_transform(&vec4, &light_info->position, view); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x)); - multiply_vector_matrix(&vec4, &light_info->direction, view); + wined3d_vec4_transform(&vec4, &light_info->direction, view); GL_EXTCALL(glUniform3fv(prog->vs.light_location[light].direction, 1, &vec4.x)); GL_EXTCALL(glUniform1f(prog->vs.light_location[light].range, light_info->OriginalParms.range)); @@ -1339,12 +1488,12 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c break; case WINED3D_LIGHT_DIRECTIONAL: - multiply_vector_matrix(&vec4, &light_info->direction, view); + wined3d_vec4_transform(&vec4, &light_info->direction, view); GL_EXTCALL(glUniform3fv(prog->vs.light_location[light].direction, 1, &vec4.x)); break; case WINED3D_LIGHT_PARALLELPOINT: - multiply_vector_matrix(&vec4, &light_info->position, view); + wined3d_vec4_transform(&vec4, &light_info->position, view); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x)); break; @@ -1354,21 +1503,21 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c checkGLcall("setting FFP lights uniforms"); } -static void shader_glsl_pointsize_uniform(const struct wined3d_context *context, +static void shader_glsl_pointsize_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; - float min, max; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; float size, att[3]; + float min, max; - get_pointsize_minmax(context, state, &min, &max); + get_pointsize_minmax(&context_gl->c, state, &min, &max); GL_EXTCALL(glUniform1f(prog->vs.pointsize_min_location, min)); checkGLcall("glUniform1f"); GL_EXTCALL(glUniform1f(prog->vs.pointsize_max_location, max)); checkGLcall("glUniform1f"); - get_pointsize(context, state, &size, att); + get_pointsize(&context_gl->c, state, &size, att); GL_EXTCALL(glUniform1f(prog->vs.pointsize_location, size)); checkGLcall("glUniform1f"); @@ -1380,10 +1529,10 @@ static void shader_glsl_pointsize_uniform(const struct wined3d_context *context, checkGLcall("glUniform1f"); } -static void shader_glsl_load_fog_uniform(const struct wined3d_context *context, +static void shader_glsl_load_fog_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_color color; float start, end, scale; union @@ -1396,17 +1545,17 @@ static void shader_glsl_load_fog_uniform(const struct wined3d_context *context, GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &color.r)); tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY]; GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, tmpvalue.f)); - get_fog_start_end(context, state, &start, &end); + get_fog_start_end(&context_gl->c, state, &start, &end); scale = 1.0f / (end - start); GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, end)); GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, scale)); checkGLcall("fog emulation uniforms"); } -static void shader_glsl_clip_plane_uniform(const struct wined3d_context *context, +static void shader_glsl_clip_plane_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int index, struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_matrix matrix; struct wined3d_vec4 plane; @@ -1417,7 +1566,7 @@ static void shader_glsl_clip_plane_uniform(const struct wined3d_context *context { invert_matrix(&matrix, &state->transforms[WINED3D_TS_VIEW]); transpose_matrix(&matrix, &matrix); - multiply_vector_matrix(&plane, &plane, &matrix); + wined3d_vec4_transform(&plane, &plane, &matrix); } GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &plane.x)); @@ -1434,50 +1583,70 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r)); } -/* Context activation is done by the caller. */ -static void get_normal_matrix(struct wined3d_context *context, struct wined3d_matrix *mat, float *normal) -{ - int i, j; - - if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING) - invert_matrix_3d(mat, mat); - else - invert_matrix(mat, mat); - /* Tests show that singular modelview matrices are used unchanged as normal - * matrices on D3D3 and older. There seems to be no clearly consistent - * behavior on newer D3D versions so always follow older ddraw behavior. */ - for (i = 0; i < 3; ++i) - for (j = 0; j < 3; ++j) - normal[i * 3 + j] = (&mat->_11)[j * 4 + i]; -} - /* Context activation is done by the caller (state handler). */ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { - const struct glsl_context_data *ctx_data = context->shader_backend_data; const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - const struct wined3d_gl_info *gl_info = context->gl_info; + struct glsl_context_data *ctx_data = context->shader_backend_data; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct glsl_shader_prog_link *prog = ctx_data->glsl_program; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + float position_fixup[4 * WINED3D_MAX_VIEWPORTS]; struct shader_glsl_priv *priv = shader_priv; - float position_fixup[4]; - float normal[3 * 3]; + unsigned int constant_version; DWORD update_mask; - - struct glsl_shader_prog_link *prog = ctx_data->glsl_program; - UINT constant_version; int i; - if (!prog) { - /* No GLSL program set - nothing to do. */ + /* No GLSL program set - nothing to do. */ + if (!prog) return; - } + constant_version = prog->constant_version; update_mask = context->constant_update_mask & prog->constant_update_mask; + if (!ctx_data->ubo_bound) + { + unsigned int base, count; + + wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, + &base, &count); + if (priv->consts_ubo) + { + if (priv->ubo_vs_c == -1) + { + GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); + checkGLcall("glBindBuffer (UBO)"); + GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); + } + GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base, priv->ubo_vs_c)); + checkGLcall("glBindBufferBase"); + } + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + if (priv->ubo_modelview == -1) + { + GL_EXTCALL(glGenBuffers(1, &priv->ubo_modelview)); + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); + checkGLcall("glBindBuffer (UBO)"); + GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, + sizeof(struct wined3d_matrix) * MAX_VERTEX_BLEND_UBO, NULL, GL_DYNAMIC_DRAW)); + checkGLcall("glBufferData (UBO)"); + } + GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + 1, priv->ubo_modelview)); + checkGLcall("glBindBufferBase"); + } + ctx_data->ubo_bound = TRUE; + } + if (update_mask & WINED3D_SHADER_CONST_VS_F) shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f, - prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version); + prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, + constant_version, priv, device_is_swvp(context->device)); if (update_mask & WINED3D_SHADER_CONST_VS_I) shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i, @@ -1490,17 +1659,19 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES) { for (i = 0; i < gl_info->limits.user_clip_distances; ++i) - shader_glsl_clip_plane_uniform(context, state, i, prog); + shader_glsl_clip_plane_uniform(context_gl, state, i, prog); } if (update_mask & WINED3D_SHADER_CONST_VS_POINTSIZE) - shader_glsl_pointsize_uniform(context, state, prog); + shader_glsl_pointsize_uniform(context_gl, state, prog); if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP) { - shader_get_position_fixup(context, state, position_fixup); + unsigned int fixup_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? + max(state->viewport_count, 1) : 1; + shader_get_position_fixup(context, state, fixup_count, position_fixup); if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) - GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup)); + GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, fixup_count, position_fixup)); else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN]) GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup)); else @@ -1508,37 +1679,48 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context checkGLcall("glUniform4fv"); } - if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW) + if (update_mask & WINED3D_SHADER_CONST_BASE_VERTEX_ID) { - struct wined3d_matrix mat; - - get_modelview_matrix(context, state, 0, &mat); - GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); - checkGLcall("glUniformMatrix4fv"); - - get_normal_matrix(context, &mat, normal); - GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[0], 1, FALSE, normal)); - checkGLcall("glUniformMatrix3fv"); + GL_EXTCALL(glUniform1i(prog->vs.base_vertex_id_location, state->base_vertex_index)); + checkGLcall("base vertex id"); } + if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW) + shader_glsl_ffp_vertex_normalmatrix_uniform(context_gl, state, prog); + if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) { struct wined3d_matrix mat; - for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i) + if (prog->vs.modelview_block_index != -1) { - if (prog->vs.modelview_matrix_location[i] == -1) - break; - if (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i))) - continue; + if (priv->ubo_modelview == -1) + FIXME("UBO buffer with vertex blend matrices is not initialized.\n"); + + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); + checkGLcall("glBindBuffer (UBO)"); + GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); - get_modelview_matrix(context, state, i, &mat); - GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); - checkGLcall("glUniformMatrix4fv"); + for (i = 0; i < MAX_VERTEX_BLEND_UBO; ++i) + get_modelview_matrix(context, state, i, &priv->modelview_buffer[i]); + + GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, + sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, priv->modelview_buffer)); + checkGLcall("glBufferSubData"); + } + else + { + for (i = 0; i < MAX_VERTEX_BLENDS; ++i) + { + if (prog->vs.modelview_matrix_location[i] == -1) + break; - get_normal_matrix(context, &mat, normal); - GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1, FALSE, normal)); - checkGLcall("glUniformMatrix3fv"); + get_modelview_matrix(context, state, i, &mat); + GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); + checkGLcall("glUniformMatrix4fv"); + } } } @@ -1553,12 +1735,12 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_FFP_TEXMATRIX) { - for (i = 0; i < MAX_TEXTURES; ++i) - shader_glsl_ffp_vertex_texmatrix_uniform(context, state, i, prog); + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + shader_glsl_ffp_vertex_texmatrix_uniform(context_gl, state, i, prog); } if (update_mask & WINED3D_SHADER_CONST_FFP_MATERIAL) - shader_glsl_ffp_vertex_material_uniform(context, state, prog); + shader_glsl_ffp_vertex_material_uniform(context_gl, state, prog); if (update_mask & WINED3D_SHADER_CONST_FFP_LIGHTS) { @@ -1568,12 +1750,12 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context DWORD directional_count = 0; DWORD parallel_point_count = 0; - for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) + for (i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) { - if (!state->lights[i]) + if (!state->light_state.lights[i]) continue; - switch (state->lights[i]->OriginalParms.type) + switch (state->light_state.lights[i]->OriginalParms.type) { case WINED3D_LIGHT_POINT: ++point_count; @@ -1588,7 +1770,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++parallel_point_count; break; default: - FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); + FIXME("Unhandled light type %#x.\n", state->light_state.lights[i]->OriginalParms.type); break; } } @@ -1597,10 +1779,10 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context directional_idx = spot_idx + spot_count; parallel_point_idx = directional_idx + directional_count; - shader_glsl_ffp_vertex_lightambient_uniform(context, state, prog); - for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) + shader_glsl_ffp_vertex_lightambient_uniform(context_gl, state, prog); + for (i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) { - const struct wined3d_light_info *light_info = state->lights[i]; + const struct wined3d_light_info *light_info = state->light_state.lights[i]; unsigned int idx; if (!light_info) @@ -1624,13 +1806,14 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; } - shader_glsl_ffp_vertex_light_uniform(context, state, idx, light_info, prog); + shader_glsl_ffp_vertex_light_uniform(context_gl, state, idx, light_info, prog); } } if (update_mask & WINED3D_SHADER_CONST_PS_F) shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f, - prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); + prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, + priv, FALSE); if (update_mask & WINED3D_SHADER_CONST_PS_I) shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i, @@ -1642,7 +1825,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV) { - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (prog->ps.bumpenv_mat_location[i] == -1) continue; @@ -1696,7 +1879,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context else GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f)); - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (prog->ps.tss_constant_location[i] == -1) continue; @@ -1709,11 +1892,11 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context } if (update_mask & WINED3D_SHADER_CONST_PS_FOG) - shader_glsl_load_fog_uniform(context, state, prog); + shader_glsl_load_fog_uniform(context_gl, state, prog); if (update_mask & WINED3D_SHADER_CONST_PS_ALPHA_TEST) { - float ref = state->render_states[WINED3D_RS_ALPHAREF] / 255.0f; + float ref = wined3d_alpha_ref(state); GL_EXTCALL(glUniform1f(prog->ps.alpha_test_ref_location, ref)); checkGLcall("alpha test emulation uniform"); @@ -1769,6 +1952,9 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev struct constant_heap *heap = &priv->vconst_heap; UINT i; + if (priv->consts_ubo) + return; + for (i = start; i < count + start; ++i) { update_heap_entry(heap, i, priv->next_constant_version); @@ -1874,9 +2060,9 @@ static const char *shader_glsl_interpolation_qualifiers(enum wined3d_shader_inte switch (mode) { case WINED3DSIM_CONSTANT: - return "flat"; + return "flat "; case WINED3DSIM_LINEAR_NOPERSPECTIVE: - return "noperspective"; + return "noperspective "; default: FIXME("Unhandled interpolation mode %#x.\n", mode); case WINED3DSIM_NONE: @@ -1907,7 +2093,7 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i for (i = 0; i < element_count; ++i) { mode = wined3d_extract_interpolation_mode(interpolation_mode, i); - shader_addline(buffer, "%s vec4 reg%u;\n", shader_glsl_interpolation_qualifiers(mode), i); + shader_addline(buffer, " %svec4 reg%u;\n", shader_glsl_interpolation_qualifiers(mode), i); } shader_addline(buffer, "} shader_in;\n"); } @@ -1922,6 +2108,14 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i } } +static BOOL needs_interpolation_qualifiers_for_shader_outputs(const struct wined3d_gl_info *gl_info) +{ + /* In GLSL 4.40+ it is fine to specify interpolation qualifiers only in + * fragment shaders. In older GLSL versions interpolation qualifiers must + * match between shader stages. */ + return gl_info->glsl_version < MAKEDWORD_VERSION(4, 40); +} + static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL rasterizer_setup, const DWORD *interpolation_mode) @@ -1942,7 +2136,7 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_ mode = wined3d_extract_interpolation_mode(interpolation_mode, i); interpolation_qualifiers = shader_glsl_interpolation_qualifiers(mode); } - shader_addline(buffer, "%s vec4 reg%u;\n", interpolation_qualifiers, i); + shader_addline(buffer, " %svec4 reg%u;\n", interpolation_qualifiers, i); } shader_addline(buffer, "} shader_out;\n"); } @@ -1957,6 +2151,11 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_ } } +static const char *get_fragment_output(const struct wined3d_gl_info *gl_info) +{ + return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out"; +} + static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) { switch (primitive_type) @@ -2037,11 +2236,12 @@ static void shader_glsl_declare_generic_vertex_attribute(struct wined3d_string_b const struct wined3d_gl_info *gl_info, const struct wined3d_shader_signature_element *e) { unsigned int index = e->register_idx; + enum wined3d_component_type type; if (e->sysval_semantic == WINED3D_SV_VERTEX_ID) { - shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_VertexID), 0.0, 0.0, 0.0);\n", - index); + shader_addline(buffer, "uniform int base_vertex_id;\n"); + shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_VertexID - base_vertex_id), 0.0, 0.0, 0.0);\n", index); return; } if (e->sysval_semantic == WINED3D_SV_INSTANCE_ID) @@ -2056,41 +2256,54 @@ static void shader_glsl_declare_generic_vertex_attribute(struct wined3d_string_b if (shader_glsl_use_explicit_attrib_location(gl_info)) shader_addline(buffer, "layout(location = %u) ", index); - switch (e->component_type) + type = e->component_type; + if ((unsigned int)type >= ARRAY_SIZE(component_type_info)) { - case WINED3D_TYPE_UINT: - shader_glsl_declare_typed_vertex_attribute(buffer, gl_info, "uvec", "uint", index); - break; - case WINED3D_TYPE_INT: - shader_glsl_declare_typed_vertex_attribute(buffer, gl_info, "ivec", "int", index); - break; - - default: - FIXME("Unhandled type %#x.\n", e->component_type); - /* Fall through. */ - case WINED3D_TYPE_UNKNOWN: - case WINED3D_TYPE_FLOAT: - shader_addline(buffer, "%s vec4 vs_in%u;\n", get_attribute_keyword(gl_info), index); - break; + FIXME("Unhandled type %#x.\n", type); + type = WINED3D_TYPE_FLOAT; } + if (type == WINED3D_TYPE_FLOAT || type == WINED3D_TYPE_UNKNOWN) + shader_addline(buffer, "%s vec4 vs_in%u;\n", get_attribute_keyword(gl_info), index); + else + shader_glsl_declare_typed_vertex_attribute(buffer, gl_info, + component_type_info[type].glsl_vector_type, + component_type_info[type].glsl_scalar_type, index); } /** Generate the variable & register declarations for the GLSL output target */ -static void shader_generate_glsl_declarations(const struct wined3d_context *context, +static void shader_generate_glsl_declarations(const struct wined3d_context_gl *context_gl, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) { const struct wined3d_shader_version *version = ®_maps->shader_version; + struct shader_glsl_priv *priv = context_gl->c.device->shader_priv; const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_shader_indexable_temp *idx_temp_reg; unsigned int uniform_block_base, uniform_block_count; + enum wined3d_shader_resource_type resource_type; const struct wined3d_shader_lconst *lconst; const char *prefix; unsigned int i; DWORD map; + if (wined3d_settings.strict_shader_math) + shader_addline(buffer, "#pragma optionNV(fastmath off)\n"); + + if (wined3d_settings.multiply_special == 2 && version->major < 4) + { + shader_addline(buffer, "float dot1(float v1, float v2) {return abs(v1) == 0.0 || abs(v2) == 0.0 ? 0.0 : v1 * v2;}\n"); + shader_addline(buffer, "float dot2(vec2 v1, vec2 v2) {return dot1(v1.x, v2.x) + dot1(v1.y, v2.y);}\n"); + shader_addline(buffer, "float dot3(vec3 v1, vec3 v2) {return dot2(v1.xy, v2.xy) + dot1(v1.z, v2.z);}\n"); + shader_addline(buffer, "float dot4(vec4 v1, vec4 v2) {return dot2(v1.xy, v2.xy) + dot2(v1.zw, v2.zw);}\n"); + + shader_addline(buffer, "float mul1(float v1, float v2) {return abs(v1) == 0.0 || abs(v2) == 0.0 ? 0.0 : v1 * v2;}\n"); + shader_addline(buffer, "vec2 mul2(vec2 v1, vec2 v2) {return vec2(mul1(v1.x, v2.x), mul1(v1.y, v2.y));}\n"); + shader_addline(buffer, "vec3 mul3(vec3 v1, vec3 v2) {return vec3(mul2(v1.xy, v2.xy), mul1(v1.z, v2.z));}\n"); + shader_addline(buffer, "vec4 mul4(vec4 v1, vec4 v2) {return vec4(mul2(v1.xy, v2.xy), mul2(v1.zw, v2.zw));}\n"); + } + prefix = shader_glsl_get_prefix(version->type); /* Prototype the subroutines */ @@ -2100,7 +2313,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } /* Declare the constants (aka uniforms) */ - if (shader->limits->constant_float > 0) + if (shader->limits->constant_float > 0 && priv->consts_ubo + && version->type == WINED3D_SHADER_TYPE_VERTEX) + { + shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n" + "{ \n" + " vec4 %s_c[%u];\n" + "};\n", prefix, min(shader->limits->constant_float, priv->max_vs_consts_f)); + } + else if (shader->limits->constant_float > 0) { unsigned max_constantsF; @@ -2165,11 +2386,12 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } else { - max_constantsF = gl_info->limits.glsl_vs_float_constants; + max_constantsF = reg_maps->constant_float_count; } } max_constantsF = min(shader->limits->constant_float, max_constantsF); - shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF); + if (max_constantsF) + shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF); } /* Always declare the full set of constants, the compiler can remove the @@ -2238,7 +2460,11 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } shadow_sampler = glsl_is_shadow_sampler(shader, ps_args, entry->resource_idx, entry->sampler_idx); - switch (reg_maps->resource_info[entry->resource_idx].type) + resource_type = version->type == WINED3D_SHADER_TYPE_PIXEL + ? pixelshader_get_resource_type(reg_maps, entry->resource_idx, ps_args->tex_types) + : reg_maps->resource_info[entry->resource_idx].type; + + switch (resource_type) { case WINED3D_SHADER_RESOURCE_BUFFER: sampler_type = "samplerBuffer"; @@ -2315,12 +2541,12 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont default: sampler_type = "unsupported_sampler"; - FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[entry->resource_idx].type); + FIXME("Unhandled resource type %#x.\n", resource_type); break; } if (shader_glsl_use_layout_binding_qualifier(gl_info)) - shader_glsl_append_sampler_binding_qualifier(buffer, context, version, entry->bind_idx); + shader_glsl_append_sampler_binding_qualifier(buffer, &context_gl->c, version, entry->bind_idx); shader_addline(buffer, "uniform %s%s %s_sampler%u;\n", sampler_type_prefix, sampler_type, prefix, entry->bind_idx); } @@ -2365,6 +2591,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont image_type = "imageBuffer"; break; + case WINED3D_SHADER_RESOURCE_TEXTURE_1D: + image_type = "image1D"; + break; + case WINED3D_SHADER_RESOURCE_TEXTURE_2D: image_type = "image2D"; break; @@ -2373,6 +2603,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont image_type = "image3D"; break; + case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY: + image_type = "image1DArray"; + break; + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: image_type = "image2DArray"; break; @@ -2449,15 +2683,16 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) { shader_addline(buffer, "const vec4 %s_lc%u = ", prefix, lconst->idx); - shader_glsl_append_imm_vec4(buffer, (const float *)lconst->value); + shader_glsl_append_imm_vec(buffer, (const float *)lconst->value, ARRAY_SIZE(lconst->value), gl_info); shader_addline(buffer, ";\n"); } } } /* Prototypes */ -static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, - const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src); +static void shader_glsl_add_src_param_ext(const struct wined3d_shader_context *ctx, + const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src, + enum wined3d_data_type data_type); /** Used for opcode modifiers - They multiply the result by the specified amount */ static const char * const shift_glsl_tab[] = { @@ -2529,64 +2764,66 @@ static void shader_glsl_gen_modifier(enum wined3d_shader_src_modifier src_modifi } } -static void shader_glsl_fixup_scalar_register_variable(char *register_name, +static void shader_glsl_fixup_scalar_register_variable(struct wined3d_string_buffer *register_name, const char *glsl_variable, const struct wined3d_gl_info *gl_info) { /* The ARB_shading_language_420pack extension allows swizzle operations on * scalars. */ if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) - sprintf(register_name, "%s", glsl_variable); + string_buffer_sprintf(register_name, "%s", glsl_variable); else - sprintf(register_name, "ivec2(%s, 0)", glsl_variable); + string_buffer_sprintf(register_name, "ivec2(%s, 0)", glsl_variable); } /** Writes the GLSL variable name that corresponds to the register that the * DX opcode parameter is trying to access */ static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg, - enum wined3d_data_type data_type, char *register_name, BOOL *is_color, - const struct wined3d_shader_instruction *ins) + enum wined3d_data_type data_type, struct wined3d_string_buffer *register_name, + BOOL *is_swizzled, const struct wined3d_shader_context *ctx) { /* oPos, oFog and oPts in D3D */ static const char * const hwrastout_reg_names[] = {"vs_out[10]", "vs_out[11].x", "vs_out[11].y"}; - const struct wined3d_shader *shader = ins->ctx->shader; - const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + const struct wined3d_shader *shader = ctx->shader; + const struct wined3d_shader_reg_maps *reg_maps = ctx->reg_maps; const struct wined3d_shader_version *version = ®_maps->shader_version; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; + const struct wined3d_gl_info *gl_info = ctx->gl_info; const char *prefix = shader_glsl_get_prefix(version->type); struct glsl_src_param rel_param0, rel_param1; - char imm_str[4][17]; - if (reg->idx[0].offset != ~0U && reg->idx[0].rel_addr) - shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param0); - if (reg->idx[1].offset != ~0U && reg->idx[1].rel_addr) - shader_glsl_add_src_param(ins, reg->idx[1].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param1); - *is_color = FALSE; + if (reg->idx[0].offset != ~0u && reg->idx[0].rel_addr) + shader_glsl_add_src_param_ext(ctx, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, + &rel_param0, reg->idx[0].rel_addr->reg.data_type); + if (reg->idx[1].offset != ~0u && reg->idx[1].rel_addr) + shader_glsl_add_src_param_ext(ctx, reg->idx[1].rel_addr, WINED3DSP_WRITEMASK_0, + &rel_param1, reg->idx[1].rel_addr->reg.data_type); + if (is_swizzled) + *is_swizzled = FALSE; switch (reg->type) { case WINED3DSPR_TEMP: - sprintf(register_name, "R%u", reg->idx[0].offset); + string_buffer_sprintf(register_name, "R%u", reg->idx[0].offset); break; case WINED3DSPR_INPUT: case WINED3DSPR_INCONTROLPOINT: if (version->type == WINED3D_SHADER_TYPE_VERTEX) { - struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct shader_glsl_ctx_priv *priv = ctx->backend_data; if (reg->idx[0].rel_addr) FIXME("VS3 input registers relative addressing.\n"); - if (priv->cur_vs_args->swizzle_map & (1u << reg->idx[0].offset)) - *is_color = TRUE; + if (is_swizzled && priv->cur_vs_args->swizzle_map & (1u << reg->idx[0].offset)) + *is_swizzled = TRUE; if (reg->idx[0].rel_addr) { - sprintf(register_name, "%s_in[%s + %u]", + string_buffer_sprintf(register_name, "%s_in[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset); } else { - sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset); } break; } @@ -2598,19 +2835,19 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * if (reg->idx[0].rel_addr) { if (reg->idx[1].rel_addr) - sprintf(register_name, "shader_in[%s + %u].reg[%s + %u]", + string_buffer_sprintf(register_name, "shader_in[%s + %u].reg[%s + %u]", rel_param0.param_str, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "shader_in[%s + %u].reg[%u]", + string_buffer_sprintf(register_name, "shader_in[%s + %u].reg[%u]", rel_param0.param_str, reg->idx[0].offset, reg->idx[1].offset); } else if (reg->idx[1].rel_addr) - sprintf(register_name, "shader_in[%u].reg[%s + %u]", reg->idx[0].offset, + string_buffer_sprintf(register_name, "shader_in[%u].reg[%s + %u]", reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "shader_in[%u].reg[%u]", + string_buffer_sprintf(register_name, "shader_in[%u].reg[%u]", reg->idx[0].offset, reg->idx[1].offset); break; } @@ -2630,14 +2867,14 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * if (needs_legacy_glsl_syntax(gl_info) && shader->u.ps.declared_in_count > in_count) { - sprintf(register_name, + string_buffer_sprintf(register_name, "((%s + %u) > %u ? (%s + %u) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s + %u])", rel_param0.param_str, idx, in_count - 1, rel_param0.param_str, idx, in_count, prefix, rel_param0.param_str, idx); } else { - sprintf(register_name, "%s_in[%s + %u]", prefix, rel_param0.param_str, idx); + string_buffer_sprintf(register_name, "%s_in[%s + %u]", prefix, rel_param0.param_str, idx); } } else @@ -2645,29 +2882,33 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * if (needs_legacy_glsl_syntax(gl_info) && shader->u.ps.declared_in_count > in_count) { - sprintf(register_name, "((%s) > %u ? (%s) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s])", + string_buffer_sprintf(register_name, + "((%s) > %u ? (%s) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s])", rel_param0.param_str, in_count - 1, rel_param0.param_str, in_count, prefix, rel_param0.param_str); } else { - sprintf(register_name, "%s_in[%s]", prefix, rel_param0.param_str); + string_buffer_sprintf(register_name, "%s_in[%s]", prefix, rel_param0.param_str); } } } else { - if (idx == in_count) sprintf(register_name, "gl_Color"); - else if (idx == in_count + 1) sprintf(register_name, "gl_SecondaryColor"); - else sprintf(register_name, "%s_in[%u]", prefix, idx); + if (idx == in_count) + string_buffer_sprintf(register_name, "gl_Color"); + else if (idx == in_count + 1) + string_buffer_sprintf(register_name, "gl_SecondaryColor"); + else + string_buffer_sprintf(register_name, "%s_in[%u]", prefix, idx); } } else { if (!reg->idx[0].offset) - strcpy(register_name, "ffp_varying_diffuse"); + string_buffer_sprintf(register_name, "ffp_varying_diffuse"); else - strcpy(register_name, "ffp_varying_specular"); + string_buffer_sprintf(register_name, "ffp_varying_specular"); break; } break; @@ -2678,46 +2919,48 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * if (reg->idx[0].rel_addr) { if (wined3d_settings.check_float_constants) - sprintf(register_name, "(%s + %u >= 0 && %s + %u < %u ? %s_c[%s + %u] : vec4(0.0))", + string_buffer_sprintf(register_name, + "(%s + %u >= 0 && %s + %u < %u ? %s_c[%s + %u] : vec4(0.0))", rel_param0.param_str, reg->idx[0].offset, rel_param0.param_str, reg->idx[0].offset, shader->limits->constant_float, prefix, rel_param0.param_str, reg->idx[0].offset); else if (reg->idx[0].offset) - sprintf(register_name, "%s_c[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_c[%s + %u]", + prefix, rel_param0.param_str, reg->idx[0].offset); else - sprintf(register_name, "%s_c[%s]", prefix, rel_param0.param_str); + string_buffer_sprintf(register_name, "%s_c[%s]", prefix, rel_param0.param_str); } else { if (shader_constant_is_local(shader, reg->idx[0].offset)) - sprintf(register_name, "%s_lc%u", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_lc%u", prefix, reg->idx[0].offset); else - sprintf(register_name, "%s_c[%u]", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_c[%u]", prefix, reg->idx[0].offset); } } break; case WINED3DSPR_CONSTINT: - sprintf(register_name, "%s_i[%u]", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_i[%u]", prefix, reg->idx[0].offset); break; case WINED3DSPR_CONSTBOOL: - sprintf(register_name, "%s_b[%u]", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_b[%u]", prefix, reg->idx[0].offset); break; case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */ if (version->type == WINED3D_SHADER_TYPE_PIXEL) - sprintf(register_name, "T%u", reg->idx[0].offset); + string_buffer_sprintf(register_name, "T%u", reg->idx[0].offset); else - sprintf(register_name, "A%u", reg->idx[0].offset); + string_buffer_sprintf(register_name, "A%u", reg->idx[0].offset); break; case WINED3DSPR_LOOP: - sprintf(register_name, "aL%u", ins->ctx->state->current_loop_reg - 1); + string_buffer_sprintf(register_name, "aL%u", ctx->state->current_loop_reg - 1); break; case WINED3DSPR_SAMPLER: - sprintf(register_name, "%s_sampler%u", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_sampler%u", prefix, reg->idx[0].offset); break; case WINED3DSPR_COLOROUT: @@ -2726,52 +2969,51 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * WARN("Write to render target %u, only %d supported.\n", reg->idx[0].offset, gl_info->limits.buffers); - sprintf(register_name, needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[%u]" : "ps_out%u", - reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s[%u]", get_fragment_output(gl_info), reg->idx[0].offset); break; case WINED3DSPR_RASTOUT: - sprintf(register_name, "%s", hwrastout_reg_names[reg->idx[0].offset]); + string_buffer_sprintf(register_name, "%s", hwrastout_reg_names[reg->idx[0].offset]); break; case WINED3DSPR_DEPTHOUT: case WINED3DSPR_DEPTHOUTGE: case WINED3DSPR_DEPTHOUTLE: - sprintf(register_name, "gl_FragDepth"); + string_buffer_sprintf(register_name, "gl_FragDepth"); break; case WINED3DSPR_ATTROUT: if (!reg->idx[0].offset) - sprintf(register_name, "%s_out[8]", prefix); + string_buffer_sprintf(register_name, "%s_out[8]", prefix); else - sprintf(register_name, "%s_out[9]", prefix); + string_buffer_sprintf(register_name, "%s_out[9]", prefix); break; case WINED3DSPR_TEXCRDOUT: /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */ if (reg->idx[0].rel_addr) - sprintf(register_name, "%s_out[%s + %u]", + string_buffer_sprintf(register_name, "%s_out[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset); else - sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset); break; case WINED3DSPR_MISCTYPE: if (!reg->idx[0].offset) { /* vPos */ - sprintf(register_name, "vpos"); + string_buffer_sprintf(register_name, "vpos"); } else if (reg->idx[0].offset == 1) { /* Note that gl_FrontFacing is a bool, while vFace is * a float for which the sign determines front/back */ - sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)"); + string_buffer_sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)"); } else { FIXME("Unhandled misctype register %u.\n", reg->idx[0].offset); - sprintf(register_name, "unrecognized_register"); + string_buffer_sprintf(register_name, "unrecognized_register"); } break; @@ -2781,22 +3023,22 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * case WINED3D_IMMCONST_SCALAR: switch (data_type) { + case WINED3D_DATA_UNORM: + case WINED3D_DATA_SNORM: case WINED3D_DATA_FLOAT: - if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) - sprintf(register_name, "uintBitsToFloat(%#xu)", reg->u.immconst_data[0]); - else - wined3d_ftoa(*(const float *)reg->u.immconst_data, register_name); + string_buffer_clear(register_name); + shader_glsl_append_imm_vec(register_name, (const float *)reg->u.immconst_data, 1, gl_info); break; case WINED3D_DATA_INT: - sprintf(register_name, "%#x", reg->u.immconst_data[0]); + string_buffer_sprintf(register_name, "%#x", reg->u.immconst_data[0]); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: - sprintf(register_name, "%#xu", reg->u.immconst_data[0]); + string_buffer_sprintf(register_name, "%#xu", reg->u.immconst_data[0]); break; default: - sprintf(register_name, "", data_type); + string_buffer_sprintf(register_name, "", data_type); break; } break; @@ -2804,74 +3046,65 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * case WINED3D_IMMCONST_VEC4: switch (data_type) { + case WINED3D_DATA_UNORM: + case WINED3D_DATA_SNORM: case WINED3D_DATA_FLOAT: - if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) - { - sprintf(register_name, "uintBitsToFloat(uvec4(%#xu, %#xu, %#xu, %#xu))", - reg->u.immconst_data[0], reg->u.immconst_data[1], - reg->u.immconst_data[2], reg->u.immconst_data[3]); - } - else - { - wined3d_ftoa(*(const float *)®->u.immconst_data[0], imm_str[0]); - wined3d_ftoa(*(const float *)®->u.immconst_data[1], imm_str[1]); - wined3d_ftoa(*(const float *)®->u.immconst_data[2], imm_str[2]); - wined3d_ftoa(*(const float *)®->u.immconst_data[3], imm_str[3]); - sprintf(register_name, "vec4(%s, %s, %s, %s)", - imm_str[0], imm_str[1], imm_str[2], imm_str[3]); - } + string_buffer_clear(register_name); + shader_glsl_append_imm_vec(register_name, (const float *)reg->u.immconst_data, 4, gl_info); break; case WINED3D_DATA_INT: - sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)", + string_buffer_sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)", reg->u.immconst_data[0], reg->u.immconst_data[1], reg->u.immconst_data[2], reg->u.immconst_data[3]); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: - sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)", + string_buffer_sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)", reg->u.immconst_data[0], reg->u.immconst_data[1], reg->u.immconst_data[2], reg->u.immconst_data[3]); break; default: - sprintf(register_name, "", data_type); + string_buffer_sprintf(register_name, "", data_type); break; } break; default: FIXME("Unhandled immconst type %#x\n", reg->immconst_type); - sprintf(register_name, "", reg->immconst_type); + string_buffer_sprintf(register_name, "", reg->immconst_type); } break; case WINED3DSPR_CONSTBUFFER: if (reg->idx[1].rel_addr) - sprintf(register_name, "%s_cb%u[%s + %u]", + string_buffer_sprintf(register_name, "%s_cb%u[%s + %u]", prefix, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx[0].offset, reg->idx[1].offset); + string_buffer_sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx[0].offset, reg->idx[1].offset); break; case WINED3DSPR_IMMCONSTBUFFER: if (reg->idx[0].rel_addr) - sprintf(register_name, "%s_icb[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_icb[%s + %u]", + prefix, rel_param0.param_str, reg->idx[0].offset); else - sprintf(register_name, "%s_icb[%u]", prefix, reg->idx[0].offset); + string_buffer_sprintf(register_name, "%s_icb[%u]", prefix, reg->idx[0].offset); break; case WINED3DSPR_PRIMID: if (version->type == WINED3D_SHADER_TYPE_GEOMETRY) - sprintf(register_name, "gl_PrimitiveIDIn"); + string_buffer_sprintf(register_name, "gl_PrimitiveIDIn"); else - sprintf(register_name, "gl_PrimitiveID"); + string_buffer_sprintf(register_name, "gl_PrimitiveID"); break; case WINED3DSPR_IDXTEMP: if (reg->idx[1].rel_addr) - sprintf(register_name, "X%u[%s + %u]", reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); + string_buffer_sprintf(register_name, "X%u[%s + %u]", + reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "X%u[%u]", reg->idx[0].offset, reg->idx[1].offset); + string_buffer_sprintf(register_name, "X%u[%u]", reg->idx[0].offset, reg->idx[1].offset); break; case WINED3DSPR_LOCALTHREADINDEX: @@ -2886,15 +3119,15 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_THREADID: - sprintf(register_name, "ivec3(gl_GlobalInvocationID)"); + string_buffer_sprintf(register_name, "ivec3(gl_GlobalInvocationID)"); break; case WINED3DSPR_THREADGROUPID: - sprintf(register_name, "ivec3(gl_WorkGroupID)"); + string_buffer_sprintf(register_name, "ivec3(gl_WorkGroupID)"); break; case WINED3DSPR_LOCALTHREADID: - sprintf(register_name, "ivec3(gl_LocalInvocationID)"); + string_buffer_sprintf(register_name, "ivec3(gl_LocalInvocationID)"); break; case WINED3DSPR_FORKINSTID: @@ -2904,44 +3137,52 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_TESSCOORD: - sprintf(register_name, "gl_TessCoord"); + string_buffer_sprintf(register_name, "gl_TessCoord"); break; case WINED3DSPR_OUTCONTROLPOINT: if (reg->idx[0].rel_addr) { if (reg->idx[1].rel_addr) - sprintf(register_name, "shader_out[%s + %u].reg[%s + %u]", + string_buffer_sprintf(register_name, "shader_out[%s + %u].reg[%s + %u]", rel_param0.param_str, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "shader_out[%s + %u].reg[%u]", + string_buffer_sprintf(register_name, "shader_out[%s + %u].reg[%u]", rel_param0.param_str, reg->idx[0].offset, reg->idx[1].offset); } else if (reg->idx[1].rel_addr) { - sprintf(register_name, "shader_out[%u].reg[%s + %u]", + string_buffer_sprintf(register_name, "shader_out[%u].reg[%s + %u]", reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); } else { - sprintf(register_name, "shader_out[%u].reg[%u]", + string_buffer_sprintf(register_name, "shader_out[%u].reg[%u]", reg->idx[0].offset, reg->idx[1].offset); } break; case WINED3DSPR_PATCHCONST: if (version->type == WINED3D_SHADER_TYPE_HULL) - sprintf(register_name, "hs_out[%u]", reg->idx[0].offset); + string_buffer_sprintf(register_name, "hs_out[%u]", reg->idx[0].offset); else - sprintf(register_name, "vpc[%u]", reg->idx[0].offset); + string_buffer_sprintf(register_name, "vpc[%u]", reg->idx[0].offset); + break; + + case WINED3DSPR_COVERAGE: + string_buffer_sprintf(register_name, "gl_SampleMaskIn[0]"); + break; + + case WINED3DSPR_SAMPLEMASK: + string_buffer_sprintf(register_name, "sample_mask"); break; default: FIXME("Unhandled register type %#x.\n", reg->type); - sprintf(register_name, "unrecognized_register"); + string_buffer_sprintf(register_name, "unrecognised_register"); break; } } @@ -3064,21 +3305,21 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co /* From a given parameter token, generate the corresponding GLSL string. * Also, return the actual register name and swizzle in case the * caller needs this information as well. */ -static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instruction *ins, +static void shader_glsl_add_src_param_ext(const struct wined3d_shader_context *ctx, const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src, enum wined3d_data_type data_type) { - struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct shader_glsl_ctx_priv *priv = ctx->backend_data; + struct wined3d_string_buffer *param_str = string_buffer_get(priv->string_buffers); struct wined3d_string_buffer *reg_name = string_buffer_get(priv->string_buffers); enum wined3d_data_type param_data_type; BOOL is_color = FALSE; char swizzle_str[6]; - glsl_src->reg_name[0] = '\0'; glsl_src->param_str[0] = '\0'; swizzle_str[0] = '\0'; - shader_glsl_get_register_name(&wined3d_src->reg, data_type, glsl_src->reg_name, &is_color, ins); + shader_glsl_get_register_name(&wined3d_src->reg, data_type, reg_name, &is_color, ctx); shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str); switch (wined3d_src->reg.type) @@ -3102,16 +3343,17 @@ static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instructio break; } - shader_glsl_sprintf_cast(reg_name, glsl_src->reg_name, data_type, param_data_type); - shader_glsl_gen_modifier(wined3d_src->modifiers, reg_name->buffer, swizzle_str, glsl_src->param_str); + shader_glsl_sprintf_cast(param_str, reg_name->buffer, data_type, param_data_type); + shader_glsl_gen_modifier(wined3d_src->modifiers, param_str->buffer, swizzle_str, glsl_src->param_str); string_buffer_release(priv->string_buffers, reg_name); + string_buffer_release(priv->string_buffers, param_str); } static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src) { - shader_glsl_add_src_param_ext(ins, wined3d_src, mask, glsl_src, wined3d_src->reg.data_type); + shader_glsl_add_src_param_ext(ins->ctx, wined3d_src, mask, glsl_src, wined3d_src->reg.data_type); } /* From a given parameter token, generate the corresponding GLSL string. @@ -3120,13 +3362,19 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *wined3d_dst, struct glsl_dst_param *glsl_dst) { - BOOL is_color = FALSE; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *reg_name; + size_t len; glsl_dst->mask_str[0] = '\0'; - glsl_dst->reg_name[0] = '\0'; - shader_glsl_get_register_name(&wined3d_dst->reg, wined3d_dst->reg.data_type, - glsl_dst->reg_name, &is_color, ins); + reg_name = string_buffer_get(priv->string_buffers); + shader_glsl_get_register_name(&wined3d_dst->reg, wined3d_dst->reg.data_type, reg_name, NULL, ins->ctx); + len = min(reg_name->content_size, ARRAY_SIZE(glsl_dst->reg_name) - 1); + memcpy(glsl_dst->reg_name, reg_name->buffer, len); + glsl_dst->reg_name[len] = '\0'; + string_buffer_release(priv->string_buffers, reg_name); + return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str); } @@ -3240,10 +3488,9 @@ static void shader_glsl_get_coord_size(enum wined3d_shader_resource_type resourc static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, DWORD resource_idx, DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function) { - enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; + enum wined3d_shader_resource_type resource_type; struct shader_glsl_ctx_priv *priv = ctx->backend_data; const struct wined3d_gl_info *gl_info = ctx->gl_info; - BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL @@ -3255,8 +3502,11 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context const char *base = "texture", *type_part = "", *suffix = ""; unsigned int coord_size, deriv_size; + resource_type = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL + ? pixelshader_get_resource_type(ctx->reg_maps, resource_idx, priv->cur_ps_args->tex_types) + : ctx->reg_maps->resource_info[resource_idx].type; + sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type; - sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE; if (resource_type >= ARRAY_SIZE(resource_type_info)) { @@ -3268,30 +3518,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) projected = FALSE; - if (shadow && lod) - { - switch (resource_type) - { - /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */ - case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: - sample_function->emulate_lod = resource_type; - grad = offset = TRUE; - lod = FALSE; - break; - - /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */ - case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: - sample_function->emulate_lod = resource_type; - grad = legacy_syntax = TRUE; - lod = FALSE; - break; - - default: - break; - } - } - - if (legacy_syntax) + if (needs_legacy_glsl_syntax(gl_info)) { if (shadow) base = "shadow"; @@ -3331,7 +3558,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context sample_function->offset_size = offset ? deriv_size : 0; sample_function->coord_mask = (1u << coord_size) - 1; sample_function->deriv_mask = (1u << deriv_size) - 1; - sample_function->output_single_component = shadow && !legacy_syntax; + sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info); } static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx, @@ -3440,11 +3667,13 @@ static void shader_glsl_color_correction_ext(struct wined3d_string_buffer *buffe static void shader_glsl_color_correction(const struct wined3d_shader_instruction *ins, struct color_fixup_desc fixup) { - char reg_name[256]; - BOOL is_color; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *reg_name; - shader_glsl_get_register_name(&ins->dst[0].reg, ins->dst[0].reg.data_type, reg_name, &is_color, ins); - shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name, ins->dst[0].write_mask, fixup); + reg_name = string_buffer_get(priv->string_buffers); + shader_glsl_get_register_name(&ins->dst[0].reg, ins->dst[0].reg.data_type, reg_name, NULL, ins->ctx); + shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name->buffer, ins->dst[0].write_mask, fixup); + string_buffer_release(priv->string_buffers, reg_name); } static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins, @@ -3452,7 +3681,6 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset, const char *coord_reg_fmt, ...) { - static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0}; const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; char dst_swizzle[6]; struct color_fixup_desc fixup; @@ -3521,26 +3749,6 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ break; } } - if (sample_function->emulate_lod) - { - if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias); - switch (sample_function->emulate_lod) - { - case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: - if (!dx) dx = "vec2(0.0, 0.0)"; - if (!dy) dy = "vec2(0.0, 0.0)"; - break; - - case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: - if (!dx) dx = "vec3(0.0, 0.0, 0.0)"; - if (!dy) dy = "vec3(0.0, 0.0, 0.0)"; - break; - - default: - break; - } - if (!offset) offset = &dummy_offset; - } if (dx && dy) shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy); else if (bias) @@ -3562,7 +3770,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ shader_glsl_color_correction(ins, fixup); } -static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer) +static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOOL use_viewport_index) { /* Write the final position. * @@ -3571,8 +3779,16 @@ static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer) * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow * a MAD. */ - shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n"); - shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n"); + if (use_viewport_index) + { + shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup[gl_ViewportIndex].y;\n"); + shader_addline(buffer, "gl_Position.xy += pos_fixup[gl_ViewportIndex].zw * gl_Position.ww;\n"); + } + else + { + shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n"); + shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n"); + } /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix() * in utils.c @@ -3619,7 +3835,12 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins) write_mask = shader_glsl_append_dst(buffer, ins); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); - shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str); + if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4 + && ins->handler_idx == WINED3DSIH_MUL) + shader_addline(buffer, "mul%d(%s, %s));\n", shader_glsl_get_write_mask_size(write_mask), + src0_param.param_str, src1_param.param_str); + else + shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str); } static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) @@ -3831,26 +4052,45 @@ static void shader_glsl_dot(const struct wined3d_shader_instruction *ins) struct glsl_src_param src0_param; struct glsl_src_param src1_param; DWORD dst_write_mask, src_write_mask; - unsigned int dst_size; + unsigned int dst_size, src_size; dst_write_mask = shader_glsl_append_dst(buffer, ins); dst_size = shader_glsl_get_write_mask_size(dst_write_mask); /* dp4 works on vec4, dp3 on vec3, etc. */ if (ins->handler_idx == WINED3DSIH_DP4) + { src_write_mask = WINED3DSP_WRITEMASK_ALL; + src_size = 4; + } else if (ins->handler_idx == WINED3DSIH_DP3) + { src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; + src_size = 3; + } else + { src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; - + src_size = 2; + } shader_glsl_add_src_param(ins, &ins->src[0], src_write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], src_write_mask, &src1_param); - if (dst_size > 1) { - shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str); - } else { - shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str); + if (dst_size > 1) + { + if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) + shader_addline(buffer, "vec%d(dot%d(%s, %s)));\n", dst_size, src_size, + src0_param.param_str, src1_param.param_str); + else + shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, + src0_param.param_str, src1_param.param_str); + } + else + { + if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) + shader_addline(buffer, "dot%d(%s, %s));\n", src_size, src0_param.param_str, src1_param.param_str); + else + shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str); } } @@ -3886,10 +4126,14 @@ static void shader_glsl_cut(const struct wined3d_shader_instruction *ins) static void shader_glsl_pow(const struct wined3d_shader_instruction *ins) { struct wined3d_string_buffer *buffer = ins->ctx->buffer; + static const float max_float = FLT_MAX; struct glsl_src_param src0_param; struct glsl_src_param src1_param; DWORD dst_write_mask; unsigned int dst_size; + BOOL guard_inf; + + guard_inf = wined3d_settings.multiply_special == 1 && ins->ctx->reg_maps->shader_version.major < 4; dst_write_mask = shader_glsl_append_dst(buffer, ins); dst_size = shader_glsl_get_write_mask_size(dst_write_mask); @@ -3899,13 +4143,33 @@ static void shader_glsl_pow(const struct wined3d_shader_instruction *ins) if (dst_size > 1) { - shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n", - dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str); + if (guard_inf) + { + shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : min(pow(abs(%s), %s), ", + dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str); + shader_glsl_append_imm_vec(buffer, &max_float, 1, ins->ctx->gl_info); + shader_addline(buffer, "));\n"); + } + else + { + shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n", + dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str); + } } else { - shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n", - src1_param.param_str, src0_param.param_str, src1_param.param_str); + if (guard_inf) + { + shader_addline(buffer, "%s == 0.0 ? 1.0 : min(pow(abs(%s), %s), ", + src1_param.param_str, src0_param.param_str, src1_param.param_str); + shader_glsl_append_imm_vec(buffer, &max_float, 1, ins->ctx->gl_info); + shader_addline(buffer, "));\n"); + } + else + { + shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n", + src1_param.param_str, src0_param.param_str, src1_param.param_str); + } } } @@ -4064,31 +4328,31 @@ static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) mask_size = shader_glsl_get_write_mask_size(write_mask); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param); - shader_addline(buffer, "tmp0.x = dot(%s, %s);\n", - src_param.param_str, src_param.param_str); + if (mask_size > 3) + shader_addline(buffer, "tmp0.x = dot(vec3(%s), vec3(%s));\n", + src_param.param_str, src_param.param_str); + else + shader_addline(buffer, "tmp0.x = dot(%s, %s);\n", + src_param.param_str, src_param.param_str); shader_glsl_append_dst(buffer, ins); - if (mask_size > 1) - { - shader_addline(buffer, "tmp0.x == 0.0 ? vec%u(0.0) : (%s * inversesqrt(tmp0.x)));\n", - mask_size, src_param.param_str); - } - else - { - shader_addline(buffer, "tmp0.x == 0.0 ? 0.0 : (%s * inversesqrt(tmp0.x)));\n", - src_param.param_str); - } + shader_addline(buffer, "tmp0.x == 0.0 ? %s : (%s * inversesqrt(tmp0.x)));\n", + src_param.param_str, src_param.param_str); } static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) { DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, ins->ctx->reg_maps->shader_version.minor); + static const float max_float = FLT_MAX, min_float = -FLT_MAX; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct wined3d_string_buffer *suffix; struct glsl_src_param src0_param; - const char *prefix, *suffix; unsigned int dst_size; DWORD dst_write_mask; + const char *prefix; + BOOL guard_inf; dst_write_mask = shader_glsl_append_dst(buffer, ins); dst_size = shader_glsl_get_write_mask_size(dst_write_mask); @@ -4098,41 +4362,78 @@ static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], dst_write_mask, &src0_param); + guard_inf = wined3d_settings.multiply_special == 1 && shader_version < WINED3D_SHADER_VERSION(4, 0); + suffix = string_buffer_get(priv->string_buffers); + switch (ins->handler_idx) { case WINED3DSIH_EXP: case WINED3DSIH_EXPP: prefix = "exp2("; - suffix = ")"; + string_buffer_sprintf(suffix, ")"); break; case WINED3DSIH_LOG: case WINED3DSIH_LOGP: - prefix = "log2(abs("; - suffix = "))"; + if (guard_inf) + { + prefix = "max(log2(abs("; + string_buffer_sprintf(suffix, ")), "); + shader_glsl_append_imm_vec(suffix, &min_float, 1, ins->ctx->gl_info); + shader_addline(suffix, ")"); + } + else + { + prefix = "log2(abs("; + string_buffer_sprintf(suffix, "))"); + } break; case WINED3DSIH_RCP: - prefix = "1.0 / "; - suffix = ""; + if (guard_inf) + { + prefix = "clamp(1.0 / "; + string_buffer_sprintf(suffix, ", "); + shader_glsl_append_imm_vec(suffix, &min_float, 1, ins->ctx->gl_info); + shader_addline(suffix, ", "); + shader_glsl_append_imm_vec(suffix, &max_float, 1, ins->ctx->gl_info); + shader_addline(suffix, ")"); + } + else + { + prefix = "1.0 / "; + string_buffer_clear(suffix); + } break; case WINED3DSIH_RSQ: - prefix = "inversesqrt(abs("; - suffix = "))"; + if (guard_inf) + { + prefix = "min(inversesqrt(abs("; + string_buffer_sprintf(suffix, ")), "); + shader_glsl_append_imm_vec(suffix, &max_float, 1, ins->ctx->gl_info); + shader_addline(suffix, ")"); + } + else + { + prefix = "inversesqrt(abs("; + string_buffer_sprintf(suffix, "))"); + } break; default: prefix = ""; - suffix = ""; + string_buffer_clear(suffix); FIXME("Unhandled instruction %#x.\n", ins->handler_idx); break; } if (dst_size > 1 && shader_version < WINED3D_SHADER_VERSION(4, 0)) - shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix); + shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix->buffer); else - shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix); + shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix->buffer); + + string_buffer_release(priv->string_buffers, suffix); } /** Process the WINED3DSIO_EXPP instruction in GLSL: @@ -4449,8 +4750,13 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param); - shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n", - src0_param.param_str, src1_param.param_str, src2_param.param_str); + if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) + shader_addline(ins->ctx->buffer, "mul%d(%s, %s) + %s);\n", + shader_glsl_get_write_mask_size(write_mask), src0_param.param_str, + src1_param.param_str, src2_param.param_str); + else + shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n", + src0_param.param_str, src1_param.param_str, src2_param.param_str); } /* Handles transforming all WINED3DSIO_M?x? opcodes for @@ -4711,16 +5017,15 @@ static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins) static void shader_glsl_loop(const struct wined3d_shader_instruction *ins) { struct wined3d_shader_parser_state *state = ins->ctx->state; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; struct wined3d_string_buffer *buffer = ins->ctx->buffer; const struct wined3d_shader *shader = ins->ctx->shader; const struct wined3d_shader_lconst *constant; - struct glsl_src_param src1_param; + struct wined3d_string_buffer *reg_name; const DWORD *control_values = NULL; if (ins->ctx->reg_maps->shader_version.major < 4) { - shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &src1_param); - /* Try to hardcode the loop control parameters if possible. Direct3D 9 * class hardware doesn't support real varying indexing, but Microsoft * designed this feature for Shader model 2.x+. If the loop control is @@ -4769,10 +5074,16 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins) } else { + reg_name = string_buffer_get(priv->string_buffers); + shader_glsl_get_register_name(&ins->src[1].reg, ins->src[1].reg.data_type, reg_name, NULL, ins->ctx); + shader_addline(buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z)\n{\n", - state->current_loop_depth, state->current_loop_reg, - src1_param.reg_name, state->current_loop_depth, src1_param.reg_name, - state->current_loop_depth, state->current_loop_reg, src1_param.reg_name); + state->current_loop_depth, state->current_loop_reg, reg_name->buffer, + state->current_loop_depth, reg_name->buffer, + state->current_loop_depth, state->current_loop_reg, reg_name->buffer); + + string_buffer_release(priv->string_buffers, reg_name); + } ++state->current_loop_reg; @@ -4862,20 +5173,20 @@ static void shader_glsl_default(const struct wined3d_shader_instruction *ins) shader_addline(ins->ctx->buffer, "default:\n"); } -static void shader_glsl_generate_conditional_op(const struct wined3d_shader_instruction *ins, - const char *op) +static void shader_glsl_generate_condition(const struct wined3d_shader_instruction *ins) { struct glsl_src_param src_param; const char *condition; condition = ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param); - shader_addline(ins->ctx->buffer, "if (%s(%s)) %s\n", condition, src_param.param_str, op); + shader_addline(ins->ctx->buffer, "if (%s(%s))\n", condition, src_param.param_str); } static void shader_glsl_if(const struct wined3d_shader_instruction *ins) { - shader_glsl_generate_conditional_op(ins, "{"); + shader_glsl_generate_condition(ins); + shader_addline(ins->ctx->buffer, "{\n"); } static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins) @@ -4898,10 +5209,11 @@ static void shader_glsl_else(const struct wined3d_shader_instruction *ins) static void shader_glsl_emit(const struct wined3d_shader_instruction *ins) { unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset; + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n"); if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(ins->ctx->buffer); + shader_glsl_fixup_position(ins->ctx->buffer, reg_maps->viewport_array); if (!stream) shader_addline(ins->ctx->buffer, "EmitVertex();\n"); @@ -4933,15 +5245,29 @@ static void shader_glsl_conditional_op(const struct wined3d_shader_instruction * switch (ins->handler_idx) { - case WINED3DSIH_BREAKP: op = "break;"; break; - case WINED3DSIH_CONTINUEP: op = "continue;"; break; - case WINED3DSIH_RETP: op = "return;"; break; + case WINED3DSIH_BREAKP: + op = "break;"; + break; + case WINED3DSIH_CONTINUEP: + op = "continue;"; + break; + case WINED3DSIH_RETP: + op = "return;"; + break; default: ERR("Unhandled opcode %#x.\n", ins->handler_idx); return; } - shader_glsl_generate_conditional_op(ins, op); + shader_glsl_generate_condition(ins); + if (ins->handler_idx == WINED3DSIH_RETP) + { + shader_addline(ins->ctx->buffer, "{\n"); + shader_glsl_generate_shader_epilogue(ins->ctx); + } + shader_addline(ins->ctx->buffer, " %s\n", op); + if (ins->handler_idx == WINED3DSIH_RETP) + shader_addline(ins->ctx->buffer, "}\n"); } static void shader_glsl_continue(const struct wined3d_shader_instruction *ins) @@ -4992,6 +5318,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) DWORD resource_idx; DWORD mask = 0, swizzle; const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + enum wined3d_shader_resource_type resource_type; /* 1.0-1.4: Use destination register as sampler source. * 2.0+: Use provided sampler source. */ @@ -5000,11 +5327,14 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) else resource_idx = ins->src[1].reg.idx[0].offset; + resource_type = ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL + ? pixelshader_get_resource_type(ins->ctx->reg_maps, resource_idx, priv->cur_ps_args->tex_types) + : ins->ctx->reg_maps->resource_info[resource_idx].type; + if (shader_version < WINED3D_SHADER_VERSION(1,4)) { DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) & WINED3D_PSARGS_TEXTRANSFORM_MASK; - enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type; /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ if (flags & WINED3D_PSARGS_PROJECTED && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) @@ -5043,7 +5373,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) else { if ((ins->flags & WINED3DSI_TEXLD_PROJECT) - && ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) + && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) { /* ps 2.0 texldp instruction always divides by the fourth component. */ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; @@ -5329,11 +5659,11 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "%s(%s_%s%u, %s, ", op, shader_glsl_get_prefix(version->type), resource, resource_idx, address->buffer); - shader_glsl_add_src_param_ext(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &data, data_type); + shader_glsl_add_src_param_ext(ins->ctx, &ins->src[1], WINED3DSP_WRITEMASK_0, &data, data_type); shader_addline(buffer, "%s", data.param_str); if (ins->src_count >= 3) { - shader_glsl_add_src_param_ext(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &data2, data_type); + shader_glsl_add_src_param_ext(ins->ctx, &ins->src[2], WINED3DSP_WRITEMASK_0, &data2, data_type); shader_addline(buffer, ", %s", data2.param_str); } @@ -5505,7 +5835,7 @@ static void shader_glsl_store_uav(const struct wined3d_shader_instruction *ins) coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1; shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &image_coord_param); - shader_glsl_add_src_param_ext(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &image_data_param, data_type); + shader_glsl_add_src_param_ext(ins->ctx, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &image_data_param, data_type); shader_addline(ins->ctx->buffer, "imageStore(%s_image%u, %s, %s);\n", shader_glsl_get_prefix(version->type), uav_idx, image_coord_param.param_str, image_data_param.param_str); @@ -5756,6 +6086,87 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) shader_addline(buffer, ")%s);\n", dst_swizzle); } +static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins) +{ + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + const struct wined3d_shader_dst_param *dst = ins->dst; + const struct wined3d_shader_src_param *src = ins->src; + enum wined3d_shader_resource_type resource_type; + enum wined3d_data_type dst_data_type; + unsigned int resource_idx, bind_idx; + char dst_swizzle[6]; + DWORD write_mask; + + dst_data_type = dst->reg.data_type; + if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT) + dst_data_type = WINED3D_DATA_UINT; + else if (ins->flags) + FIXME("Unhandled flags %#x.\n", ins->flags); + + write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type); + shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle); + + if (dst_data_type == WINED3D_DATA_UINT) + shader_addline(buffer, "uvec4("); + else + shader_addline(buffer, "vec4("); + + if (src->reg.type == WINED3DSPR_RASTERIZER) + { + if (gl_info->supported[ARB_SAMPLE_SHADING]) + { + shader_addline(buffer, "gl_NumSamples"); + } + else + { + FIXME("OpenGL implementation does not support ARB_sample_shading.\n"); + shader_addline(buffer, "1"); + } + } + else + { + resource_idx = src->reg.idx[0].offset; + resource_type = reg_maps->resource_info[resource_idx].type; + if (resource_type >= ARRAY_SIZE(resource_type_info)) + { + ERR("Unexpected resource type %#x.\n", resource_type); + return; + } + bind_idx = shader_glsl_find_sampler(®_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT); + + if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES]) + { + shader_addline(buffer, "textureSamples(%s_sampler%u)", + shader_glsl_get_prefix(reg_maps->shader_version.type), bind_idx); + } + else + { + FIXME("textureSamples() is not supported.\n"); + shader_addline(buffer, "1"); + } + } + + shader_addline(buffer, ", 0, 0, 0)%s);\n", dst_swizzle); +} + +static void shader_glsl_interpolate(const struct wined3d_shader_instruction *ins) +{ + const struct wined3d_shader_src_param *input = &ins->src[0]; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct glsl_src_param sample_param; + char dst_swizzle[6]; + DWORD write_mask; + + write_mask = shader_glsl_append_dst(buffer, ins); + shader_glsl_get_swizzle(input, FALSE, write_mask, dst_swizzle); + + shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &sample_param); + shader_addline(buffer, "interpolateAtSample(shader_in.reg%u, %s)%s);\n", + input->reg.idx[0].offset, sample_param.param_str, dst_swizzle); +} + static void shader_glsl_ld(const struct wined3d_shader_instruction *ins) { const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; @@ -5851,7 +6262,7 @@ static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) * comparison for array textures and cube textures. We use textureGrad*() * to implement sample_c_lz. */ -static void shader_glsl_gen_sample_c_lz(const struct wined3d_shader_instruction *ins, +static void shader_glsl_gen_sample_c_lz_emulation(const struct wined3d_shader_instruction *ins, unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, unsigned int coord_size, const char *coord_param, const char *ref_param) { @@ -5880,6 +6291,7 @@ static void shader_glsl_gen_sample_c_lz(const struct wined3d_shader_instruction static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins) { + const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; unsigned int resource_idx, sampler_idx, sampler_bind_idx; const struct wined3d_shader_resource_info *resource_info; struct glsl_src_param coord_param, compare_param; @@ -5908,10 +6320,11 @@ static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &compare_param); sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx); if (ins->handler_idx == WINED3DSIH_SAMPLE_C_LZ + && !gl_info->supported[EXT_TEXTURE_SHADOW_LOD] && (resource_info->type == WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY || resource_info->type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)) { - shader_glsl_gen_sample_c_lz(ins, sampler_bind_idx, &sample_function, + shader_glsl_gen_sample_c_lz_emulation(ins, sampler_bind_idx, &sample_function, coord_size, coord_param.param_str, compare_param.param_str); } else @@ -6378,32 +6791,40 @@ static void shader_glsl_bem(const struct wined3d_shader_instruction *ins) * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) { + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; DWORD sampler_idx = ins->dst[0].reg.idx[0].offset; struct glsl_sample_function sample_function; - struct glsl_src_param src0_param; + struct wined3d_string_buffer *reg_name; - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); + reg_name = string_buffer_get(priv->string_buffers); + shader_glsl_get_register_name(&ins->src[0].reg, ins->src[0].reg.data_type, reg_name, NULL, ins->ctx); shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, - "%s.wx", src0_param.reg_name); + "%s.wx", reg_name->buffer); shader_glsl_release_sample_function(ins->ctx, &sample_function); + + string_buffer_release(priv->string_buffers, reg_name); } /** Process the WINED3DSIO_TEXREG2GB instruction in GLSL * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) { + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; DWORD sampler_idx = ins->dst[0].reg.idx[0].offset; struct glsl_sample_function sample_function; - struct glsl_src_param src0_param; + struct wined3d_string_buffer *reg_name; - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); + reg_name = string_buffer_get(priv->string_buffers); + shader_glsl_get_register_name(&ins->src[0].reg, ins->src[0].reg.data_type, reg_name, NULL, ins->ctx); shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, - "%s.yz", src0_param.reg_name); + "%s.yz", reg_name->buffer); shader_glsl_release_sample_function(ins->ctx, &sample_function); + + string_buffer_release(priv->string_buffers, reg_name); } /** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL @@ -6429,7 +6850,8 @@ static void shader_glsl_texkill(const struct wined3d_shader_instruction *ins) { if (ins->ctx->reg_maps->shader_version.major >= 4) { - shader_glsl_generate_conditional_op(ins, "discard;"); + shader_glsl_generate_condition(ins); + shader_addline(ins->ctx->buffer, " discard;\n"); } else { @@ -6498,7 +6920,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w semantic_idx = input->semantic_idx; shader_glsl_write_mask_to_str(input->mask, reg_mask); - if (args->vp_mode == vertexshader) + if (args->vp_mode == WINED3D_VP_MODE_SHADER) { if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx) { @@ -6514,6 +6936,14 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n", input->register_idx, reg_mask); } + else if (input->sysval_semantic == WINED3D_SV_SAMPLE_INDEX) + { + if (gl_info->supported[ARB_SAMPLE_SHADING]) + shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_SampleID);\n", + input->register_idx, reg_mask); + else + FIXME("ARB_sample_shading is not supported.\n"); + } else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx) { if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT]) @@ -6522,6 +6952,14 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w else FIXME("ARB_fragment_layer_viewport is not supported.\n"); } + else if (input->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx) + { + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_ViewportIndex);\n", + input->register_idx, reg_mask); + else + FIXME("ARB_viewport_array is not supported.\n"); + } else { if (input->sysval_semantic) @@ -6537,7 +6975,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w if (args->pointsprite) shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", shader->u.ps.input_reg_map[input->register_idx]); - else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx)) + else if (args->vp_mode == WINED3D_VP_MODE_NONE && args->texcoords_initialized & (1u << semantic_idx)) shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n", shader->u.ps.input_reg_map[input->register_idx], reg_mask, needs_legacy_glsl_syntax(gl_info) @@ -6813,6 +7251,11 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n", output->register_idx, reg_mask); } + else if (output->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx) + { + shader_addline(buffer, "gl_ViewportIndex = floatBitsToInt(outputs[%u])%s;\n", + output->register_idx, reg_mask); + } else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE) { shader_glsl_generate_clip_or_cull_distances(buffer, output, reg_maps_out->clip_distance_mask); @@ -6864,13 +7307,13 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl if (ps_major < 3) { DWORD colors_written_mask[2] = {0}; - DWORD texcoords_written_mask[MAX_TEXTURES] = {0}; + DWORD texcoords_written_mask[WINED3D_MAX_TEXTURES] = {0}; if (!legacy_syntax) { declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_diffuse;\n"); declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_specular;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); + declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } @@ -6907,7 +7350,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl } else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) { - if (semantic_idx < MAX_TEXTURES) + if (semantic_idx < WINED3D_MAX_TEXTURES) { shader_addline(buffer, "%s[%u]%s = outputs[%u]%s;\n", legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", @@ -6943,15 +7386,14 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl reg_mask, reg_mask); } } - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (ps && !(ps->reg_maps.texcoord & (1u << i))) continue; if (texcoords_written_mask[i] != WINED3DSP_WRITEMASK_ALL) { - if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info) - && !texcoords_written_mask[i]) + if (!shader_glsl_full_ffp_varyings(gl_info) && !texcoords_written_mask[i]) continue; shader_glsl_write_mask_to_str(~texcoords_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask); @@ -6979,11 +7421,11 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl return ret; } -static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv, - const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc) +static void shader_glsl_generate_stream_output_setup(struct wined3d_string_buffer *buffer, + const struct wined3d_shader *shader) { - struct wined3d_string_buffer *buffer = &priv->shader_buffer; - unsigned int i; + const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; + unsigned int i, register_idx, component_idx; shader_addline(buffer, "out shader_in_out\n{\n"); for (i = 0; i < so_desc->element_count; ++i) @@ -6995,21 +7437,24 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr FIXME("Unhandled stream %u.\n", e->stream_idx); continue; } - if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP) + if (!e->semantic_name) + continue; + if (!shader_get_stream_output_register_info(shader, e, ®ister_idx, &component_idx)) continue; - if (e->component_idx || e->component_count != 4) + if (component_idx || e->component_count != 4) { if (e->component_count == 1) shader_addline(buffer, "float"); else shader_addline(buffer, "vec%u", e->component_count); + shader_addline(buffer, " reg%u_%u_%u;\n", - e->register_idx, e->component_idx, e->component_idx + e->component_count - 1); + register_idx, component_idx, component_idx + e->component_count - 1); } else { - shader_addline(buffer, "vec4 reg%u;\n", e->register_idx); + shader_addline(buffer, "vec4 reg%u;\n", register_idx); } } shader_addline(buffer, "} shader_out;\n"); @@ -7025,24 +7470,25 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr FIXME("Unhandled stream %u.\n", e->stream_idx); continue; } - if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP) + if (!e->semantic_name) + continue; + if (!shader_get_stream_output_register_info(shader, e, ®ister_idx, &component_idx)) continue; - if (e->component_idx || e->component_count != 4) + if (component_idx || e->component_count != 4) { DWORD write_mask; char str_mask[6]; - write_mask = ((1u << e->component_count) - 1) << e->component_idx; + write_mask = ((1u << e->component_count) - 1) << component_idx; shader_glsl_write_mask_to_str(write_mask, str_mask); shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n", - e->register_idx, e->component_idx, e->component_idx + e->component_count - 1, - e->register_idx, str_mask); + register_idx, component_idx, component_idx + e->component_count - 1, + register_idx, str_mask); } else { - shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n", - e->register_idx, e->register_idx); + shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n", register_idx, register_idx); } } shader_addline(buffer, "}\n"); @@ -7150,20 +7596,20 @@ static void shader_glsl_generate_patch_constant_setup(struct wined3d_string_buff static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info) { - const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; + const char *output = get_fragment_output(gl_info); - shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(srgb_const0.x));\n", output); + shader_addline(buffer, "tmp0.xyz = pow(%s[0].xyz, vec3(srgb_const0.x));\n", output); shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n"); - shader_addline(buffer, "tmp1.xyz = %s.xyz * vec3(srgb_const0.w);\n", output); - shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s.xyz, vec3(srgb_const1.x));\n", output); - shader_addline(buffer, "%s.xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); - shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", output, output); + shader_addline(buffer, "tmp1.xyz = %s[0].xyz * vec3(srgb_const0.w);\n", output); + shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s[0].xyz, vec3(srgb_const1.x));\n", output); + shader_addline(buffer, "%s[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); + shader_addline(buffer, "%s[0] = clamp(%s[0], 0.0, 1.0);\n", output, output); } static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode) { - const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; + const char *output = get_fragment_output(gl_info); switch (mode) { @@ -7188,15 +7634,13 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, return; } - shader_addline(buffer, "%s.xyz = mix(ffp_fog.color.xyz, %s.xyz, clamp(fog, 0.0, 1.0));\n", + shader_addline(buffer, "%s[0].xyz = mix(ffp_fog.color.xyz, %s[0].xyz, clamp(fog, 0.0, 1.0));\n", output, output); } static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func) { - const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; - /* alpha_func is the PASS condition, not the DISCARD condition. Instead of * flipping all the operators here, just negate the comparison below. */ static const char * const comparison_operator[] = @@ -7215,11 +7659,19 @@ static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer return; if (alpha_func != WINED3D_CMP_NEVER) - shader_addline(buffer, "if (!(%s.a %s alpha_test_ref))\n", - output, comparison_operator[alpha_func - WINED3D_CMP_NEVER]); + shader_addline(buffer, "if (!(%s[0].a %s alpha_test_ref))\n", + get_fragment_output(gl_info), comparison_operator[alpha_func - WINED3D_CMP_NEVER]); shader_addline(buffer, " discard;\n"); } +static void shader_glsl_generate_colour_key_test(struct wined3d_string_buffer *buffer, + const char *colour, const char *colour_key_low, const char *colour_key_high) +{ + shader_addline(buffer, "if (all(greaterThanEqual(%s, %s)) && all(lessThan(%s, %s)))\n", + colour, colour_key_low, colour, colour_key_high); + shader_addline(buffer, " discard;\n"); +} + static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info) { @@ -7237,6 +7689,8 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n"); if (gl_info->supported[ARB_SHADER_STORAGE_BUFFER_OBJECT]) shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n"); + if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES]) + shader_addline(buffer, "#extension GL_ARB_shader_texture_image_samples : enable\n"); if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n"); if (gl_info->supported[ARB_SHADING_LANGUAGE_PACKING]) @@ -7249,22 +7703,74 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + shader_addline(buffer, "#extension GL_ARB_viewport_array : enable\n"); if (gl_info->supported[EXT_GPU_SHADER4]) shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); if (gl_info->supported[EXT_TEXTURE_ARRAY]) shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n"); + if (gl_info->supported[EXT_TEXTURE_SHADOW_LOD]) + shader_addline(buffer, "#extension GL_EXT_texture_shadow_lod : enable\n"); +} + +static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const struct wined3d_shader *shader, + const struct ps_compile_args *args, struct wined3d_string_buffer_list *string_buffers) +{ + const struct wined3d_shader_signature *output_signature = &shader->output_signature; + struct wined3d_string_buffer *src, *assignment; + enum wined3d_data_type dst_data_type; + const char *swizzle; + unsigned int i; + + if (output_signature->element_count) + { + src = string_buffer_get(string_buffers); + assignment = string_buffer_get(string_buffers); + for (i = 0; i < output_signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *output = &output_signature->elements[i]; + + /* register_idx is set to ~0u for non-color outputs. */ + if (output->register_idx == ~0u) + continue; + if ((unsigned int)output->component_type >= ARRAY_SIZE(component_type_info)) + { + FIXME("Unhandled component type %#x.\n", output->component_type); + continue; + } + dst_data_type = component_type_info[output->component_type].data_type; + shader_addline(buffer, "color_out%u = ", output->semantic_idx); + string_buffer_sprintf(src, "ps_out[%u]", output->semantic_idx); + shader_glsl_sprintf_cast(assignment, src->buffer, dst_data_type, WINED3D_DATA_FLOAT); + swizzle = args->rt_alpha_swizzle & (1u << output->semantic_idx) ? ".argb" : ""; + shader_addline(buffer, "%s%s;\n", assignment->buffer, swizzle); + } + string_buffer_release(string_buffers, src); + string_buffer_release(string_buffers, assignment); + } + else + { + DWORD mask = shader->reg_maps.rt_mask; + + while (mask) + { + i = wined3d_bit_scan(&mask); + swizzle = args->rt_alpha_swizzle & (1u << i) ? ".argb" : ""; + shader_addline(buffer, "color_out%u = ps_out[%u]%s;\n", i, i, swizzle); + } + } } static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, - const struct ps_compile_args *args) + const struct ps_compile_args *args, struct wined3d_string_buffer_list *string_buffers) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */ if (reg_maps->shader_version.major < 2) - shader_addline(buffer, "%s = R0;\n", output); + shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info)); if (args->srgb_correction) shader_glsl_generate_srgb_write_correction(buffer, gl_info); @@ -7274,19 +7780,25 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in shader_glsl_generate_fog_code(buffer, gl_info, args->fog); shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1); + + if (reg_maps->sample_mask) + shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n"); + + if (!needs_legacy_glsl_syntax(gl_info)) + shader_glsl_generate_color_output(buffer, gl_info, shader, args, string_buffers); } /* Context activation is done by the caller. */ -static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_fragment_shader(const struct wined3d_context_gl *context_gl, struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, - const struct wined3d_shader *shader, - const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info) + const struct wined3d_shader *shader, const struct ps_compile_args *args, + struct ps_np2fixup_info *np2fixup_info) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; const struct wined3d_shader_version *version = ®_maps->shader_version; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const char *prefix = shader_glsl_get_prefix(version->type); - const struct wined3d_gl_info *gl_info = context->gl_info; - const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); + BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); unsigned int i, extra_constants_needed = 0; struct shader_glsl_ctx_priv priv_ctx; GLuint shader_id; @@ -7310,6 +7822,8 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n"); if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT]) shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n"); + if (gl_info->supported[ARB_SAMPLE_SHADING]) + shader_addline(buffer, "#extension GL_ARB_sample_shading : enable\n"); if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n"); /* The spec says that it doesn't have to be explicitly enabled, but the @@ -7318,7 +7832,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n"); /* Base Declarations */ - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + shader_generate_glsl_declarations(context_gl, buffer, shader, reg_maps, &priv_ctx); if (gl_info->supported[ARB_CONSERVATIVE_DEPTH]) { @@ -7345,10 +7859,14 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context for (i = 0; i < shader->limits->sampler; ++i) { - if (!reg_maps->resource_info[i].type || !(args->np2_fixup & (1u << i))) + enum wined3d_shader_resource_type resource_type; + + resource_type = pixelshader_get_resource_type(reg_maps, i, args->tex_types); + + if (!resource_type || !(args->np2_fixup & (1u << i))) continue; - if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) + if (resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) { FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n"); continue; @@ -7362,7 +7880,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts); } - if (version->major < 3 || args->vp_mode != vertexshader) + if (version->major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER) { shader_addline(buffer, "uniform struct\n{\n"); shader_addline(buffer, " vec4 color;\n"); @@ -7377,7 +7895,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); if (glsl_is_color_reg_read(shader, 1)) shader_addline(buffer, "vec4 ffp_varying_specular;\n"); - shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", WINED3D_MAX_TEXTURES); shader_addline(buffer, "float ffp_varying_fogcoord;\n"); } else @@ -7386,8 +7904,8 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context declare_in_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_diffuse;\n"); if (glsl_is_color_reg_read(shader, 1)) declare_in_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_specular;\n"); - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); - shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); + declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", WINED3D_MAX_TEXTURES); declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } } @@ -7396,7 +7914,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context { unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); - if (args->vp_mode == vertexshader && reg_maps->input_registers) + if (args->vp_mode == WINED3D_VP_MODE_SHADER && reg_maps->input_registers) shader_glsl_declare_shader_inputs(gl_info, buffer, in_count, shader->u.ps.interpolation_mode, version->major >= 4); shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); @@ -7422,10 +7940,10 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context if (args->srgb_correction) { shader_addline(buffer, "const vec4 srgb_const0 = "); - shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0); + shader_glsl_append_imm_vec(buffer, &wined3d_srgb_const[0].x, 4, gl_info); shader_addline(buffer, ";\n"); shader_addline(buffer, "const vec4 srgb_const1 = "); - shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1); + shader_glsl_append_imm_vec(buffer, &wined3d_srgb_const[1].x, 4, gl_info); shader_addline(buffer, ";\n"); } if (reg_maps->vpos || reg_maps->usesdsy) @@ -7439,7 +7957,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context { if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) { - if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) + if (context_gl->c.d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) shader_addline(buffer, "layout(%spixel_center_integer) in vec4 gl_FragCoord;\n", args->render_offscreen ? "" : "origin_upper_left, "); else if (!args->render_offscreen) @@ -7454,22 +7972,51 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context if (!needs_legacy_glsl_syntax(gl_info)) { + const struct wined3d_shader_signature *output_signature = &shader->output_signature; + if (args->dual_source_blend) + shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.dual_buffers * 2); + else + shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.buffers); + if (output_signature->element_count) { - for (i = 0; i < gl_info->limits.dual_buffers * 2; i++) + for (i = 0; i < output_signature->element_count; ++i) { + const struct wined3d_shader_signature_element *output = &output_signature->elements[i]; + + if (output->register_idx == ~0u) + continue; + if ((unsigned int)output->component_type >= ARRAY_SIZE(component_type_info)) + { + FIXME("Unhandled component type %#x.\n", output->component_type); + continue; + } if (shader_glsl_use_explicit_attrib_location(gl_info)) - shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2); - shader_addline(buffer, "out vec4 ps_out%u;\n", i); + { + if (args->dual_source_blend) + shader_addline(buffer, "layout(location = %u, index = %u) ", output->semantic_idx / 2, output->semantic_idx % 2); + else + shader_addline(buffer, "layout(location = %u) ", output->semantic_idx); + } + shader_addline(buffer, "out %s4 color_out%u;\n", + component_type_info[output->component_type].glsl_vector_type, output->semantic_idx); } } else { - for (i = 0; i < gl_info->limits.buffers; i++) + DWORD mask = reg_maps->rt_mask; + + while (mask) { + i = wined3d_bit_scan(&mask); if (shader_glsl_use_explicit_attrib_location(gl_info)) - shader_addline(buffer, "layout(location = %u) ", i); - shader_addline(buffer, "out vec4 ps_out%u;\n", i); + { + if (args->dual_source_blend) + shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2); + else + shader_addline(buffer, "layout(location = %u) ", i); + } + shader_addline(buffer, "out vec4 color_out%u;\n", i); } } } @@ -7482,6 +8029,9 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "void main()\n{\n"); + if (reg_maps->sample_mask) + shader_addline(buffer, "float sample_mask = uintBitsToFloat(0xffffffffu);\n"); + /* Direct3D applications expect integer vPos values, while OpenGL drivers * add approximately 0.5. This causes off-by-one problems as spotted by * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly @@ -7502,7 +8052,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context { if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) shader_addline(buffer, "vpos = gl_FragCoord;\n"); - else if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) + else if (context_gl->c.d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) shader_addline(buffer, "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n"); else @@ -7510,7 +8060,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n"); } - if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader) + if (reg_maps->shader_version.major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER) { unsigned int i; WORD map = reg_maps->texcoord; @@ -7553,7 +8103,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context /* In SM4+ the shader epilogue is generated by the "ret" instruction. */ if (reg_maps->shader_version.major < 4) - shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args); + shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args, string_buffers); shader_addline(buffer, "}\n"); @@ -7604,18 +8154,18 @@ static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_in shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n"); if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(buffer); + shader_glsl_fixup_position(buffer, FALSE); } /* Context activation is done by the caller. */ -static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_vertex_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct vs_compile_args *args) { struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; const struct wined3d_shader_version *version = ®_maps->shader_version; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_string_buffer *buffer = &priv->shader_buffer; - const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_ctx_priv priv_ctx; GLuint shader_id; unsigned int i; @@ -7631,9 +8181,11 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context shader_addline(buffer, "#extension GL_ARB_draw_instanced : enable\n"); if (shader_glsl_use_explicit_attrib_location(gl_info)) shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); + if (gl_info->supported[ARB_SHADER_VIEWPORT_LAYER_ARRAY]) + shader_addline(buffer, "#extension GL_ARB_shader_viewport_layer_array : enable\n"); /* Base Declarations */ - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + shader_generate_glsl_declarations(context_gl, buffer, shader, reg_maps, &priv_ctx); for (i = 0; i < shader->input_signature.element_count; ++i) shader_glsl_declare_generic_vertex_attribute(buffer, gl_info, &shader->input_signature.elements[i]); @@ -7656,7 +8208,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context { declare_out_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_diffuse;\n"); declare_out_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_specular;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); + declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } } @@ -7749,13 +8301,13 @@ static void shader_glsl_generate_shader_phase_invocation(struct wined3d_string_b } } -static GLuint shader_glsl_generate_hull_shader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_hull_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, const struct wined3d_shader *shader) { struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_string_buffer *buffer = &priv->shader_buffer; - const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_hull_shader *hs = &shader->u.hs; const struct wined3d_shader_phase *phase; struct shader_glsl_ctx_priv priv_ctx; @@ -7770,7 +8322,7 @@ static GLuint shader_glsl_generate_hull_shader(const struct wined3d_context *con shader_glsl_enable_extensions(buffer, gl_info); shader_addline(buffer, "#extension GL_ARB_tessellation_shader : enable\n"); - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + shader_generate_glsl_declarations(context_gl, buffer, shader, reg_maps, &priv_ctx); shader_addline(buffer, "layout(vertices = %u) out;\n", hs->output_vertex_count); @@ -7842,16 +8394,16 @@ static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_in shader_addline(buffer, "setup_ds_output(ds_out);\n"); if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) - shader_glsl_fixup_position(buffer); + shader_glsl_fixup_position(buffer, FALSE); } -static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct ds_compile_args *args) { struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_string_buffer *buffer = &priv->shader_buffer; - const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_ctx_priv priv_ctx; GLuint shader_id; @@ -7864,7 +8416,7 @@ static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *c shader_glsl_enable_extensions(buffer, gl_info); shader_addline(buffer, "#extension GL_ARB_tessellation_shader : enable\n"); - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + shader_generate_glsl_declarations(context_gl, buffer, shader, reg_maps, &priv_ctx); shader_addline(buffer, "layout("); switch (shader->u.ds.tessellator_domain) @@ -7939,14 +8491,18 @@ static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *c } /* Context activation is done by the caller. */ -static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct gs_compile_args *args) { struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_string_buffer *buffer = &priv->shader_buffer; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_shader_signature_element *output; + enum wined3d_primitive_type primitive_type; struct shader_glsl_ctx_priv priv_ctx; + unsigned int max_vertices; + unsigned int i, j; GLuint shader_id; memset(&priv_ctx, 0, sizeof(priv_ctx)); @@ -7956,31 +8512,77 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context shader_glsl_enable_extensions(buffer, gl_info); - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + shader_generate_glsl_declarations(context_gl, buffer, shader, reg_maps, &priv_ctx); - shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type)); + primitive_type = shader->u.gs.input_type ? shader->u.gs.input_type : args->primitive_type; + shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(primitive_type)); if (shader->u.gs.instance_count > 1) shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count); shader_addline(buffer, ") in;\n"); + + primitive_type = shader->u.gs.output_type ? shader->u.gs.output_type : args->primitive_type; + if (!(max_vertices = shader->u.gs.vertices_out)) + { + switch (args->primitive_type) + { + case WINED3D_PT_POINTLIST: + max_vertices = 1; + break; + case WINED3D_PT_LINELIST: + max_vertices = 2; + break; + case WINED3D_PT_TRIANGLELIST: + max_vertices = 3; + break; + default: + FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(args->primitive_type)); + break; + } + } shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n", - glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out); + glsl_primitive_type_from_d3d(primitive_type), max_vertices); shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input); if (!gl_info->supported[ARB_CLIP_CONTROL]) - shader_addline(buffer, "uniform vec4 pos_fixup;\n"); + { + shader_addline(buffer, "uniform vec4 pos_fixup"); + if (reg_maps->viewport_array) + shader_addline(buffer, "[%u]", WINED3D_MAX_VIEWPORTS); + shader_addline(buffer, ";\n"); + } if (is_rasterization_disabled(shader)) { - shader_glsl_generate_stream_output_setup(priv, shader, &shader->u.gs.so_desc); + shader_glsl_generate_stream_output_setup(buffer, shader); } else { shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info, TRUE, args->interpolation_mode); } + shader_addline(buffer, "void main()\n{\n"); - if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) - return 0; + if (shader->function) + { + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; + } + else + { + for (i = 0; i < max_vertices; ++i) + { + for (j = 0; j < shader->output_signature.element_count; ++j) + { + output = &shader->output_signature.elements[j]; + shader_addline(buffer, "gs_out[%u] = shader_in[%u].reg[%u];\n", + output->register_idx, i, output->register_idx); + } + shader_addline(buffer, "setup_gs_output(gs_out);\n"); + if (!gl_info->supported[ARB_CLIP_CONTROL]) + shader_glsl_fixup_position(buffer, FALSE); + shader_addline(buffer, "EmitVertex();\n"); + } + } shader_addline(buffer, "}\n"); shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER)); @@ -8000,7 +8602,7 @@ static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_con switch (shader->reg_maps.shader_version.type) { case WINED3D_SHADER_TYPE_PIXEL: - shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args); + shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args, priv->string_buffers); break; case WINED3D_SHADER_TYPE_VERTEX: shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, priv->cur_vs_args); @@ -8018,13 +8620,13 @@ static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_con } /* Context activation is done by the caller. */ -static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context *context, +static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context_gl *context_gl, struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, const struct wined3d_shader *shader) { const struct wined3d_shader_thread_group_size *thread_group_size = &shader->u.cs.thread_group_size; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct shader_glsl_ctx_priv priv_ctx; GLuint shader_id; unsigned int i; @@ -8037,7 +8639,7 @@ static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context * shader_glsl_enable_extensions(buffer, gl_info); shader_addline(buffer, "#extension GL_ARB_compute_shader : enable\n"); - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + shader_generate_glsl_declarations(context_gl, buffer, shader, reg_maps, &priv_ctx); for (i = 0; i < reg_maps->tgsm_count; ++i) { @@ -8059,7 +8661,7 @@ static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context * return shader_id; } -static GLuint find_glsl_pshader(const struct wined3d_context *context, +static GLuint find_glsl_fragment_shader(const struct wined3d_context_gl *context_gl, struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, struct wined3d_shader *shader, const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info) @@ -8125,10 +8727,8 @@ static GLuint find_glsl_pshader(const struct wined3d_context *context, memset(np2fixup, 0, sizeof(*np2fixup)); *np2fixup_info = args->np2_fixup ? np2fixup : NULL; - pixelshader_update_resource_types(shader, args->tex_types); - string_buffer_clear(buffer); - ret = shader_glsl_generate_pshader(context, buffer, string_buffers, shader, args, np2fixup); + ret = shader_glsl_generate_fragment_shader(context_gl, buffer, string_buffers, shader, args, np2fixup); gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; @@ -8137,8 +8737,10 @@ static GLuint find_glsl_pshader(const struct wined3d_context *context, static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new, const DWORD use_map) { - if((stored->swizzle_map & use_map) != new->swizzle_map) return FALSE; - if((stored->clip_enabled) != new->clip_enabled) return FALSE; + if ((stored->swizzle_map & use_map) != new->swizzle_map) + return FALSE; + if ((stored->clip_enabled) != new->clip_enabled) + return FALSE; if (stored->point_size != new->point_size) return FALSE; if (stored->per_vertex_point_size != new->per_vertex_point_size) @@ -8149,17 +8751,18 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str return FALSE; if (stored->next_shader_input_count != new->next_shader_input_count) return FALSE; - return stored->fog_src == new->fog_src; + if (stored->fog_src != new->fog_src) + return FALSE; + return !memcmp(stored->interpolation_mode, new->interpolation_mode, sizeof(new->interpolation_mode)); } -static GLuint find_glsl_vshader(const struct wined3d_context *context, struct shader_glsl_priv *priv, - struct wined3d_shader *shader, const struct vs_compile_args *args) +static GLuint find_glsl_vertex_shader(const struct wined3d_context_gl *context_gl, + struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct vs_compile_args *args) { - UINT i; - DWORD new_size; - DWORD use_map = context->stream_info.use_map; struct glsl_vs_compiled_shader *gl_shaders, *new_array; + uint32_t use_map = context_gl->c.stream_info.use_map; struct glsl_shader_private *shader_data; + unsigned int i, new_size; GLuint ret; if (!shader->backend_data) @@ -8210,13 +8813,13 @@ static GLuint find_glsl_vshader(const struct wined3d_context *context, struct sh gl_shaders[shader_data->num_gl_shaders].args = *args; string_buffer_clear(&priv->shader_buffer); - ret = shader_glsl_generate_vshader(context, priv, shader, args); + ret = shader_glsl_generate_vertex_shader(context_gl, priv, shader, args); gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; } -static GLuint find_glsl_hull_shader(const struct wined3d_context *context, +static GLuint find_glsl_hull_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, struct wined3d_shader *shader) { struct glsl_hs_compiled_shader *gl_shaders, *new_array; @@ -8255,13 +8858,13 @@ static GLuint find_glsl_hull_shader(const struct wined3d_context *context, gl_shaders = new_array; string_buffer_clear(&priv->shader_buffer); - ret = shader_glsl_generate_hull_shader(context, priv, shader); + ret = shader_glsl_generate_hull_shader(context_gl, priv, shader); gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; } -static GLuint find_glsl_domain_shader(const struct wined3d_context *context, +static GLuint find_glsl_domain_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct ds_compile_args *args) { struct glsl_ds_compiled_shader *gl_shaders, *new_array; @@ -8309,14 +8912,14 @@ static GLuint find_glsl_domain_shader(const struct wined3d_context *context, gl_shaders = new_array; string_buffer_clear(&priv->shader_buffer); - ret = shader_glsl_generate_domain_shader(context, priv, shader, args); + ret = shader_glsl_generate_domain_shader(context_gl, priv, shader, args); gl_shaders[shader_data->num_gl_shaders].args = *args; gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; } -static GLuint find_glsl_geometry_shader(const struct wined3d_context *context, +static GLuint find_glsl_geometry_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct gs_compile_args *args) { struct glsl_gs_compiled_shader *gl_shaders, *new_array; @@ -8364,7 +8967,7 @@ static GLuint find_glsl_geometry_shader(const struct wined3d_context *context, gl_shaders = new_array; string_buffer_clear(&priv->shader_buffer); - ret = shader_glsl_generate_geometry_shader(context, priv, shader, args); + ret = shader_glsl_generate_geometry_shader(context_gl, priv, shader, args); gl_shaders[shader_data->num_gl_shaders].args = *args; gl_shaders[shader_data->num_gl_shaders++].id = ret; @@ -8388,7 +8991,7 @@ static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, c } static void shader_glsl_ffp_vertex_lighting_footer(struct wined3d_string_buffer *buffer, - const struct wined3d_ffp_vs_settings *settings, unsigned int idx) + const struct wined3d_ffp_vs_settings *settings, unsigned int idx, BOOL legacy_lighting) { shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)" " * ffp_light[%u].diffuse.xyz * att;\n", idx); @@ -8396,8 +8999,9 @@ static void shader_glsl_ffp_vertex_lighting_footer(struct wined3d_string_buffer shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); else shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); - shader_addline(buffer, "if (dot(dir, normal) > 0.0 && t > 0.0) specular +=" - " pow(t, ffp_material.shininess) * ffp_light[%u].specular * att;\n", idx); + shader_addline(buffer, "if (dot(dir, normal) > 0.0 && t > 0.0%s) specular +=" + " pow(t, ffp_material.shininess) * ffp_light[%u].specular * att;\n", + legacy_lighting ? " && ffp_material.shininess > 0.0" : "", idx); } static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer, @@ -8452,7 +9056,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer continue; } shader_addline(buffer, "dir = normalize(dir);\n"); - shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); shader_addline(buffer, "}\n"); } @@ -8493,7 +9097,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer shader_addline(buffer, "}\n"); continue; } - shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); shader_addline(buffer, "}\n"); } @@ -8504,7 +9108,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer continue; shader_addline(buffer, "att = 1.0;\n"); shader_addline(buffer, "dir = normalize(ffp_light[%u].direction.xyz);\n", idx); - shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); } for (i = 0; i < settings->parallel_point_light_count; ++i, ++idx) @@ -8514,7 +9118,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer continue; shader_addline(buffer, "att = 1.0;\n"); shader_addline(buffer, "dir = normalize(ffp_light[%u].position.xyz);\n", idx); - shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); } shader_addline(buffer, "ffp_varying_diffuse.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n", @@ -8548,11 +9152,13 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr BOOL legacy_lighting = priv->legacy_lighting; GLuint shader_obj; unsigned int i; - char var[64]; string_buffer_clear(buffer); shader_glsl_add_version_declaration(buffer, gl_info); + TRACE("settings->vb_indices %#x.\n", settings->vb_indices); + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + shader_addline(buffer,"#extension GL_ARB_uniform_buffer_object : enable\n"); if (shader_glsl_use_explicit_attrib_location(gl_info)) shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); @@ -8567,10 +9173,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } shader_addline(buffer, "\n"); - shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS); - shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS); + if (settings->vb_indices && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + shader_addline(buffer,"layout(std140) uniform ffp_modelview_ubo\n\ + { \n\ + mat4 ffp_modelview_matrix[%u];\n\ + };\n", MAX_VERTEX_BLEND_UBO); + } + else + { + shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", settings->vertexblends + 1); + } + shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); - shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES); + shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); + shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", WINED3D_MAX_TEXTURES); shader_addline(buffer, "uniform struct\n{\n"); shader_addline(buffer, " vec4 emissive;\n"); @@ -8594,7 +9211,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, " float q_att;\n"); shader_addline(buffer, " float cos_htheta;\n"); shader_addline(buffer, " float cos_hphi;\n"); - shader_addline(buffer, "} ffp_light[%u];\n", MAX_ACTIVE_LIGHTS); + shader_addline(buffer, "} ffp_light[%u];\n", WINED3D_MAX_ACTIVE_LIGHTS); if (settings->point_size) { @@ -8612,7 +9229,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr { shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); shader_addline(buffer, "vec4 ffp_varying_specular;\n"); - shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); shader_addline(buffer, "float ffp_varying_fogcoord;\n"); } else @@ -8622,13 +9239,15 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n"); declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); + declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } shader_addline(buffer, "\nvoid main()\n{\n"); shader_addline(buffer, "float m;\n"); shader_addline(buffer, "vec3 r;\n"); + if (settings->vb_indices) + shader_addline(buffer, "int ind;\n"); for (i = 0; i < ARRAY_SIZE(attrib_info); ++i) { @@ -8636,7 +9255,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, "%s %s = vs_in%u%s;\n", attrib_info[i].type, attrib_info[i].name, i, settings->swizzle_map & (1u << i) ? ".zyxw" : ""); } - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { unsigned int coord_idx = settings->texgen[i] & 0x0000ffff; if ((settings->texgen[i] & 0xffff0000) == WINED3DTSS_TCI_PASSTHRU @@ -8654,21 +9273,24 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } else { - if (!settings->sw_blending) - { - for (i = 0; i < settings->vertexblends; ++i) - shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); + for (i = 0; i < settings->vertexblends; ++i) + shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); - shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); + shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); + if (settings->vb_indices) + { for (i = 0; i < settings->vertexblends + 1; ++i) { - sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i); - shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var); + shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); + shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " + "(ffp_modelview_matrix[ind] * ffp_attrib_position);\n", i); } } else { - shader_addline(buffer, "vec4 ec_pos = ffp_attrib_position;\n"); + for (i = 0; i < settings->vertexblends + 1; ++i) + shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " + "(ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); } shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n"); @@ -8686,17 +9308,26 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, "vec3 normal = vec3(0.0);\n"); if (settings->normal) { - if (!settings->sw_blending) + if (!settings->vertexblends) { - for (i = 0; i < settings->vertexblends + 1; ++i) - { - sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i); - shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var); - } + shader_addline(buffer, "normal = ffp_normal_matrix * ffp_attrib_normal;\n"); } else { - shader_addline(buffer, "normal = ffp_attrib_normal;\n"); + for (i = 0; i < settings->vertexblends + 1; ++i) + { + if (settings->vb_indices) + { + shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); + shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " + "(mat3(ffp_modelview_matrix[ind]) * ffp_attrib_normal);\n", i); + } + else + { + shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " + "(mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); + } + } } if (settings->normalize) @@ -8715,7 +9346,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, "ffp_varying_specular = clamp(ffp_varying_specular, 0.0, 1.0);\n"); } - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { BOOL output_legacy_texcoord = legacy_syntax; @@ -8725,7 +9356,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr if (settings->texcoords & (1u << i)) shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ffp_attrib_texcoord%u;\n", i, i, i); - else if (gl_info->limits.glsl_varyings >= wined3d_max_compat_varyings(gl_info)) + else if (shader_glsl_full_ffp_varyings(gl_info)) shader_addline(buffer, "ffp_varying_texcoord[%u] = vec4(0.0);\n", i); else output_legacy_texcoord = FALSE; @@ -8910,7 +9541,7 @@ static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_string_buf } static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color, - BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) + BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) { const char *dstmask, *dstreg, *arg0, *arg1, *arg2; @@ -8921,10 +9552,7 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un else dstmask = ".w"; - if (dst == tempreg) - dstreg = "temp_reg"; - else - dstreg = "ret"; + dstreg = tmp_dst ? "temp_reg" : "ret"; arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0); arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1); @@ -9060,14 +9688,13 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un /* Context activation is done by the caller. */ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv, - const struct ffp_frag_settings *settings, const struct wined3d_context *context) + const struct ffp_frag_settings *settings, const struct wined3d_context_gl *context_gl) { - const char *output = needs_legacy_glsl_syntax(context->gl_info) ? "gl_FragData[0]" : "ps_out0"; struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers); enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1; struct wined3d_string_buffer *buffer = &priv->shader_buffer; BYTE lum_map = 0, bump_map = 0, tex_map = 0, tss_const_map = 0; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); BOOL tempreg_used = FALSE, tfactor_used = FALSE; UINT lowest_disabled_stage; @@ -9078,7 +9705,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * string_buffer_clear(buffer); /* Find out which textures are read */ - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (settings->op[stage].cop == WINED3D_TOP_DISABLE) break; @@ -9094,7 +9721,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * tfactor_used = TRUE; if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; - if (settings->op[stage].dst == tempreg) + if (settings->op[stage].tmp_dst) tempreg_used = TRUE; if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT) tss_const_map |= 1u << stage; @@ -9149,9 +9776,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (!needs_legacy_glsl_syntax(gl_info)) { + shader_addline(buffer, "vec4 ps_out[1];\n"); if (shader_glsl_use_explicit_attrib_location(gl_info)) shader_addline(buffer, "layout(location = 0) "); - shader_addline(buffer, "out vec4 ps_out0;\n"); + shader_addline(buffer, "out vec4 color_out0;\n"); } shader_addline(buffer, "vec4 tmp0, tmp1;\n"); @@ -9160,7 +9788,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "vec4 temp_reg = vec4(0.0);\n"); shader_addline(buffer, "vec4 arg0, arg1, arg2;\n"); - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { const char *sampler_type; @@ -9195,7 +9823,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (sampler_type) { if (shader_glsl_use_layout_binding_qualifier(gl_info)) - shader_glsl_append_sampler_binding_qualifier(buffer, context, NULL, stage); + shader_glsl_append_sampler_binding_qualifier(buffer, &context_gl->c, NULL, stage); shader_addline(buffer, "uniform sampler%s ps_sampler%u;\n", sampler_type, stage); } @@ -9219,10 +9847,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (settings->sRGB_write) { shader_addline(buffer, "const vec4 srgb_const0 = "); - shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0); + shader_glsl_append_imm_vec(buffer, &wined3d_srgb_const[0].x, 4, gl_info); shader_addline(buffer, ";\n"); shader_addline(buffer, "const vec4 srgb_const1 = "); - shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1); + shader_glsl_append_imm_vec(buffer, &wined3d_srgb_const[1].x, 4, gl_info); shader_addline(buffer, ";\n"); } @@ -9240,16 +9868,16 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * { shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); shader_addline(buffer, "vec4 ffp_varying_specular;\n"); - shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); - shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", WINED3D_MAX_TEXTURES); shader_addline(buffer, "float ffp_varying_fogcoord;\n"); } else { declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n"); declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n"); - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); - shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); + declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", WINED3D_MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", WINED3D_MAX_TEXTURES); declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } @@ -9261,7 +9889,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "ffp_varying_specular = gl_SecondaryColor;\n"); } - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { if (tex_map & (1u << stage)) { @@ -9282,7 +9910,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "if (any(lessThan(ffp_texcoord[7], vec4(0.0)))) discard;\n"); /* Generate texture sampling instructions */ - for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage) { const char *texture_function, *coord_mask; BOOL proj; @@ -9290,12 +9918,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (!(tex_map & (1u << stage))) continue; - if (settings->op[stage].projected == proj_none) + if (settings->op[stage].projected == WINED3D_PROJECTION_NONE) { proj = FALSE; } - else if (settings->op[stage].projected == proj_count4 - || settings->op[stage].projected == proj_count3) + else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4 + || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) { proj = TRUE; } @@ -9311,65 +9939,34 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * switch (settings->op[stage].tex_type) { case WINED3D_GL_RES_TYPE_TEX_1D: - if (proj) - { - texture_function = "texture1DProj"; - coord_mask = "xw"; - } - else - { - texture_function = "texture1D"; - coord_mask = "x"; - } + texture_function = "texture1D"; + coord_mask = "x"; break; case WINED3D_GL_RES_TYPE_TEX_2D: - if (proj) - { - texture_function = "texture2DProj"; - coord_mask = "xyw"; - } - else - { - texture_function = "texture2D"; - coord_mask = "xy"; - } + texture_function = "texture2D"; + coord_mask = "xy"; break; case WINED3D_GL_RES_TYPE_TEX_3D: - if (proj) - { - texture_function = "texture3DProj"; - coord_mask = "xyzw"; - } - else - { - texture_function = "texture3D"; - coord_mask = "xyz"; - } + texture_function = "texture3D"; + coord_mask = "xyz"; break; case WINED3D_GL_RES_TYPE_TEX_CUBE: texture_function = "textureCube"; coord_mask = "xyz"; break; case WINED3D_GL_RES_TYPE_TEX_RECT: - if (proj) - { - texture_function = "texture2DRectProj"; - coord_mask = "xyw"; - } - else - { - texture_function = "texture2DRect"; - coord_mask = "xy"; - } + texture_function = "texture2DRect"; + coord_mask = "xy"; break; default: FIXME("Unhandled texture type %#x.\n", settings->op[stage].tex_type); texture_function = ""; coord_mask = "xyzw"; + proj = FALSE; break; } if (!legacy_syntax) - texture_function = proj ? "textureProj" : "texture"; + texture_function = "texture"; if (stage > 0 && (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP @@ -9378,12 +9975,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1); /* With projective textures, texbem only divides the static - * texture coord, not the displacement, so multiply the + * texture coordinate, not the displacement, so multiply the * displacement with the dividing parameter before passing it to * TXP. */ - if (settings->op[stage].projected != proj_none) + if (settings->op[stage].projected != WINED3D_PROJECTION_NONE) { - if (settings->op[stage].projected == proj_count4) + if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4) { shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n", stage, stage); @@ -9401,22 +9998,22 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "ret = ffp_texcoord[%u] + ret.xyxy;\n", stage); } - shader_addline(buffer, "tex%u = %s(ps_sampler%u, ret.%s);\n", - stage, texture_function, stage, coord_mask); + shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ret.%s%s);\n", + stage, texture_function, proj ? "Proj" : "", stage, coord_mask, proj ? "w" : ""); if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n", stage, stage - 1, stage - 1, stage - 1); } - else if (settings->op[stage].projected == proj_count3) + else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3) { - shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n", - stage, texture_function, stage, stage); + shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ffp_texcoord[%u].xyz);\n", + stage, texture_function, proj ? "Proj" : "", stage, stage); } else { - shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].%s);\n", - stage, texture_function, stage, stage, coord_mask); + shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ffp_texcoord[%u].%s%s);\n", + stage, texture_function, proj ? "Proj" : "", stage, stage, coord_mask, proj ? "w" : ""); } string_buffer_sprintf(tex_reg_name, "tex%u", stage); @@ -9425,15 +10022,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * } if (settings->color_key_enabled) - { - shader_addline(buffer, "if (all(greaterThanEqual(tex0, color_key[0])) && all(lessThan(tex0, color_key[1])))\n"); - shader_addline(buffer, " discard;\n"); - } + shader_glsl_generate_colour_key_test(buffer, "tex0", "color_key[0]", "color_key[1]"); shader_addline(buffer, "ret = ffp_varying_diffuse;\n"); /* Generate the main shader */ - for (stage = 0; stage < MAX_TEXTURES; ++stage) + for (stage = 0; stage < WINED3D_MAX_TEXTURES; ++stage) { BOOL op_equal; @@ -9460,29 +10054,30 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * if (settings->op[stage].aop == WINED3D_TOP_DISABLE) { - shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst, + shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (op_equal) { - shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst, + shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE) { - shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst, + shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); - shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst, + shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst, settings->op[stage].aop, settings->op[stage].aarg0, settings->op[stage].aarg1, settings->op[stage].aarg2); } } - shader_addline(buffer, "%s = ffp_varying_specular * specular_enable + ret;\n", output); + shader_addline(buffer, "%s[0] = ffp_varying_specular * specular_enable + ret;\n", + get_fragment_output(gl_info)); if (settings->sRGB_write) shader_glsl_generate_srgb_write_correction(buffer, gl_info); @@ -9490,6 +10085,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_glsl_generate_fog_code(buffer, gl_info, settings->fog); shader_glsl_generate_alpha_test(buffer, gl_info, alpha_test_func); + if (!needs_legacy_glsl_syntax(gl_info)) + shader_addline(buffer, "color_out0 = ps_out[0];\n"); shader_addline(buffer, "}\n"); @@ -9522,7 +10119,7 @@ static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct } static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(struct shader_glsl_priv *priv, - const struct ffp_frag_settings *args, const struct wined3d_context *context) + const struct ffp_frag_settings *args, const struct wined3d_context_gl *context_gl) { struct glsl_ffp_fragment_shader *glsl_desc; const struct ffp_frag_desc *desc; @@ -9534,7 +10131,7 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str return NULL; glsl_desc->entry.settings = *args; - glsl_desc->id = shader_glsl_generate_ffp_fragment_shader(priv, args, context); + glsl_desc->id = shader_glsl_generate_ffp_fragment_shader(priv, args, context_gl); list_init(&glsl_desc->linked_programs); add_ffp_frag_shader(&priv->ffp_fragment_shaders, &glsl_desc->entry); @@ -9543,19 +10140,39 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info, - struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count) + struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, + unsigned int vs_c_count) { unsigned int i; struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers); - for (i = 0; i < vs_c_count; ++i) + if (priv->consts_ubo && vs_c_count) { - string_buffer_sprintf(name, "vs_c[%u]", i); - vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); - } - memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); + unsigned int base, count; - for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) + vs->vs_c_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "vs_c_ubo")); + checkGLcall("glGetUniformBlockIndex"); + if (vs->vs_c_block_index == -1) + ERR("Could not get ubo_vs_c block index.\n"); + + wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, + &base, &count); + assert(count >= 1); + GL_EXTCALL(glUniformBlockBinding(program_id, vs->vs_c_block_index, base)); + checkGLcall("glUniformBlockBinding"); + } + else if (!priv->consts_ubo) + { + for (i = 0; i < min(vs_c_count, priv->max_vs_consts_f); ++i) + { + string_buffer_sprintf(name, "vs_c[%u]", i); + vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } + if (vs_c_count < priv->max_vs_consts_f) + memset(&vs->uniform_f_locations[vs_c_count], 0xff, (priv->max_vs_consts_f - vs_c_count) * sizeof(GLuint)); + } + + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { string_buffer_sprintf(name, "vs_i[%u]", i); vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); @@ -9568,19 +10185,38 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * } vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); + vs->base_vertex_id_location = GL_EXTCALL(glGetUniformLocation(program_id, "base_vertex_id")); - for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i) + for (i = 0; i < MAX_VERTEX_BLENDS; ++i) { string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i); vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i) + + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + vs->modelview_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "ffp_modelview_ubo")); + checkGLcall("glGetUniformBlockIndex"); + if (vs->modelview_block_index != -1) + { + unsigned int base, count; + + wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, + &base, &count); + assert(count >= 2); + + GL_EXTCALL(glUniformBlockBinding(program_id, vs->modelview_block_index, base + 1)); + checkGLcall("glUniformBlockBinding"); + } + } + else { - string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i); - vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + vs->modelview_block_index = -1; } + vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); - for (i = 0; i < MAX_TEXTURES; ++i) + vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i); vs->texture_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); @@ -9591,7 +10227,7 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * vs->material_emissive_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.emissive")); vs->material_shininess_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.shininess")); vs->light_ambient_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_light_ambient")); - for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) + for (i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) { string_buffer_sprintf(name, "ffp_light[%u].diffuse", i); vs->light_location[i].diffuse = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); @@ -9666,7 +10302,7 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info * ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { string_buffer_sprintf(name, "bumpenv_mat%u", i); ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); @@ -9696,11 +10332,11 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info * } static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, - const struct wined3d_context *context, struct wined3d_shader *shader) + const struct wined3d_context_gl *context_gl, struct wined3d_shader *shader) { - struct glsl_context_data *ctx_data = context->shader_backend_data; + struct glsl_context_data *ctx_data = context_gl->c.shader_backend_data; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_string_buffer *buffer = &priv->shader_buffer; - const struct wined3d_gl_info *gl_info = context->gl_info; struct glsl_cs_compiled_shader *gl_shaders; struct glsl_shader_private *shader_data; struct glsl_shader_prog_link *entry; @@ -9719,7 +10355,6 @@ static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, return E_OUTOFMEMORY; } shader_data = shader->backend_data; - gl_shaders = shader_data->gl_shaders.cs; if (!(shader_data->gl_shaders.cs = heap_alloc(sizeof(*gl_shaders)))) { @@ -9735,7 +10370,7 @@ static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, TRACE("Compiling compute shader %p.\n", shader); string_buffer_clear(buffer); - shader_id = shader_glsl_generate_compute_shader(context, buffer, &priv->string_buffers, shader); + shader_id = shader_glsl_generate_compute_shader(context_gl, buffer, &priv->string_buffers, shader); gl_shaders[shader_data->num_gl_shaders++].id = shader_id; program_id = GL_EXTCALL(glCreateProgram()); @@ -9765,7 +10400,7 @@ static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, GL_EXTCALL(glUseProgram(program_id)); checkGLcall("glUseProgram"); - shader_glsl_load_program_resources(context, priv, program_id, shader); + shader_glsl_load_program_resources(context_gl, priv, program_id, shader); shader_glsl_load_images(gl_info, priv, program_id, &shader->reg_maps); entry->constant_update_mask = 0; @@ -9775,7 +10410,7 @@ static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, return WINED3D_OK; } -static GLuint find_glsl_compute_shader(const struct wined3d_context *context, +static GLuint find_glsl_compute_shader(const struct wined3d_context_gl *context_gl, struct shader_glsl_priv *priv, struct wined3d_shader *shader) { struct glsl_shader_private *shader_data; @@ -9783,7 +10418,7 @@ static GLuint find_glsl_compute_shader(const struct wined3d_context *context, if (!shader->backend_data) { WARN("Failed to find GLSL program for compute shader %p.\n", shader); - if (FAILED(shader_glsl_compile_compute_shader(priv, context, shader))) + if (FAILED(shader_glsl_compile_compute_shader(priv, context_gl, shader))) { ERR("Failed to compile compute shader %p.\n", shader); return 0; @@ -9794,7 +10429,7 @@ static GLuint find_glsl_compute_shader(const struct wined3d_context *context, } /* Context activation is done by the caller. */ -static void set_glsl_compute_shader_program(const struct wined3d_context *context, +static void set_glsl_compute_shader_program(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data) { struct glsl_shader_prog_link *entry; @@ -9802,7 +10437,7 @@ static void set_glsl_compute_shader_program(const struct wined3d_context *contex struct glsl_program_key key; GLuint cs_id; - if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE))) + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE))) return; if (!(shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE])) @@ -9812,7 +10447,7 @@ static void set_glsl_compute_shader_program(const struct wined3d_context *contex return; } - cs_id = find_glsl_compute_shader(context, priv, shader); + cs_id = find_glsl_compute_shader(context_gl, priv, shader); memset(&key, 0, sizeof(key)); key.cs_id = cs_id; if (!(entry = get_glsl_program_entry(priv, &key))) @@ -9821,11 +10456,11 @@ static void set_glsl_compute_shader_program(const struct wined3d_context *contex } /* Context activation is done by the caller. */ -static void set_glsl_shader_program(const struct wined3d_context *context, const struct wined3d_state *state, +static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data) { - const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_shader *pre_rasterization_shader; const struct ps_np2fixup_info *np2fixup_info = NULL; struct wined3d_shader *hshader, *dshader, *gshader; @@ -9841,11 +10476,11 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const GLuint ds_id = 0; GLuint gs_id = 0; GLuint ps_id = 0; - struct list *ps_list = NULL, *vs_list = NULL; + struct list *ps_list, *vs_list; WORD attribs_map; struct wined3d_string_buffer *tmp_name; - if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_VERTEX)) && ctx_data->glsl_program) + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_VERTEX)) && ctx_data->glsl_program) { vs_id = ctx_data->glsl_program->vs.id; vs_list = &ctx_data->glsl_program->vs.shader_entry; @@ -9859,8 +10494,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, context); - vs_id = find_glsl_vshader(context, priv, vshader, &vs_compile_args); + find_vs_compile_args(state, vshader, context_gl->c.stream_info.swizzle_map, &vs_compile_args, &context_gl->c); + vs_id = find_glsl_vertex_shader(context_gl, priv, vshader, &vs_compile_args); vs_list = &vshader->linked_programs; } else if (priv->vertex_pipe == &glsl_vertex_pipe) @@ -9868,20 +10503,24 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const struct glsl_ffp_vertex_shader *ffp_shader; struct wined3d_ffp_vs_settings settings; - wined3d_ffp_get_vs_settings(context, state, &settings); + wined3d_ffp_get_vs_settings(&context_gl->c, state, &settings); ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings); vs_id = ffp_shader->id; vs_list = &ffp_shader->linked_programs; } + if (vshader && vshader->reg_maps.constant_float_count > WINED3D_MAX_VS_CONSTS_F + && !device_is_swvp(context_gl->c.device)) + FIXME("Applying context with SW shader in HW mode.\n"); + hshader = state->shader[WINED3D_SHADER_TYPE_HULL]; - if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program) + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program) hs_id = ctx_data->glsl_program->hs.id; else if (hshader) - hs_id = find_glsl_hull_shader(context, priv, hshader); + hs_id = find_glsl_hull_shader(context_gl, priv, hshader); dshader = state->shader[WINED3D_SHADER_TYPE_DOMAIN]; - if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_DOMAIN)) && ctx_data->glsl_program) + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_DOMAIN)) && ctx_data->glsl_program) { ds_id = ctx_data->glsl_program->ds.id; } @@ -9889,12 +10528,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const { struct ds_compile_args args; - find_ds_compile_args(state, dshader, &args, context); - ds_id = find_glsl_domain_shader(context, priv, dshader, &args); + find_ds_compile_args(state, dshader, &args, &context_gl->c); + ds_id = find_glsl_domain_shader(context_gl, priv, dshader, &args); } gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; - if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY)) && ctx_data->glsl_program) + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY)) && ctx_data->glsl_program) { gs_id = ctx_data->glsl_program->gs.id; } @@ -9902,8 +10541,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const { struct gs_compile_args args; - find_gs_compile_args(state, gshader, &args, context); - gs_id = find_glsl_geometry_shader(context, priv, gshader, &args); + find_gs_compile_args(state, gshader, &args, &context_gl->c); + gs_id = find_glsl_geometry_shader(context_gl, priv, gshader, &args); } /* A pixel shader is not used when rasterization is disabled. */ @@ -9912,7 +10551,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const ps_id = 0; ps_list = NULL; } - else if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program) + else if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program) { ps_id = ctx_data->glsl_program->ps.id; ps_list = &ctx_data->glsl_program->ps.shader_entry; @@ -9924,8 +10563,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const { struct ps_compile_args ps_compile_args; pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - find_ps_compile_args(state, pshader, context->stream_info.position_transformed, &ps_compile_args, context); - ps_id = find_glsl_pshader(context, &priv->shader_buffer, &priv->string_buffers, + find_ps_compile_args(state, pshader, context_gl->c.stream_info.position_transformed, + &ps_compile_args, &context_gl->c); + ps_id = find_glsl_fragment_shader(context_gl, &priv->shader_buffer, &priv->string_buffers, pshader, &ps_compile_args, &np2fixup_info); ps_list = &pshader->linked_programs; } @@ -9935,8 +10575,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const struct glsl_ffp_fragment_shader *ffp_shader; struct ffp_frag_settings settings; - gen_ffp_frag_op(context, state, &settings, FALSE); - ffp_shader = shader_glsl_find_ffp_fragment_shader(priv, &settings, context); + gen_ffp_frag_op(&context_gl->c, state, &settings, FALSE); + ffp_shader = shader_glsl_find_ffp_fragment_shader(priv, &settings, context_gl); ps_id = ffp_shader->id; ps_list = &ffp_shader->linked_programs; } @@ -10035,31 +10675,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const } } checkGLcall("glBindAttribLocation"); - string_buffer_release(&priv->string_buffers, tmp_name); if (!needs_legacy_glsl_syntax(gl_info)) { - char var[12]; - - if (wined3d_dualblend_enabled(state, gl_info)) + for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i) { - for (i = 0; i < gl_info->limits.dual_buffers * 2; i++) - { - sprintf(var, "ps_out%u", i); - GL_EXTCALL(glBindFragDataLocationIndexed(program_id, i / 2, i % 2, var)); - checkGLcall("glBindFragDataLocationIndexed"); - } - } - else - { - for (i = 0; i < gl_info->limits.buffers; i++) - { - sprintf(var, "ps_out%u", i); - GL_EXTCALL(glBindFragDataLocation(program_id, i, var)); - checkGLcall("glBindFragDataLocation"); - } + string_buffer_sprintf(tmp_name, "color_out%u", i); + GL_EXTCALL(glBindFragDataLocation(program_id, i, tmp_name->buffer)); + checkGLcall("glBindFragDataLocation"); } } + string_buffer_release(&priv->string_buffers, tmp_name); } if (hshader) @@ -10086,7 +10712,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const GL_EXTCALL(glAttachShader(program_id, gs_id)); checkGLcall("glAttachShader"); - shader_glsl_init_transform_feedback(context, priv, program_id, gshader); + shader_glsl_init_transform_feedback(context_gl, priv, program_id, gshader); list_add_head(&gshader->linked_programs, &entry->gs.shader_entry); } @@ -10157,15 +10783,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B; if (entry->vs.pos_fixup_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; + if (entry->vs.base_vertex_id_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_BASE_VERTEX_ID; - shader_glsl_load_program_resources(context, priv, program_id, vshader); + shader_glsl_load_program_resources(context_gl, priv, program_id, vshader); } else { entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW | WINED3D_SHADER_CONST_FFP_PROJ; - for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i) + for (i = 0; i < MAX_VERTEX_BLENDS; ++i) { if (entry->vs.modelview_matrix_location[i] != -1) { @@ -10174,7 +10802,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const } } - for (i = 0; i < MAX_TEXTURES; ++i) + if (entry->vs.modelview_block_index != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; + + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (entry->vs.texture_matrix_location[i] != -1) { @@ -10196,14 +10827,14 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; if (hshader) - shader_glsl_load_program_resources(context, priv, program_id, hshader); + shader_glsl_load_program_resources(context_gl, priv, program_id, hshader); if (dshader) { if (entry->ds.pos_fixup_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; - shader_glsl_load_program_resources(context, priv, program_id, dshader); + shader_glsl_load_program_resources(context_gl, priv, program_id, dshader); } if (gshader) @@ -10211,7 +10842,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (entry->gs.pos_fixup_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; - shader_glsl_load_program_resources(context, priv, program_id, gshader); + shader_glsl_load_program_resources(context_gl, priv, program_id, gshader); } if (ps_id) @@ -10226,17 +10857,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (entry->ps.ycorrection_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR; - shader_glsl_load_program_resources(context, priv, program_id, pshader); + shader_glsl_load_program_resources(context_gl, priv, program_id, pshader); shader_glsl_load_images(gl_info, priv, program_id, &pshader->reg_maps); } else { entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS; - shader_glsl_load_samplers(context, priv, program_id, NULL); + shader_glsl_load_samplers(&context_gl->c, priv, program_id, NULL); } - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (entry->ps.bumpenv_mat_location[i] != -1) { @@ -10264,7 +10895,7 @@ static void shader_glsl_precompile(void *shader_priv, struct wined3d_shader *sha if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE) { context = context_acquire(device, NULL, 0); - shader_glsl_compile_compute_shader(shader_priv, context, shader); + shader_glsl_compile_compute_shader(shader_priv, wined3d_context_gl(context), shader); context_release(context); } } @@ -10273,18 +10904,19 @@ static void shader_glsl_precompile(void *shader_priv, struct wined3d_shader *sha static void shader_glsl_select(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct glsl_context_data *ctx_data = context->shader_backend_data; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct shader_glsl_priv *priv = shader_priv; struct glsl_shader_prog_link *glsl_program; GLenum current_vertex_color_clamp; GLuint program_id, prev_id; - priv->vertex_pipe->vp_enable(gl_info, !use_vs(state)); - priv->fragment_pipe->enable_extension(gl_info, !use_ps(state)); + priv->vertex_pipe->vp_enable(context, !use_vs(state)); + priv->fragment_pipe->fp_enable(context, !use_ps(state)); prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; - set_glsl_shader_program(context, state, priv, ctx_data); + set_glsl_shader_program(context_gl, state, priv, ctx_data); glsl_program = ctx_data->glsl_program; if (glsl_program) @@ -10292,7 +10924,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex program_id = glsl_program->id; current_vertex_color_clamp = glsl_program->vs.vertex_color_clamp; if (glsl_program->shader_controlled_clip_distances) - context_enable_clip_distances(context, glsl_program->clip_distance_mask); + wined3d_context_gl_enable_clip_distances(context_gl, glsl_program->clip_distance_mask); } else { @@ -10332,13 +10964,14 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex static void shader_glsl_select_compute(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct glsl_context_data *ctx_data = context->shader_backend_data; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct shader_glsl_priv *priv = shader_priv; GLuint program_id, prev_id; prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; - set_glsl_compute_shader_program(context, state, priv, ctx_data); + set_glsl_compute_shader_program(context_gl, state, priv, ctx_data); program_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; TRACE("Using GLSL program %u.\n", program_id); @@ -10373,16 +11006,17 @@ static void shader_glsl_invalidate_current_program(struct wined3d_context *conte /* Context activation is done by the caller. */ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *context) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct glsl_context_data *ctx_data = context->shader_backend_data; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct shader_glsl_priv *priv = shader_priv; shader_glsl_invalidate_current_program(context); GL_EXTCALL(glUseProgram(0)); checkGLcall("glUseProgram"); - priv->vertex_pipe->vp_enable(gl_info, FALSE); - priv->fragment_pipe->enable_extension(gl_info, FALSE); + priv->vertex_pipe->vp_enable(context, FALSE); + priv->fragment_pipe->fp_enable(context, FALSE); if (needs_legacy_glsl_syntax(gl_info) && gl_info->supported[ARB_COLOR_BUFFER_FLOAT]) { @@ -10426,7 +11060,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) } context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + gl_info = wined3d_context_gl(context)->gl_info; TRACE("Deleting linked programs.\n"); linked_programs = &shader->linked_programs; @@ -10637,9 +11271,9 @@ static void constant_heap_free(struct constant_heap *heap) } static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, - const struct fragment_pipeline *fragment_pipe) + const struct wined3d_fragment_pipe_ops *fragment_pipe) { - SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1; + SIZE_T stack_size; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct fragment_caps fragment_caps; void *vertex_priv, *fragment_priv; @@ -10648,6 +11282,19 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win if (!(priv = heap_alloc_zero(sizeof(*priv)))) return E_OUTOFMEMORY; + priv->consts_ubo = gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]; + priv->max_vs_consts_f = min(WINED3D_MAX_VS_CONSTS_F_SWVP, priv->consts_ubo + ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) + : gl_info->limits.glsl_vs_float_constants); + + if (!(device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING))) + priv->max_vs_consts_f = min(priv->max_vs_consts_f, WINED3D_MAX_VS_CONSTS_F); + + stack_size = priv->consts_ubo + ? wined3d_log2i(WINED3D_MAX_PS_CONSTS_F) + 1 + : wined3d_log2i(max(priv->max_vs_consts_f, WINED3D_MAX_PS_CONSTS_F)) + 1; + TRACE("consts_ubo %#x, max_vs_consts_f %u.\n", priv->consts_ubo, priv->max_vs_consts_f); + string_buffer_list_init(&priv->string_buffers); if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv))) @@ -10660,7 +11307,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv))) { ERR("Failed to initialize fragment pipe.\n"); - vertex_pipe->vp_free(device); + vertex_pipe->vp_free(device, NULL); heap_free(priv); return E_FAIL; } @@ -10677,7 +11324,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win goto fail; } - if (!constant_heap_init(&priv->vconst_heap, WINED3D_MAX_VS_CONSTS_F)) + if (!priv->consts_ubo && !constant_heap_init(&priv->vconst_heap, priv->max_vs_consts_f)) { ERR("Failed to initialize vertex shader constant heap\n"); goto fail; @@ -10694,14 +11341,26 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win priv->next_constant_version = 1; priv->vertex_pipe = vertex_pipe; priv->fragment_pipe = fragment_pipe; - fragment_pipe->get_caps(gl_info, &fragment_caps); + fragment_pipe->get_caps(device->adapter, &fragment_caps); priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; priv->legacy_lighting = device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING; - + priv->ubo_modelview = -1; /* To be initialized on first usage. */ + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + { + priv->modelview_buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv->modelview_buffer) + * MAX_VERTEX_BLEND_UBO); + if (!priv->modelview_buffer) + { + ERR("Failed to alloacte modelview buffer.\n"); + goto fail; + } + } device->vertex_priv = vertex_priv; device->fragment_priv = fragment_priv; device->shader_priv = priv; + priv->ubo_vs_c = -1; + return WINED3D_OK; fail: @@ -10709,14 +11368,14 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win constant_heap_free(&priv->vconst_heap); heap_free(priv->stack); string_buffer_free(&priv->shader_buffer); - fragment_pipe->free_private(device); - vertex_pipe->vp_free(device); + fragment_pipe->free_private(device, NULL); + vertex_pipe->vp_free(device, NULL); heap_free(priv); return E_OUTOFMEMORY; } /* Context activation is done by the caller. */ -static void shader_glsl_free(struct wined3d_device *device) +static void shader_glsl_free(struct wined3d_device *device, struct wined3d_context *context) { struct shader_glsl_priv *priv = device->shader_priv; @@ -10726,9 +11385,24 @@ static void shader_glsl_free(struct wined3d_device *device) heap_free(priv->stack); string_buffer_list_cleanup(&priv->string_buffers); string_buffer_free(&priv->shader_buffer); - priv->fragment_pipe->free_private(device); - priv->vertex_pipe->vp_free(device); + priv->fragment_pipe->free_private(device, context); + priv->vertex_pipe->vp_free(device, context); + if (priv->ubo_modelview != -1) + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_modelview)); + checkGLcall("glDeleteBuffers"); + priv->ubo_modelview = -1; + } + HeapFree(GetProcessHeap(), 0, priv->modelview_buffer); + if (priv->ubo_vs_c != -1) + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_vs_c)); + checkGLcall("glDeleteBuffers"); + priv->ubo_vs_c = -1; + } heap_free(device->shader_priv); device->shader_priv = NULL; } @@ -10751,7 +11425,8 @@ static void shader_glsl_free_context_data(struct wined3d_context *context) static void shader_glsl_init_context_state(struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; gl_info->gl_ops.gl.p_glEnable(GL_PROGRAM_POINT_SIZE); checkGLcall("GL_PROGRAM_POINT_SIZE"); @@ -10760,8 +11435,6 @@ static void shader_glsl_init_context_state(struct wined3d_context *context) static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *gl_info) { BOOL shader_model_4 = gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) - && gl_info->supported[WINED3D_GL_VERSION_3_2] - && gl_info->supported[ARB_SAMPLER_OBJECTS] && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_TEXTURE_SWIZZLE]; @@ -10769,7 +11442,6 @@ static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *g && gl_info->supported[ARB_COMPUTE_SHADER] && gl_info->supported[ARB_CULL_DISTANCE] && gl_info->supported[ARB_DERIVATIVE_CONTROL] - && gl_info->supported[ARB_DRAW_INDIRECT] && gl_info->supported[ARB_GPU_SHADER5] && gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS] && gl_info->supported[ARB_SHADER_IMAGE_LOAD_STORE] @@ -10791,8 +11463,9 @@ static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *g return 2; } -static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) +static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; unsigned int shader_model = shader_glsl_get_shader_model(gl_info); TRACE("Shader model %u.\n", shader_model); @@ -10807,7 +11480,10 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0; caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0; - caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants); + caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F_SWVP, + gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] + ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) + : gl_info->limits.glsl_vs_float_constants); caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants); caps->varying_count = gl_info->limits.glsl_varyings; @@ -10833,6 +11509,10 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s * shader_glsl_alloc(). */ caps->wined3d_caps = WINED3D_SHADER_CAP_VS_CLIPPING | WINED3D_SHADER_CAP_SRGB_WRITE; + if (needs_interpolation_qualifiers_for_shader_outputs(gl_info)) + caps->wined3d_caps |= WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION; + if (shader_glsl_full_ffp_varyings(gl_info)) + caps->wined3d_caps |= WINED3D_SHADER_CAP_FULL_FFP_VARYINGS; } static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup) @@ -10889,8 +11569,8 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_PS */ shader_glsl_nop, - /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, - /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SGV */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_PS_SIV */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_SGV */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_SIV */ shader_glsl_nop, /* WINED3DSIH_DCL_INTERFACE */ NULL, @@ -10929,7 +11609,6 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_DSY */ shader_glsl_map2gl, /* WINED3DSIH_DSY_COARSE */ shader_glsl_map2gl, /* WINED3DSIH_DSY_FINE */ shader_glsl_map2gl, - /* WINED3DSIH_EVAL_SAMPLE_INDEX */ NULL, /* WINED3DSIH_ELSE */ shader_glsl_else, /* WINED3DSIH_EMIT */ shader_glsl_emit, /* WINED3DSIH_EMIT_STREAM */ shader_glsl_emit, @@ -10938,6 +11617,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_ENDREP */ shader_glsl_end, /* WINED3DSIH_ENDSWITCH */ shader_glsl_end, /* WINED3DSIH_EQ */ shader_glsl_relop, + /* WINED3DSIH_EVAL_SAMPLE_INDEX */ shader_glsl_interpolate, /* WINED3DSIH_EXP */ shader_glsl_scalar_op, /* WINED3DSIH_EXPP */ shader_glsl_expp, /* WINED3DSIH_F16TOF32 */ shader_glsl_float16, @@ -11033,7 +11713,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_SAMPLE_C */ shader_glsl_sample_c, /* WINED3DSIH_SAMPLE_C_LZ */ shader_glsl_sample_c, /* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample, - /* WINED3DSIH_SAMPLE_INFO */ NULL, + /* WINED3DSIH_SAMPLE_INFO */ shader_glsl_sample_info, /* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample, /* WINED3DSIH_SAMPLE_POS */ NULL, /* WINED3DSIH_SETP */ NULL, @@ -11128,16 +11808,22 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = shader_glsl_has_ffp_proj_control, }; -static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {} +static void glsl_vertex_pipe_vp_enable(const struct wined3d_context *context, BOOL enable) {} -static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps) +static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + caps->xyzrhw = TRUE; caps->emulated_flatshading = !needs_legacy_glsl_syntax(gl_info); caps->ffp_generic_attributes = TRUE; - caps->max_active_lights = MAX_ACTIVE_LIGHTS; + caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS; caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; - caps->max_vertex_blend_matrix_index = MAX_VERTEX_INDEX_BLENDS - 1; + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLEND_UBO - 1; + else + caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLENDS - 1; + caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN | WINED3DVTXPCAPS_MATERIALSOURCE7 | WINED3DVTXPCAPS_VERTEXFOG @@ -11173,30 +11859,33 @@ static void *glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops * return NULL; } -static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context) +static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *param) { struct glsl_ffp_vertex_shader *shader = WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_vertex_shader, desc.entry); struct glsl_shader_prog_link *program, *program2; - struct glsl_ffp_destroy_ctx *ctx = context; + struct glsl_ffp_destroy_ctx *ctx = param; + const struct wined3d_gl_info *gl_info; + gl_info = ctx->context_gl->gl_info; LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs, struct glsl_shader_prog_link, vs.shader_entry) { - delete_glsl_program_entry(ctx->priv, ctx->gl_info, program); + delete_glsl_program_entry(ctx->priv, gl_info, program); } - ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id); + GL_EXTCALL(glDeleteShader(shader->id)); heap_free(shader); } /* Context activation is done by the caller. */ -static void glsl_vertex_pipe_vp_free(struct wined3d_device *device) +static void glsl_vertex_pipe_vp_free(struct wined3d_device *device, struct wined3d_context *context) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct shader_glsl_priv *priv = device->vertex_priv; struct glsl_ffp_destroy_ctx ctx; ctx.priv = priv; - ctx.gl_info = &device->adapter->gl_info; + ctx.context_gl = context_gl; wine_rb_destroy(&priv->ffp_vertex_shaders, shader_glsl_free_ffp_vertex_shader, &ctx); } @@ -11212,7 +11901,10 @@ static void glsl_vertex_pipe_shader(struct wined3d_context *context, static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + BOOL specular = !!(context->stream_info.use_map & (1u << WINED3D_FFP_SPECULAR)); + BOOL diffuse = !!(context->stream_info.use_map & (1u << WINED3D_FFP_DIFFUSE)); BOOL normal = !!(context->stream_info.use_map & (1u << WINED3D_FFP_NORMAL)); const BOOL legacy_clip_planes = needs_legacy_glsl_syntax(gl_info); BOOL transformed = context->stream_info.position_transformed; @@ -11245,8 +11937,13 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, /* Because of settings->texcoords, we have to regenerate the vertex * shader on a vdecl change if there aren't enough varyings to just - * always output all the texture coordinates. */ - if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info) + * always output all the texture coordinates. + * + * Likewise, we have to invalidate the shader when using per-vertex + * colours and diffuse/specular attribute presence changes, or when + * normal presence changes. */ + if (!shader_glsl_full_ffp_varyings(gl_info) || (state->render_states[WINED3D_RS_COLORVERTEX] + && (diffuse != context->last_was_diffuse || specular != context->last_was_specular)) || normal != context->last_was_normal) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; @@ -11269,6 +11966,8 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, } context->last_was_vshader = use_vs(state); + context->last_was_diffuse = diffuse; + context->last_was_specular = specular; context->last_was_normal = normal; } @@ -11326,19 +12025,20 @@ static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, static void glsl_vertex_pipe_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW; + context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW + | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; } static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - int i = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)); - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i); + context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; } static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int k; context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW @@ -11396,7 +12096,7 @@ static void glsl_vertex_pipe_texmatrix_np2(struct wined3d_context *context, if (!texture) return; - if (sampler >= MAX_TEXTURES) + if (sampler >= WINED3D_MAX_TEXTURES) return; if ((np2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) @@ -11454,7 +12154,8 @@ static void glsl_vertex_pipe_shademode(struct wined3d_context *context, static void glsl_vertex_pipe_clip_plane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; UINT index = state_id - STATE_CLIPPLANE(0); if (index >= gl_info->limits.user_clip_distances) @@ -11463,7 +12164,7 @@ static void glsl_vertex_pipe_clip_plane(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; } -static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = +static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = { {STATE_VDECL, {STATE_VDECL, glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE }, {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), glsl_vertex_pipe_vs }, WINED3D_GL_EXT_NONE }, @@ -11516,11 +12217,258 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, @@ -11612,13 +12560,15 @@ const struct wined3d_vertex_pipe_ops glsl_vertex_pipe = glsl_vertex_pipe_vp_states, }; -static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOOL enable) +static void glsl_fragment_pipe_enable(const struct wined3d_context *context, BOOL enable) { /* Nothing to do. */ } -static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) +static void glsl_fragment_pipe_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL | WINED3D_FRAGMENT_CAP_SRGB_WRITE | WINED3D_FRAGMENT_CAP_COLOR_KEY; @@ -11649,8 +12599,8 @@ static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, s | WINED3DTEXOPCAPS_LERP | WINED3DTEXOPCAPS_BUMPENVMAP | WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE; - caps->MaxTextureBlendStages = MAX_TEXTURES; - caps->MaxSimultaneousTextures = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_TEXTURES); + caps->MaxTextureBlendStages = WINED3D_MAX_TEXTURES; + caps->MaxSimultaneousTextures = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], WINED3D_MAX_TEXTURES); } static DWORD glsl_fragment_pipe_get_emul_mask(const struct wined3d_gl_info *gl_info) @@ -11676,30 +12626,33 @@ static void *glsl_fragment_pipe_alloc(const struct wined3d_shader_backend_ops *s return NULL; } -static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, void *context) +static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, void *param) { struct glsl_ffp_fragment_shader *shader = WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_fragment_shader, entry.entry); struct glsl_shader_prog_link *program, *program2; - struct glsl_ffp_destroy_ctx *ctx = context; + struct glsl_ffp_destroy_ctx *ctx = param; + const struct wined3d_gl_info *gl_info; + gl_info = ctx->context_gl->gl_info; LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs, struct glsl_shader_prog_link, ps.shader_entry) { - delete_glsl_program_entry(ctx->priv, ctx->gl_info, program); + delete_glsl_program_entry(ctx->priv, gl_info, program); } - ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id); + GL_EXTCALL(glDeleteShader(shader->id)); heap_free(shader); } /* Context activation is done by the caller. */ -static void glsl_fragment_pipe_free(struct wined3d_device *device) +static void glsl_fragment_pipe_free(struct wined3d_device *device, struct wined3d_context *context) { + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct shader_glsl_priv *priv = device->fragment_priv; struct glsl_ffp_destroy_ctx ctx; ctx.priv = priv; - ctx.gl_info = &device->adapter->gl_info; + ctx.context_gl = context_gl; wine_rb_destroy(&priv->ffp_fragment_shaders, shader_glsl_free_ffp_fragment_shader, &ctx); } @@ -11754,8 +12707,10 @@ static void glsl_fragment_pipe_fog(struct wined3d_context *context, static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + /* Because of settings->texcoords_initialized and args->texcoords_initialized. */ - if (context->gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(context->gl_info)) + if (!shader_glsl_full_ffp_varyings(gl_info)) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE))) @@ -11765,8 +12720,10 @@ static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, static void glsl_fragment_pipe_vs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + /* Because of settings->texcoords_initialized and args->texcoords_initialized. */ - if (context->gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(context->gl_info)) + if (!shader_glsl_full_ffp_varyings(gl_info)) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; } @@ -11785,9 +12742,9 @@ static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *cont static void glsl_fragment_pipe_alpha_test_func(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; GLint func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]); - float ref = state->render_states[WINED3D_RS_ALPHAREF] / 255.0f; + float ref = wined3d_alpha_ref(state); if (func) { @@ -11805,7 +12762,7 @@ static void glsl_fragment_pipe_core_alpha_test(struct wined3d_context *context, static void glsl_fragment_pipe_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_ALPHATESTENABLE]) { @@ -11837,7 +12794,7 @@ static void glsl_fragment_pipe_shademode(struct wined3d_context *context, context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; } -static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = +static const struct wined3d_state_entry_template glsl_fragment_pipe_state_template[] = { {STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE }, {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), glsl_fragment_pipe_vs }, WINED3D_GL_EXT_NONE }, @@ -11966,7 +12923,7 @@ static void glsl_fragment_pipe_free_context_data(struct wined3d_context *context { } -const struct fragment_pipeline glsl_fragment_pipe = +const struct wined3d_fragment_pipe_ops glsl_fragment_pipe = { glsl_fragment_pipe_enable, glsl_fragment_pipe_get_caps, @@ -11978,3 +12935,907 @@ const struct fragment_pipeline glsl_fragment_pipe = shader_glsl_color_fixup_supported, glsl_fragment_pipe_state_template, }; + +struct glsl_blitter_args +{ + GLenum texture_type; + struct color_fixup_desc fixup; + unsigned short use_colour_key; +}; + +struct glsl_blitter_program +{ + struct wine_rb_entry entry; + struct glsl_blitter_args args; + GLuint id; +}; + +struct wined3d_glsl_blitter +{ + struct wined3d_blitter blitter; + struct wined3d_string_buffer_list string_buffers; + struct wine_rb_tree programs; + GLuint palette_texture; +}; + +static int glsl_blitter_args_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct glsl_blitter_args *a = key; + const struct glsl_blitter_args *b = &WINE_RB_ENTRY_VALUE(entry, const struct glsl_blitter_program, entry)->args; + + return memcmp(a, b, sizeof(*a)); +} + +/* Context activation is done by the caller. */ +static void glsl_free_blitter_program(struct wine_rb_entry *entry, void *ctx) +{ + struct glsl_blitter_program *program = WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry); + struct wined3d_context_gl *context_gl = ctx; + const struct wined3d_gl_info *gl_info; + + gl_info = context_gl->gl_info; + GL_EXTCALL(glDeleteProgram(program->id)); + checkGLcall("glDeleteProgram()"); + heap_free(program); +} + +/* Context activation is done by the caller. */ +static void glsl_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_glsl_blitter *glsl_blitter; + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_destroy(next, context); + + glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter); + + if (glsl_blitter->palette_texture) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &glsl_blitter->palette_texture); + + wine_rb_destroy(&glsl_blitter->programs, glsl_free_blitter_program, context_gl); + string_buffer_list_cleanup(&glsl_blitter->string_buffers); + + heap_free(glsl_blitter); +} + +static void glsl_blitter_generate_p8_shader(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, + const char *output, const char *tex_type, const char *swizzle) +{ + shader_addline(buffer, "uniform sampler1D sampler_palette;\n"); + shader_addline(buffer, "\nvoid main()\n{\n"); + /* The alpha-component contains the palette index. */ + shader_addline(buffer, " float index = texture%s(sampler, out_texcoord.%s).%c;\n", + needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle, + gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x'); + /* Scale the index by 255/256 and add a bias of 0.5 in order to sample in + * the middle. */ + shader_addline(buffer, " index = (index * 255.0 + 0.5) / 256.0;\n"); + shader_addline(buffer, " %s = texture%s(sampler_palette, index);\n", + output, needs_legacy_glsl_syntax(gl_info) ? "1D" : ""); + if (args->use_colour_key) + shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high"); + shader_addline(buffer, "}\n"); +} + +static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, + const char *tex_type) +{ + enum complex_fixup complex_fixup = get_complex_fixup(args->fixup); + char chroma, luminance; + const char *tex; + + /* The YUY2 and UYVY formats contain two pixels packed into a 32 bit + * macropixel, giving effectively 16 bits per pixel. The color consists of + * a luminance(Y) and two chroma(U and V) values. Each macropixel has two + * luminance values, one for each single pixel it contains, and one U and + * one V value shared between both pixels. + * + * The data is loaded into an A8L8 texture. With YUY2, the luminance + * component contains the luminance and alpha the chroma. With UYVY it is + * vice versa. Thus take the format into account when generating the read + * swizzles + * + * Reading the Y value is straightforward - just sample the texture. The + * hardware takes care of filtering in the horizontal and vertical + * direction. + * + * Reading the U and V values is harder. We have to avoid filtering + * horizontally, because that would mix the U and V values of one pixel or + * two adjacent pixels. Thus floor the texture coordinate and add 0.5 to + * get an unfiltered read, regardless of the filtering setting. Vertical + * filtering works automatically though - the U and V values of two rows + * are mixed nicely. + * + * Apart of avoiding filtering issues, the code has to know which value it + * just read, and where it can find the other one. To determine this, it + * checks if it sampled an even or odd pixel, and shifts the 2nd read + * accordingly. + * + * Handling horizontal filtering of U and V values requires reading a 2nd + * pair of pixels, extracting U and V and mixing them. This is not + * implemented yet. + * + * An alternative implementation idea is to load the texture as A8R8G8B8 + * texture, with width / 2. This way one read gives all 3 values, finding + * U and V is easy in an unfiltered situation. Finding the luminance on + * the other hand requires finding out if it is an odd or even pixel. The + * real drawback of this approach is filtering. This would have to be + * emulated completely in the shader, reading up two 2 packed pixels in up + * to 2 rows and interpolating both horizontally and vertically. Beyond + * that it would require adjustments to the texture handling code to deal + * with the width scaling. */ + + if (complex_fixup == COMPLEX_FIXUP_UYVY) + { + chroma = 'x'; + luminance = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y'; + } + else + { + chroma = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y'; + luminance = 'x'; + } + + tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : ""; + + /* First we have to read the chroma values. This means we need at least + * two pixels (no filtering), or 4 pixels (with filtering). To get the + * unmodified chroma, we have to rid ourselves of the filtering when we + * sample the texture. */ + shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); + /* We must not allow filtering between pixel x and x+1, this would mix U + * and V. Vertical filtering is ok. However, bear in mind that the pixel + * center is at 0.5, so add 0.5. */ + shader_addline(buffer, " texcoord.x = (floor(texcoord.x * size.x) + 0.5) / size.x;\n"); + shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma); + + /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25 + * and 0.75 for the even and odd pixels respectively. */ + /* Put the value into either of the chroma values. */ + shader_addline(buffer, " bool even = fract(texcoord.x * size.x * 0.5) < 0.5;\n"); + shader_addline(buffer, " if (even)\n"); + shader_addline(buffer, " chroma.y = luminance;\n"); + shader_addline(buffer, " else\n"); + shader_addline(buffer, " chroma.x = luminance;\n"); + + /* Sample pixel 2. If we read an even pixel, sample the pixel right to the + * current one. Otherwise, sample the left pixel. */ + shader_addline(buffer, " texcoord.x += even ? 1.0 / size.x : -1.0 / size.x;\n"); + shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma); + + /* Put the value into the other chroma. */ + shader_addline(buffer, " if (even)\n"); + shader_addline(buffer, " chroma.x = luminance;\n"); + shader_addline(buffer, " else\n"); + shader_addline(buffer, " chroma.y = luminance;\n"); + + /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of + * the current one and lerp the two U and V values. */ + + /* This gives the correctly filtered luminance value. */ + shader_addline(buffer, " luminance = texture%s(sampler, out_texcoord.xy).%c;\n", tex, luminance); +} + +static void gen_yv12_read(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const char *tex_type) +{ + char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x'; + const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : ""; + + /* YV12 surfaces contain a WxH sized luminance plane, followed by a + * (W/2)x(H/2) V and a (W/2)x(H/2) U plane, each with 8 bit per pixel. So + * the effective bitdepth is 12 bits per pixel. Since the U and V planes + * have only half the pitch of the luminance plane, the packing into the + * gl texture is a bit unfortunate. If the whole texture is interpreted as + * luminance data it looks approximately like this: + * + * +----------------------------------+---- + * | | + * | | + * | | + * | | + * | | 2 + * | LUMINANCE | - + * | | 3 + * | | + * | | + * | | + * | | + * +----------------+-----------------+---- + * | | | + * | V even rows | V odd rows | + * | | | 1 + * +----------------+------------------ - + * | | | 3 + * | U even rows | U odd rows | + * | | | + * +----------------+-----------------+---- + * | | | + * | 0.5 | 0.5 | + * + * So it appears as if there are 4 chroma images, but in fact the odd rows + * in the chroma images are in the same row as the even ones. So it is + * kinda tricky to read. */ + + /* First sample the chroma values. */ + shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); + /* The chroma planes have only half the width. */ + shader_addline(buffer, " texcoord.x *= 0.5;\n"); + + /* The first value is between 2/3 and 5/6 of the texture's height, so + * scale+bias the coordinate. Also read the right side of the image when + * reading odd lines. + * + * Don't forget to clamp the y values in into the range, otherwise we'll + * get filtering bleeding. */ + + /* Read odd lines from the right side (add 0.5 to the x coordinate). */ + shader_addline(buffer, " if (fract(floor(texcoord.y * size.y) * 0.5 + 1.0 / 6.0) >= 0.5)\n"); + shader_addline(buffer, " texcoord.x += 0.5;\n"); + + /* Clamp, keep the half pixel origin in mind. */ + shader_addline(buffer, " texcoord.y = clamp(2.0 / 3.0 + texcoord.y / 6.0, " + "2.0 / 3.0 + 0.5 / size.y, 5.0 / 6.0 - 0.5 / size.y);\n"); + + shader_addline(buffer, " chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component); + + /* The other chroma value is 1/6th of the texture lower, from 5/6th to + * 6/6th No need to clamp because we're just reusing the already clamped + * value from above. */ + shader_addline(buffer, " texcoord.y += 1.0 / 6.0;\n"); + shader_addline(buffer, " chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component); + + /* Sample the luminance value. It is in the top 2/3rd of the texture, so + * scale the y coordinate. Clamp the y coordinate to prevent the chroma + * values from bleeding into the sampled luminance values due to + * filtering. */ + shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); + /* Multiply the y coordinate by 2/3 and clamp it. */ + shader_addline(buffer, " texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n"); + shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component); +} + +static void gen_nv12_read(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const char *tex_type) +{ + char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x'; + const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : ""; + + /* NV12 surfaces contain a WxH sized luminance plane, followed by a + * (W/2)x(H/2) sized plane where each component is an UV pair. So the + * effective bitdepth is 12 bits per pixel. If the whole texture is + * interpreted as luminance data it looks approximately like this: + * + * +----------------------------------+---- + * | | + * | | + * | | + * | | + * | | 2 + * | LUMINANCE | - + * | | 3 + * | | + * | | + * | | + * | | + * +----------------------------------+---- + * |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV| + * |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV| + * | | 1 + * | | - + * | | 3 + * | | + * | | + * +----------------------------------+---- */ + + /* First sample the chroma values. */ + shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); + /* We only have half the number of chroma pixels. */ + shader_addline(buffer, " texcoord.x *= 0.5;\n"); + shader_addline(buffer, " texcoord.y = (texcoord.y + 2.0) / 3.0;\n"); + + /* We must not allow filtering horizontally, this would mix U and V. + * Vertical filtering is ok. However, bear in mind that the pixel center + * is at 0.5, so add 0.5. */ + + /* Convert to non-normalised coordinates so we can find the individual + * pixel. */ + shader_addline(buffer, " texcoord.x = floor(texcoord.x * size.x);\n"); + /* Multiply by 2 since chroma components are stored in UV pixel pairs, add + * 0.5 to hit the center of the pixel. Then convert back to normalised + * coordinates. */ + shader_addline(buffer, " texcoord.x = (texcoord.x * 2.0 + 0.5) / size.x;\n"); + /* Clamp, keep the half pixel origin in mind. */ + shader_addline(buffer, " texcoord.y = max(texcoord.y, 2.0 / 3.0 + 0.5 / size.y);\n"); + + shader_addline(buffer, " chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component); + /* Add 1.0 / size.x to sample the adjacent texel. */ + shader_addline(buffer, " texcoord.x += 1.0 / size.x;\n"); + shader_addline(buffer, " chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component); + + /* Sample the luminance value. It is in the top 2/3rd of the texture, so + * scale the y coordinate. Clamp the y coordinate to prevent the chroma + * values from bleeding into the sampled luminance values due to + * filtering. */ + shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n"); + /* Multiply the y coordinate by 2/3 and clamp it. */ + shader_addline(buffer, " texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n"); + shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component); +} + +static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, + const char *output, const char *tex_type, const char *swizzle) +{ + enum complex_fixup complex_fixup = get_complex_fixup(args->fixup); + + shader_addline(buffer, "const vec4 yuv_coef = vec4(1.403, -0.344, -0.714, 1.770);\n"); + shader_addline(buffer, "float luminance;\n"); + shader_addline(buffer, "vec2 texcoord;\n"); + shader_addline(buffer, "vec2 chroma;\n"); + shader_addline(buffer, "uniform vec2 size;\n"); + + shader_addline(buffer, "\nvoid main()\n{\n"); + + switch (complex_fixup) + { + case COMPLEX_FIXUP_UYVY: + case COMPLEX_FIXUP_YUY2: + gen_packed_yuv_read(buffer, gl_info, args, tex_type); + break; + + case COMPLEX_FIXUP_YV12: + gen_yv12_read(buffer, gl_info, tex_type); + break; + + case COMPLEX_FIXUP_NV12: + gen_nv12_read(buffer, gl_info, tex_type); + break; + + default: + FIXME("Unsupported fixup %#x.\n", complex_fixup); + string_buffer_free(buffer); + return; + } + + /* Calculate the final result. Formula is taken from + * http://www.fourcc.org/fccyvrgb.php. Note that the chroma + * ranges from -0.5 to 0.5. */ + shader_addline(buffer, "\n chroma.xy -= 0.5;\n"); + + shader_addline(buffer, " %s.x = luminance + chroma.x * yuv_coef.x;\n", output); + shader_addline(buffer, " %s.y = luminance + chroma.y * yuv_coef.y + chroma.x * yuv_coef.z;\n", output); + shader_addline(buffer, " %s.z = luminance + chroma.y * yuv_coef.w;\n", output); + if (args->use_colour_key) + shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high"); + + shader_addline(buffer, "}\n"); +} + +static void glsl_blitter_generate_plain_shader(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args, + const char *output, const char *tex_type, const char *swizzle) +{ + shader_addline(buffer, "\nvoid main()\n{\n"); + shader_addline(buffer, " %s = texture%s(sampler, out_texcoord.%s);\n", + output, needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle); + shader_glsl_color_correction_ext(buffer, output, WINED3DSP_WRITEMASK_ALL, args->fixup); + if (args->use_colour_key) + shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high"); + shader_addline(buffer, "}\n"); +} + +/* Context activation is done by the caller. */ +static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter, + const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args) +{ + static const struct + { + GLenum texture_target; + const char texture_type[7]; + const char texcoord_swizzle[4]; + } + texture_data[] = + { + {GL_TEXTURE_2D, "2D", "xy"}, + {GL_TEXTURE_CUBE_MAP, "Cube", "xyz"}, + {GL_TEXTURE_RECTANGLE_ARB, "2DRect", "xy"}, + }; + static const char vshader_main[] = + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4(pos, 0.0, 1.0);\n" + " out_texcoord = texcoord;\n" + "}\n"; + enum complex_fixup complex_fixup = get_complex_fixup(args->fixup); + struct wined3d_string_buffer *buffer, *output; + GLuint program, vshader_id, fshader_id; + const char *tex_type, *swizzle, *ptr; + unsigned int i; + GLint loc; + + for (i = 0; i < ARRAY_SIZE(texture_data); ++i) + { + if (args->texture_type == texture_data[i].texture_target) + { + tex_type = texture_data[i].texture_type; + swizzle = texture_data[i].texcoord_swizzle; + break; + } + } + if (i == ARRAY_SIZE(texture_data)) + { + FIXME("Unsupported texture type %#x.\n", args->texture_type); + return 0; + } + + program = GL_EXTCALL(glCreateProgram()); + + vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); + + buffer = string_buffer_get(&blitter->string_buffers); + shader_glsl_add_version_declaration(buffer, gl_info); + shader_addline(buffer, "%s vec2 pos;\n", get_attribute_keyword(gl_info)); + shader_addline(buffer, "%s vec3 texcoord;\n", get_attribute_keyword(gl_info)); + declare_out_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n"); + shader_addline(buffer, vshader_main); + + ptr = buffer->buffer; + GL_EXTCALL(glShaderSource(vshader_id, 1, &ptr, NULL)); + GL_EXTCALL(glAttachShader(program, vshader_id)); + GL_EXTCALL(glDeleteShader(vshader_id)); + + fshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); + + string_buffer_clear(buffer); + shader_glsl_add_version_declaration(buffer, gl_info); + shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type); + if (args->use_colour_key) + { + shader_addline(buffer, "uniform struct\n{\n"); + shader_addline(buffer, " vec4 low, high;\n"); + shader_addline(buffer, "} colour_key;\n"); + } + declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n"); + /* TODO: Declare the out variable with the correct type (and put it in the + * blitter args). */ + if (!needs_legacy_glsl_syntax(gl_info)) + shader_addline(buffer, "out vec4 ps_out[1];\n"); + + output = string_buffer_get(&blitter->string_buffers); + string_buffer_sprintf(output, "%s[0]", get_fragment_output(gl_info)); + + switch (complex_fixup) + { + case COMPLEX_FIXUP_P8: + glsl_blitter_generate_p8_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); + break; + case COMPLEX_FIXUP_YUY2: + case COMPLEX_FIXUP_UYVY: + case COMPLEX_FIXUP_YV12: + case COMPLEX_FIXUP_NV12: + glsl_blitter_generate_yuv_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); + break; + case COMPLEX_FIXUP_NONE: + glsl_blitter_generate_plain_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); + } + + string_buffer_release(&blitter->string_buffers, output); + + ptr = buffer->buffer; + GL_EXTCALL(glShaderSource(fshader_id, 1, &ptr, NULL)); + string_buffer_release(&blitter->string_buffers, buffer); + GL_EXTCALL(glAttachShader(program, fshader_id)); + GL_EXTCALL(glDeleteShader(fshader_id)); + + GL_EXTCALL(glBindAttribLocation(program, 0, "pos")); + GL_EXTCALL(glBindAttribLocation(program, 1, "texcoord")); + + if (!needs_legacy_glsl_syntax(gl_info)) + GL_EXTCALL(glBindFragDataLocation(program, 0, "ps_out")); + + GL_EXTCALL(glCompileShader(vshader_id)); + print_glsl_info_log(gl_info, vshader_id, FALSE); + GL_EXTCALL(glCompileShader(fshader_id)); + print_glsl_info_log(gl_info, fshader_id, FALSE); + GL_EXTCALL(glLinkProgram(program)); + shader_glsl_validate_link(gl_info, program); + + GL_EXTCALL(glUseProgram(program)); + loc = GL_EXTCALL(glGetUniformLocation(program, "sampler")); + GL_EXTCALL(glUniform1i(loc, 0)); + if (complex_fixup == COMPLEX_FIXUP_P8) + { + loc = GL_EXTCALL(glGetUniformLocation(program, "sampler_palette")); + GL_EXTCALL(glUniform1i(loc, 1)); + } + + return program; +} + +/* Context activation is done by the caller. */ +static void glsl_blitter_upload_palette(struct wined3d_glsl_blitter *blitter, + struct wined3d_context_gl *context_gl, const struct wined3d_texture_gl *texture_gl) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_palette *palette; + + palette = texture_gl->t.swapchain ? texture_gl->t.swapchain->palette : NULL; + + if (!blitter->palette_texture) + gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture); + + wined3d_context_gl_active_texture(context_gl, gl_info, 1); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, blitter->palette_texture); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + + if (palette) + { + gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, palette->colors); + } + else + { + static const DWORD black; + + FIXME("P8 texture loaded without a palette.\n"); + gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 1, 0, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, &black); + } + + wined3d_context_gl_active_texture(context_gl, gl_info, 0); +} + +/* Context activation is done by the caller. */ +static struct glsl_blitter_program *glsl_blitter_get_program(struct wined3d_glsl_blitter *blitter, + struct wined3d_context_gl *context_gl, const struct wined3d_texture_gl *texture_gl, BOOL use_colour_key) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct glsl_blitter_program *program; + struct glsl_blitter_args args; + struct wine_rb_entry *entry; + + memset(&args, 0, sizeof(args)); + args.texture_type = texture_gl->target; + args.fixup = texture_gl->t.resource.format->color_fixup; + args.use_colour_key = use_colour_key; + + if ((entry = wine_rb_get(&blitter->programs, &args))) + return WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry); + + if (!(program = heap_alloc(sizeof(*program)))) + { + ERR("Failed to allocate blitter program memory.\n"); + return NULL; + } + + program->args = args; + if (!(program->id = glsl_blitter_generate_program(blitter, gl_info, &args))) + { + WARN("Failed to generate blitter program.\n"); + heap_free(program); + return NULL; + } + + if (wine_rb_put(&blitter->programs, &program->args, &program->entry) == -1) + { + ERR("Failed to store blitter program.\n"); + GL_EXTCALL(glDeleteProgram(program->id)); + heap_free(program); + return NULL; + } + + return program; +} + +static BOOL glsl_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_context *context, + const struct wined3d_texture_gl *src_texture, DWORD src_location, + const struct wined3d_texture_gl *dst_texture, DWORD dst_location) +{ + const struct wined3d_resource *src_resource = &src_texture->t.resource; + const struct wined3d_resource *dst_resource = &dst_texture->t.resource; + const struct wined3d_format *src_format = src_resource->format; + const struct wined3d_format *dst_format = dst_resource->format; + BOOL decompress; + + if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id) + { + if (dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) + blit_op = WINED3D_BLIT_OP_DEPTH_BLIT; + else + blit_op = WINED3D_BLIT_OP_COLOR_BLIT; + } + + if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT && blit_op != WINED3D_BLIT_OP_COLOR_BLIT_CKEY + && blit_op != WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) + { + TRACE("Unsupported blit_op %#x.\n", blit_op); + return FALSE; + } + + if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) + return FALSE; + + if (src_texture->target == GL_TEXTURE_2D_MULTISAMPLE + || src_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + TRACE("Multi-sample source textures not supported.\n"); + return FALSE; + } + + /* We don't necessarily want to blit from resources without + * WINED3D_RESOURCE_ACCESS_GPU, but that may be the only way to decompress + * compressed textures. */ + decompress = (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); + if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) + { + TRACE("Source or destination resource does not have GPU access.\n"); + return FALSE; + } + + if (!is_identity_fixup(dst_format->color_fixup) + && (dst_format->id != src_format->id || dst_location != WINED3D_LOCATION_DRAWABLE)) + { + TRACE("Destination fixups are not supported.\n"); + return FALSE; + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && !((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE) + || (dst_resource->bind_flags & WINED3D_BIND_RENDER_TARGET))) + { + TRACE("Destination texture is not FBO attachable.\n"); + return FALSE; + } + + TRACE("Returning supported.\n"); + return TRUE; +} + +static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, + struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, + unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) +{ + struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); + struct wined3d_texture_gl *dst_texture_gl = wined3d_texture_gl(dst_texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_device *device = dst_texture->resource.device; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_texture *staging_texture = NULL; + struct wined3d_glsl_blitter *glsl_blitter; + struct wined3d_color_key alpha_test_key; + struct glsl_blitter_program *program; + struct wined3d_blitter *next; + unsigned int src_level; + GLint location; + RECT s, d; + + TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), + wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), + wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); + + if (!glsl_blitter_supported(op, context, src_texture_gl, src_location, dst_texture_gl, dst_location)) + { + if (!(next = blitter->next)) + { + ERR("No blitter to handle blit op %#x.\n", op); + return dst_location; + } + + TRACE("Forwarding to blitter %p.\n", next); + return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); + } + + glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter); + + if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + struct wined3d_resource_desc desc; + struct wined3d_box upload_box; + HRESULT hr; + + TRACE("Source texture is not GPU accessible, creating a staging texture.\n"); + + src_level = src_sub_resource_idx % src_texture->level_count; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + desc.format = src_texture->resource.format->id; + desc.multisample_type = src_texture->resource.multisample_type; + desc.multisample_quality = src_texture->resource.multisample_quality; + desc.usage = WINED3DUSAGE_PRIVATE; + desc.bind_flags = 0; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + desc.width = wined3d_texture_get_level_width(src_texture, src_level); + desc.height = wined3d_texture_get_level_height(src_texture, src_level); + desc.depth = 1; + desc.size = 0; + + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0, + NULL, NULL, &wined3d_null_parent_ops, &staging_texture))) + { + ERR("Failed to create staging texture, hr %#x.\n", hr); + return dst_location; + } + + wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth); + wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0, + src_texture, src_sub_resource_idx, &upload_box); + + src_texture = staging_texture; + src_texture_gl = wined3d_texture_gl(src_texture); + src_sub_resource_idx = 0; + } + else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && (src_texture->sub_resources[src_sub_resource_idx].locations + & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE + && !wined3d_resource_is_offscreen(&src_texture->resource)) + { + + /* Without FBO blits transferring from the drawable to the texture is + * expensive, because we have to flip the data in sysmem. Since we can + * flip in the blitter, we don't actually need that flip anyway. So we + * use the surface's texture as scratch texture, and flip the source + * rectangle instead. */ + texture2d_load_fb_texture(src_texture_gl, src_sub_resource_idx, FALSE, context); + + s = *src_rect; + src_level = src_sub_resource_idx % src_texture->level_count; + s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top; + s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom; + src_rect = &s; + } + else + { + wined3d_texture_load(src_texture, context, FALSE); + } + + wined3d_context_gl_apply_blit_state(context_gl, device); + + if (dst_location == WINED3D_LOCATION_DRAWABLE) + { + d = *dst_rect; + wined3d_texture_translate_drawable_coords(dst_texture, context_gl->window, &d); + dst_rect = &d; + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + GLenum buffer; + + if (dst_location == WINED3D_LOCATION_DRAWABLE) + { + TRACE("Destination texture %p is onscreen.\n", dst_texture); + buffer = wined3d_texture_get_gl_buffer(dst_texture); + } + else + { + TRACE("Destination texture %p is offscreen.\n", dst_texture); + buffer = GL_COLOR_ATTACHMENT0; + } + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, + &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location); + wined3d_context_gl_set_draw_buffer(context_gl, buffer); + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); + context_invalidate_state(context, STATE_FRAMEBUFFER); + } + + if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) + { + const struct wined3d_format *f = src_texture->resource.format; + + alpha_test_key.color_space_low_value = 0; + alpha_test_key.color_space_high_value = ~(((1u << f->alpha_size) - 1) << f->alpha_offset); + colour_key = &alpha_test_key; + } + else if (op != WINED3D_BLIT_OP_COLOR_BLIT_CKEY) + { + colour_key = NULL; + } + + if (!(program = glsl_blitter_get_program(glsl_blitter, context_gl, src_texture_gl, !!colour_key))) + { + ERR("Failed to get blitter program.\n"); + return dst_location; + } + GL_EXTCALL(glUseProgram(program->id)); + switch (get_complex_fixup(program->args.fixup)) + { + case COMPLEX_FIXUP_P8: + glsl_blitter_upload_palette(glsl_blitter, context_gl, src_texture_gl); + break; + + case COMPLEX_FIXUP_YUY2: + case COMPLEX_FIXUP_UYVY: + case COMPLEX_FIXUP_YV12: + case COMPLEX_FIXUP_NV12: + src_level = src_sub_resource_idx % src_texture->level_count; + location = GL_EXTCALL(glGetUniformLocation(program->id, "size")); + GL_EXTCALL(glUniform2f(location, wined3d_texture_get_level_pow2_width(src_texture, src_level), + wined3d_texture_get_level_pow2_height(src_texture, src_level))); + break; + + default: + break; + } + if (colour_key) + { + struct wined3d_color float_key[2]; + + wined3d_format_get_float_color_key(src_texture->resource.format, colour_key, float_key); + location = GL_EXTCALL(glGetUniformLocation(program->id, "colour_key.low")); + GL_EXTCALL(glUniform4fv(location, 1, &float_key[0].r)); + location = GL_EXTCALL(glGetUniformLocation(program->id, "colour_key.high")); + GL_EXTCALL(glUniform4fv(location, 1, &float_key[1].r)); + } + wined3d_context_gl_draw_shaded_quad(context_gl, src_texture_gl, src_sub_resource_idx, src_rect, dst_rect, filter); + GL_EXTCALL(glUseProgram(0)); + + if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture)) + gl_info->gl_ops.gl.p_glFlush(); + + if (staging_texture) + wined3d_texture_decref(staging_texture); + + return dst_location; +} + +static void glsl_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, + unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, + const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) +{ + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_clear(next, device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, color, depth, stencil); +} + +static const struct wined3d_blitter_ops glsl_blitter_ops = +{ + glsl_blitter_destroy, + glsl_blitter_clear, + glsl_blitter_blit, +}; + +struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next, + const struct wined3d_device *device) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_glsl_blitter *blitter; + + if (device->shader_backend != &glsl_shader_backend) + return NULL; + + if (!gl_info->supported[ARB_VERTEX_SHADER] || !gl_info->supported[ARB_FRAGMENT_SHADER]) + return NULL; + + if (!(blitter = heap_alloc(sizeof(*blitter)))) + { + ERR("Failed to allocate blitter.\n"); + return NULL; + } + + TRACE("Created blitter %p.\n", blitter); + + blitter->blitter.ops = &glsl_blitter_ops; + blitter->blitter.next = *next; + string_buffer_list_init(&blitter->string_buffers); + wine_rb_init(&blitter->programs, glsl_blitter_args_compare); + blitter->palette_texture = 0; + *next = &blitter->blitter; + + return *next; +} \ No newline at end of file diff --git a/dll/directx/wine/wined3d/nvidia_texture_shader.c b/dll/directx/wine/wined3d/nvidia_texture_shader.c index 0baa414e57d..10f35e61d59 100644 --- a/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -30,9 +30,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); /* Context activation for state handlers is done by the caller. */ -static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD stage, struct wined3d_context *context) +static void nvts_activate_dimensions(const struct wined3d_state *state, + unsigned int stage, struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_texture *texture; BOOL bumpmap = FALSE; if (stage > 0 @@ -40,16 +42,16 @@ static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD st || state->texture_states[stage - 1][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP)) { bumpmap = TRUE; - context->texShaderBumpMap |= (1u << stage); + context_gl->c.texShaderBumpMap |= (1u << stage); } else { - context->texShaderBumpMap &= ~(1u << stage); + context_gl->c.texShaderBumpMap &= ~(1u << stage); } - if (state->textures[stage]) + if ((texture = state->textures[stage])) { - switch (state->textures[stage]->target) + switch (wined3d_texture_gl(texture)->target) { case GL_TEXTURE_2D: gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, @@ -69,6 +71,9 @@ static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD st gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)"); break; + default: + FIXME("Unhandled target %#x.\n", wined3d_texture_gl(texture)->target); + break; } } else @@ -478,9 +483,10 @@ void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); BOOL tex_used = context->fixed_function_usage_map & (1u << stage); - DWORD mapped_stage = context->tex_unit_map[stage]; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int mapped_stage = context_gl->tex_unit_map[stage]; TRACE("Setting color op for stage %u.\n", stage); @@ -496,7 +502,7 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s FIXME("Attempt to enable unsupported stage!\n"); return; } - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); } if (context->lowest_disabled_stage > 0) @@ -545,13 +551,9 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s if (tex_used) { if (gl_info->supported[NV_TEXTURE_SHADER2]) - { - nvts_activate_dimensions(state, stage, context); - } + nvts_activate_dimensions(state, stage, context_gl); else - { texture_activate_dimensions(state->textures[stage], gl_info); - } } } @@ -574,9 +576,9 @@ static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_s BOOL usedBump = !!(context->texShaderBumpMap & 1u << (stage + 1)); if (usesBump != usedBump) { - context_active_texture(context, gl_info, mapped_stage + 1); - nvts_activate_dimensions(state, stage + 1, context); - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage + 1); + nvts_activate_dimensions(state, stage + 1, context_gl); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); } } } @@ -599,27 +601,31 @@ static void nvrc_resultarg(struct wined3d_context *context, const struct wined3d static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD sampler = state_id - STATE_SAMPLER(0); - DWORD mapped_stage = context->tex_unit_map[sampler]; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + unsigned int sampler, mapped_stage; + + sampler = state_id - STATE_SAMPLER(0); + mapped_stage = context_gl->tex_unit_map[sampler]; /* No need to enable / disable anything here for unused samplers. The tex_colorop * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop * will take care of this business. */ - if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) + if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context_gl->gl_info->limits.textures) return; if (sampler >= context->lowest_disabled_stage) return; if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) return; - nvts_activate_dimensions(state, sampler, context); + nvts_activate_dimensions(state, sampler, context_gl); } static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = context->tex_unit_map[stage + 1]; - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + unsigned int mapped_stage = context_gl->tex_unit_map[stage + 1]; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; float mat[2][2]; /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to @@ -630,7 +636,7 @@ static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3 */ if (mapped_stage < gl_info->limits.textures) { - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); /* We can't just pass a pointer to the state to GL due to the * different matrix format (column major vs row major). */ @@ -645,7 +651,8 @@ static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3 static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_color color; wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); @@ -653,8 +660,10 @@ static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d } /* Context activation is done by the caller. */ -static void nvrc_enable(const struct wined3d_gl_info *gl_info, BOOL enable) +static void nvrc_enable(const struct wined3d_context *context, BOOL enable) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + if (enable) { gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV); @@ -668,9 +677,11 @@ static void nvrc_enable(const struct wined3d_gl_info *gl_info, BOOL enable) } /* Context activation is done by the caller. */ -static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable) +static void nvts_enable(const struct wined3d_context *context, BOOL enable) { - nvrc_enable(gl_info, enable); + const struct wined3d_gl_info *gl_info = wined3d_context_gl_const(context)->gl_info; + + nvrc_enable(context, enable); if (enable) { gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_SHADER_NV); @@ -683,8 +694,10 @@ static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable) } } -static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) +static void nvrc_fragment_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + caps->wined3d_caps = 0; caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; @@ -735,7 +748,7 @@ static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct WINED3DTEXOPCAPS_PREMODULATE */ #endif - caps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners); + caps->MaxTextureBlendStages = min(WINED3D_MAX_TEXTURES, gl_info->limits.general_combiners); caps->MaxSimultaneousTextures = gl_info->limits.textures; } @@ -750,7 +763,7 @@ static void *nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader } /* Context activation is done by the caller. */ -static void nvrc_fragment_free(struct wined3d_device *device) {} +static void nvrc_fragment_free(struct wined3d_device *device, struct wined3d_context *context) {} /* Two fixed function pipeline implementations using GL_NV_register_combiners and * GL_NV_texture_shader. The nvts_fragment_pipeline assumes that both extensions @@ -764,7 +777,7 @@ static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup) return is_identity_fixup(fixup); } -static const struct StateEntryTemplate nvrc_fragmentstate_template[] = +static const struct wined3d_state_entry_template nvrc_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -915,7 +928,8 @@ static void nvrc_context_free(struct wined3d_context *context) } -const struct fragment_pipeline nvts_fragment_pipeline = { +const struct wined3d_fragment_pipe_ops nvts_fragment_pipeline = +{ nvts_enable, nvrc_fragment_get_caps, nvrc_fragment_get_emul_mask, @@ -927,7 +941,8 @@ const struct fragment_pipeline nvts_fragment_pipeline = { nvrc_fragmentstate_template, }; -const struct fragment_pipeline nvrc_fragment_pipeline = { +const struct wined3d_fragment_pipe_ops nvrc_fragment_pipeline = +{ nvrc_enable, nvrc_fragment_get_caps, nvrc_fragment_get_emul_mask, diff --git a/dll/directx/wine/wined3d/palette.c b/dll/directx/wine/wined3d/palette.c index 67308093c95..ecd493ef842 100644 --- a/dll/directx/wine/wined3d/palette.c +++ b/dll/directx/wine/wined3d/palette.c @@ -106,6 +106,8 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, palette, flags, start, count, entries); TRACE("Palette flags: %#x.\n", palette->flags); + wined3d_cs_finish(palette->device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES) { const BYTE *entry = (const BYTE *)entries; diff --git a/dll/directx/wine/wined3d/query.c b/dll/directx/wine/wined3d/query.c index 5ea79b6e4a7..e6d3b34ebdb 100644 --- a/dll/directx/wine/wined3d/query.c +++ b/dll/directx/wine/wined3d/query.c @@ -25,6 +25,98 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); +static void wined3d_query_buffer_invalidate(struct wined3d_query *query) +{ + /* map[0] != map[1]: exact values do not have any significance. */ + query->map_ptr[0] = 0; + query->map_ptr[1] = ~(UINT64)0; +} + +static BOOL wined3d_query_buffer_is_valid(struct wined3d_query *query) +{ + return query->map_ptr[0] == query->map_ptr[1]; +} + +static void wined3d_query_create_buffer_object(struct wined3d_context_gl *context_gl, struct wined3d_query *query) +{ + const GLuint map_flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLuint buffer_object; + + GL_EXTCALL(glGenBuffers(1, &buffer_object)); + GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, buffer_object)); + GL_EXTCALL(glBufferStorage(GL_QUERY_BUFFER, sizeof(query->map_ptr[0]) * 2, NULL, map_flags)); + query->map_ptr = GL_EXTCALL(glMapBufferRange(GL_QUERY_BUFFER, 0, sizeof(query->map_ptr[0]) * 2, map_flags)); + GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, 0)); + checkGLcall("query buffer object creation"); + + wined3d_query_buffer_invalidate(query); + query->buffer_object = buffer_object; +} + +void wined3d_query_gl_destroy_buffer_object(struct wined3d_context_gl *context_gl, struct wined3d_query *query) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + + GL_EXTCALL(glDeleteBuffers(1, &query->buffer_object)); + checkGLcall("query buffer object destruction"); + + query->buffer_object = 0; + query->map_ptr = NULL; +} + +/* From ARB_occlusion_query: "Querying the state for a given occlusion query + * forces that occlusion query to complete within a finite amount of time." + * In practice, that means drivers flush when retrieving + * GL_QUERY_RESULT_AVAILABLE, which can be undesirable when applications use a + * significant number of queries. Using a persistently mapped query buffer + * object allows us to avoid these implicit flushes. An additional benefit is + * that it allows us to poll the query status from the application-thread + * instead of from the csmt-thread. */ +static BOOL wined3d_query_buffer_queue_result(struct wined3d_context_gl *context_gl, + struct wined3d_query *query, GLuint id) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLsync tmp_sync; + + if (!gl_info->supported[ARB_QUERY_BUFFER_OBJECT] || !gl_info->supported[ARB_BUFFER_STORAGE]) + return FALSE; + /* Don't use query buffers without CSMT, mainly for simplicity. */ + if (!context_gl->c.device->cs->thread) + return FALSE; + + if (query->buffer_object) + { + /* If there's still a query result in-flight for the existing buffer + * object (i.e., the query was restarted before we received its + * result), we can't reuse the existing buffer object. */ + if (wined3d_query_buffer_is_valid(query)) + wined3d_query_buffer_invalidate(query); + else + wined3d_query_gl_destroy_buffer_object(context_gl, query); + } + + if (!query->buffer_object) + wined3d_query_create_buffer_object(context_gl, query); + + GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, query->buffer_object)); + /* Read the same value twice. We know we have the result if map_ptr[0] == map_ptr[1]. */ + GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, (void *)0)); + GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, (void *)sizeof(query->map_ptr[0]))); + GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, 0)); + checkGLcall("queue query result"); + + /* ARB_buffer_storage requires the client to call FenceSync with + * SYNC_GPU_COMMANDS_COMPLETE after the server does a write. This behavior + * is not enforced by Mesa. + */ + tmp_sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); + GL_EXTCALL(glDeleteSync(tmp_sync)); + checkGLcall("query buffer sync"); + + return TRUE; +} + static UINT64 get_query_result64(GLuint id, const struct wined3d_gl_info *gl_info) { if (gl_info->supported[ARB_TIMER_QUERY]) @@ -89,31 +181,31 @@ static BOOL wined3d_fence_supported(const struct wined3d_gl_info *gl_info) } static enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence, - const struct wined3d_device *device, DWORD flags) + struct wined3d_device *device, DWORD flags) { const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; enum wined3d_fence_result ret; BOOL fence_result; TRACE("fence %p, device %p, flags %#x.\n", fence, device, flags); - if (!fence->context) + if (!fence->context_gl) { TRACE("Fence not issued.\n"); return WINED3D_FENCE_NOT_STARTED; } - if (!(context = context_reacquire(device, fence->context))) + if (!(context_gl = wined3d_context_gl_reacquire(fence->context_gl))) { - if (!fence->context->gl_info->supported[ARB_SYNC]) + if (!fence->context_gl->gl_info->supported[ARB_SYNC]) { WARN("Fence tested from wrong thread.\n"); return WINED3D_FENCE_WRONG_THREAD; } - context = context_acquire(device, NULL, 0); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; if (gl_info->supported[ARB_SYNC]) { @@ -162,27 +254,27 @@ static enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence * ret = WINED3D_FENCE_ERROR; } - context_release(context); + context_release(&context_gl->c); return ret; } enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, - const struct wined3d_device *device) + struct wined3d_device *device) { const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; enum wined3d_fence_result ret; TRACE("fence %p, device %p.\n", fence, device); - if (!fence->context) + if (!fence->context_gl) { TRACE("Fence not issued.\n"); return WINED3D_FENCE_NOT_STARTED; } - gl_info = fence->context->gl_info; + gl_info = fence->context_gl->gl_info; - if (!(context = context_reacquire(device, fence->context))) + if (!(context_gl = wined3d_context_gl_reacquire(fence->context_gl))) { /* A glFinish does not reliably wait for draws in other contexts. The caller has * to find its own way to cope with the thread switch @@ -192,9 +284,9 @@ enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, WARN("Fence finished from wrong thread.\n"); return WINED3D_FENCE_WRONG_THREAD; } - context = context_acquire(device, NULL, 0); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; if (gl_info->supported[ARB_SYNC]) { @@ -219,13 +311,13 @@ enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, ret = WINED3D_FENCE_ERROR; } } - else if (context->gl_info->supported[APPLE_FENCE]) + else if (gl_info->supported[APPLE_FENCE]) { GL_EXTCALL(glFinishFenceAPPLE(fence->object.id)); checkGLcall("glFinishFenceAPPLE"); ret = WINED3D_FENCE_OK; } - else if (context->gl_info->supported[NV_FENCE]) + else if (gl_info->supported[NV_FENCE]) { GL_EXTCALL(glFinishFenceNV(fence->object.id)); checkGLcall("glFinishFenceNV"); @@ -237,23 +329,23 @@ enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, ret = WINED3D_FENCE_ERROR; } - context_release(context); + context_release(&context_gl->c); return ret; } -void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_device *device) +void wined3d_fence_issue(struct wined3d_fence *fence, struct wined3d_device *device) { - struct wined3d_context *context = NULL; + struct wined3d_context_gl *context_gl = NULL; const struct wined3d_gl_info *gl_info; - if (fence->context && !(context = context_reacquire(device, fence->context)) - && !fence->context->gl_info->supported[ARB_SYNC]) - context_free_fence(fence); - if (!context) - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; - if (!fence->context) - context_alloc_fence(context, fence); + if (fence->context_gl && !(context_gl = wined3d_context_gl_reacquire(fence->context_gl)) + && !fence->context_gl->gl_info->supported[ARB_SYNC]) + wined3d_context_gl_free_fence(fence); + if (!context_gl) + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + gl_info = context_gl->gl_info; + if (!fence->context_gl) + wined3d_context_gl_alloc_fence(context_gl, fence); if (gl_info->supported[ARB_SYNC]) { @@ -274,13 +366,13 @@ void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_devic checkGLcall("glSetFenceNV"); } - context_release(context); + context_release(&context_gl->c); } static void wined3d_fence_free(struct wined3d_fence *fence) { - if (fence->context) - context_free_fence(fence); + if (fence->context_gl) + wined3d_context_gl_free_fence(fence); } void wined3d_fence_destroy(struct wined3d_fence *fence) @@ -338,12 +430,6 @@ static void wined3d_query_destroy_object(void *object) if (!list_empty(&query->poll_list_entry)) list_remove(&query->poll_list_entry); - - /* Queries are specific to the GL context that created them. Not - * deleting the query will obviously leak it, but that's still better - * than potentially deleting a different query with the same id in this - * context, and (still) leaking the actual query. */ - query->query_ops->query_destroy(query); } ULONG CDECL wined3d_query_decref(struct wined3d_query *query) @@ -354,8 +440,11 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) if (!refcount) { + struct wined3d_device *device = query->device; + query->parent_ops->wined3d_object_destroyed(query->parent); - wined3d_cs_destroy_object(query->device->cs, wined3d_query_destroy_object, query); + wined3d_cs_destroy_object(device->cs, wined3d_query_destroy_object, query); + device->adapter->adapter_ops->adapter_destroy_query(query); } return refcount; @@ -382,15 +471,20 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, return WINED3DERR_INVALIDCALL; } - if (!query->device->cs->thread) + if (query->device->cs->thread) { - if (!query->query_ops->query_poll(query, flags)) + if (query->counter_main != query->counter_retrieved + || (query->buffer_object && !wined3d_query_buffer_is_valid(query))) + { + if (flags & WINED3DGETDATA_FLUSH && !query->device->cs->queries_flushed) + wined3d_cs_emit_flush(query->device->cs); return S_FALSE; + } + if (query->buffer_object) + query->data = query->map_ptr; } - else if (query->counter_main != query->counter_retrieved) + else if (!query->query_ops->query_poll(query, flags)) { - if (flags & WINED3DGETDATA_FLUSH && !query->device->cs->queries_flushed) - wined3d_cs_emit_flush(query->device->cs); return S_FALSE; } @@ -427,20 +521,19 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD flags) { struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); - struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; GLuint available; TRACE("query %p, flags %#x.\n", query, flags); - if (!(context = context_reacquire(device, oq->context))) + if (!(context_gl = wined3d_context_gl_reacquire(oq->context_gl))) { FIXME("%p Wrong thread, returning 1.\n", query); oq->samples = 1; return TRUE; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available)); TRACE("Available %#x.\n", available); @@ -452,7 +545,7 @@ static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD } checkGLcall("poll occlusion query"); - context_release(context); + context_release(&context_gl->c); return available; } @@ -526,8 +619,8 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD { struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; BOOL poll = FALSE; TRACE("query %p, flags %#x.\n", query, flags); @@ -538,31 +631,33 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD { if (oq->started) { - if ((context = context_reacquire(device, oq->context))) + if ((context_gl = wined3d_context_gl_reacquire(oq->context_gl))) { + gl_info = context_gl->gl_info; GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); checkGLcall("glEndQuery()"); } else { FIXME("Wrong thread, can't restart query.\n"); - context_free_occlusion_query(oq); - context = context_acquire(device, NULL, 0); - context_alloc_occlusion_query(context, oq); + wined3d_context_gl_free_occlusion_query(oq); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + wined3d_context_gl_alloc_occlusion_query(context_gl, oq); } } else { - if (oq->context) - context_free_occlusion_query(oq); - context = context_acquire(device, NULL, 0); - context_alloc_occlusion_query(context, oq); + if (oq->context_gl) + wined3d_context_gl_free_occlusion_query(oq); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + wined3d_context_gl_alloc_occlusion_query(context_gl, oq); } + gl_info = context_gl->gl_info; GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id)); checkGLcall("glBeginQuery()"); - context_release(context); + context_release(&context_gl->c); oq->started = TRUE; } if (flags & WINED3DISSUE_END) @@ -572,12 +667,14 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD * so avoid generating an error. */ if (oq->started) { - if ((context = context_reacquire(device, oq->context))) + if ((context_gl = wined3d_context_gl_reacquire(oq->context_gl))) { + gl_info = context_gl->gl_info; GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); checkGLcall("glEndQuery()"); + wined3d_query_buffer_queue_result(context_gl, query, oq->id); - context_release(context); + context_release(&context_gl->c); poll = TRUE; } else @@ -594,21 +691,20 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query, DWORD flags) { struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); - struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; GLuint64 timestamp; GLuint available; TRACE("query %p, flags %#x.\n", query, flags); - if (!(context = context_reacquire(device, tq->context))) + if (!(context_gl = wined3d_context_gl_reacquire(tq->context_gl))) { FIXME("%p Wrong thread, returning 1.\n", query); tq->timestamp = 1; return TRUE; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); @@ -622,7 +718,7 @@ static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query, DWORD tq->timestamp = timestamp; } - context_release(context); + context_release(&context_gl->c); return available; } @@ -631,7 +727,7 @@ static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD { struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; TRACE("query %p, flags %#x.\n", query, flags); @@ -641,14 +737,14 @@ static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD } if (flags & WINED3DISSUE_END) { - if (tq->context) - context_free_timestamp_query(tq); - context = context_acquire(query->device, NULL, 0); - gl_info = context->gl_info; - context_alloc_timestamp_query(context, tq); + if (tq->context_gl) + wined3d_context_gl_free_timestamp_query(tq); + context_gl = wined3d_context_gl(context_acquire(query->device, NULL, 0)); + gl_info = context_gl->gl_info; + wined3d_context_gl_alloc_timestamp_query(context_gl, tq); GL_EXTCALL(glQueryCounter(tq->id, GL_TIMESTAMP)); checkGLcall("glQueryCounter()"); - context_release(context); + context_release(&context_gl->c); return TRUE; } @@ -673,20 +769,19 @@ static BOOL wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *que static BOOL wined3d_so_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags) { struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query); - struct wined3d_device *device = query->device; GLuint written_available, generated_available; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; TRACE("query %p, flags %#x.\n", query, flags); - if (!(context = context_reacquire(device, pq->context))) + if (!(context_gl = wined3d_context_gl_reacquire(pq->context_gl))) { FIXME("%p Wrong thread, returning 0 primitives.\n", query); memset(&pq->statistics, 0, sizeof(pq->statistics)); return TRUE; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.written, GL_QUERY_RESULT_AVAILABLE, &written_available)); @@ -704,17 +799,35 @@ static BOOL wined3d_so_statistics_query_ops_poll(struct wined3d_query *query, DW } checkGLcall("poll SO statistics query"); - context_release(context); + context_release(&context_gl->c); return written_available && generated_available; } +static void wined3d_so_statistics_query_end(struct wined3d_so_statistics_query *query, + struct wined3d_context_gl *context_gl) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + + if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + { + GL_EXTCALL(glEndQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query->stream_idx)); + GL_EXTCALL(glEndQueryIndexed(GL_PRIMITIVES_GENERATED, query->stream_idx)); + } + else + { + GL_EXTCALL(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)); + GL_EXTCALL(glEndQuery(GL_PRIMITIVES_GENERATED)); + } + checkGLcall("end query"); +} + static BOOL wined3d_so_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags) { struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query); struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; BOOL poll = FALSE; TRACE("query %p, flags %#x.\n", query, flags); @@ -723,47 +836,55 @@ static BOOL wined3d_so_statistics_query_ops_issue(struct wined3d_query *query, D { if (pq->started) { - if ((context = context_reacquire(device, pq->context))) + if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl))) { - GL_EXTCALL(glEndQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, pq->stream_idx)); - GL_EXTCALL(glEndQueryIndexed(GL_PRIMITIVES_GENERATED, pq->stream_idx)); + wined3d_so_statistics_query_end(pq, context_gl); } else { FIXME("Wrong thread, can't restart query.\n"); - context_free_so_statistics_query(pq); - context = context_acquire(device, NULL, 0); - context_alloc_so_statistics_query(context, pq); + wined3d_context_gl_free_so_statistics_query(pq); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + wined3d_context_gl_alloc_so_statistics_query(context_gl, pq); } } else { - if (pq->context) - context_free_so_statistics_query(pq); - context = context_acquire(device, NULL, 0); - context_alloc_so_statistics_query(context, pq); + if (pq->context_gl) + wined3d_context_gl_free_so_statistics_query(pq); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + wined3d_context_gl_alloc_so_statistics_query(context_gl, pq); } + gl_info = context_gl->gl_info; - GL_EXTCALL(glBeginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, - pq->stream_idx, pq->u.query.written)); - GL_EXTCALL(glBeginQueryIndexed(GL_PRIMITIVES_GENERATED, - pq->stream_idx, pq->u.query.generated)); + if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + { + GL_EXTCALL(glBeginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, + pq->stream_idx, pq->u.query.written)); + GL_EXTCALL(glBeginQueryIndexed(GL_PRIMITIVES_GENERATED, + pq->stream_idx, pq->u.query.generated)); + } + else + { + GL_EXTCALL(glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, + pq->u.query.written)); + GL_EXTCALL(glBeginQuery(GL_PRIMITIVES_GENERATED, + pq->u.query.generated)); + } checkGLcall("begin query"); - context_release(context); + context_release(&context_gl->c); pq->started = TRUE; } if (flags & WINED3DISSUE_END) { if (pq->started) { - if ((context = context_reacquire(device, pq->context))) + if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl))) { - GL_EXTCALL(glEndQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, pq->stream_idx)); - GL_EXTCALL(glEndQueryIndexed(GL_PRIMITIVES_GENERATED, pq->stream_idx)); - checkGLcall("end query"); + wined3d_so_statistics_query_end(pq, context_gl); - context_release(context); + context_release(&context_gl->c); poll = TRUE; } else @@ -780,21 +901,20 @@ static BOOL wined3d_so_statistics_query_ops_issue(struct wined3d_query *query, D static BOOL wined3d_pipeline_query_ops_poll(struct wined3d_query *query, DWORD flags) { struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query); - struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; GLuint available; int i; TRACE("query %p, flags %#x.\n", query, flags); - if (!(context = context_reacquire(device, pq->context))) + if (!(context_gl = wined3d_context_gl_reacquire(pq->context_gl))) { FIXME("%p Wrong thread.\n", query); memset(&pq->statistics, 0, sizeof(pq->statistics)); return TRUE; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; for (i = 0; i < ARRAY_SIZE(pq->u.id); ++i) { @@ -819,14 +939,14 @@ static BOOL wined3d_pipeline_query_ops_poll(struct wined3d_query *query, DWORD f } checkGLcall("poll pipeline statistics query"); - context_release(context); + context_release(&context_gl->c); return available; } static void wined3d_pipeline_statistics_query_end(struct wined3d_pipeline_statistics_query *query, - struct wined3d_context *context) + struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; GL_EXTCALL(glEndQuery(GL_VERTICES_SUBMITTED_ARB)); GL_EXTCALL(glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB)); @@ -846,8 +966,8 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD { struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query); struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; BOOL poll = FALSE; TRACE("query %p, flags %#x.\n", query, flags); @@ -856,25 +976,26 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD { if (pq->started) { - if ((context = context_reacquire(device, pq->context))) + if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl))) { - wined3d_pipeline_statistics_query_end(pq, context); + wined3d_pipeline_statistics_query_end(pq, context_gl); } else { FIXME("Wrong thread, can't restart query.\n"); - context_free_pipeline_statistics_query(pq); - context = context_acquire(device, NULL, 0); - context_alloc_pipeline_statistics_query(context, pq); + wined3d_context_gl_free_pipeline_statistics_query(pq); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + wined3d_context_gl_alloc_pipeline_statistics_query(context_gl, pq); } } else { - if (pq->context) - context_free_pipeline_statistics_query(pq); - context = context_acquire(device, NULL, 0); - context_alloc_pipeline_statistics_query(context, pq); + if (pq->context_gl) + wined3d_context_gl_free_pipeline_statistics_query(pq); + context_gl = wined3d_context_gl(context_acquire(device, NULL, 0)); + wined3d_context_gl_alloc_pipeline_statistics_query(context_gl, pq); } + gl_info = context_gl->gl_info; GL_EXTCALL(glBeginQuery(GL_VERTICES_SUBMITTED_ARB, pq->u.query.vertices)); GL_EXTCALL(glBeginQuery(GL_PRIMITIVES_SUBMITTED_ARB, pq->u.query.primitives)); @@ -889,17 +1010,17 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD GL_EXTCALL(glBeginQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB, pq->u.query.clipping_output)); checkGLcall("begin query"); - context_release(context); + context_release(&context_gl->c); pq->started = TRUE; } if (flags & WINED3DISSUE_END) { if (pq->started) { - if ((context = context_reacquire(device, pq->context))) + if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl))) { - wined3d_pipeline_statistics_query_end(pq, context); - context_release(context); + wined3d_pipeline_statistics_query_end(pq, context_gl); + context_release(&context_gl->c); poll = TRUE; } else @@ -990,8 +1111,8 @@ static void wined3d_occlusion_query_ops_destroy(struct wined3d_query *query) { struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); - if (oq->context) - context_free_occlusion_query(oq); + if (oq->context_gl) + wined3d_context_gl_free_occlusion_query(oq); heap_free(oq); } @@ -1034,8 +1155,8 @@ static void wined3d_timestamp_query_ops_destroy(struct wined3d_query *query) { struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); - if (tq->context) - context_free_timestamp_query(tq); + if (tq->context_gl) + wined3d_context_gl_free_timestamp_query(tq); heap_free(tq); } @@ -1130,8 +1251,8 @@ static void wined3d_so_statistics_query_ops_destroy(struct wined3d_query *query) { struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query); - if (pq->context) - context_free_so_statistics_query(pq); + if (pq->context_gl) + wined3d_context_gl_free_so_statistics_query(pq); heap_free(pq); } @@ -1152,6 +1273,8 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device, if (WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0 <= type && type <= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3) stream_idx = type - WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0; + else if (type == WINED3D_QUERY_TYPE_SO_STATISTICS) + stream_idx = 0; else return WINED3DERR_NOTAVAILABLE; @@ -1163,7 +1286,7 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device, WARN("OpenGL implementation does not support primitive queries.\n"); return WINED3DERR_NOTAVAILABLE; } - if (!gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + if (stream_idx && !gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) { WARN("OpenGL implementation does not support indexed queries.\n"); return WINED3DERR_NOTAVAILABLE; @@ -1185,8 +1308,8 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device, static void wined3d_pipeline_query_ops_destroy(struct wined3d_query *query) { struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query); - if (pq->context) - context_free_pipeline_statistics_query(pq); + if (pq->context_gl) + wined3d_context_gl_free_pipeline_statistics_query(pq); heap_free(pq); } @@ -1237,6 +1360,8 @@ static const struct wined3d_query_ops statistics_query_ops = wined3d_statistics_query_ops_destroy, }; +#ifdef __REACTOS__ +#else static HRESULT wined3d_statistics_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) @@ -1257,6 +1382,7 @@ static HRESULT wined3d_statistics_query_create(struct wined3d_device *device, return WINED3D_OK; } +#endif static void wined3d_overflow_query_ops_destroy(struct wined3d_query *query) { @@ -1291,7 +1417,7 @@ static HRESULT wined3d_overflow_query_create(struct wined3d_device *device, return WINED3D_OK; } -HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type, +HRESULT wined3d_query_gl_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) { TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", @@ -1312,6 +1438,7 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_q case WINED3D_QUERY_TYPE_TIMESTAMP_FREQ: return wined3d_timestamp_disjoint_query_create(device, type, parent, parent_ops, query); + case WINED3D_QUERY_TYPE_SO_STATISTICS: case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0: case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1: case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2: @@ -1319,10 +1446,7 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_q return wined3d_so_statistics_query_create(device, type, parent, parent_ops, query); case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS: - return wined3d_pipeline_query_create(device, type, parent, parent_ops, query); - - case WINED3D_QUERY_TYPE_SO_STATISTICS: - return wined3d_statistics_query_create(device, type, parent, parent_ops, query); + return wined3d_pipeline_query_create(device, type, parent, parent_ops, query);\ case WINED3D_QUERY_TYPE_SO_OVERFLOW: return wined3d_overflow_query_create(device, type, parent, parent_ops, query); @@ -1332,3 +1456,12 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_q return WINED3DERR_NOTAVAILABLE; } } + +HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) +{ + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + return device->adapter->adapter_ops->adapter_create_query(device, type, parent, parent_ops, query); +} diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c index 8b7f17bb6bd..5b2e624dd07 100644 --- a/dll/directx/wine/wined3d/resource.c +++ b/dll/directx/wine/wined3d/resource.c @@ -28,41 +28,36 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); -static void resource_check_usage(DWORD usage) +static void resource_check_usage(DWORD usage, unsigned int access) { - static DWORD handled = WINED3DUSAGE_RENDERTARGET - | WINED3DUSAGE_DEPTHSTENCIL - | WINED3DUSAGE_WRITEONLY - | WINED3DUSAGE_DYNAMIC + static const DWORD handled = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_STATICDECL | WINED3DUSAGE_OVERLAY | WINED3DUSAGE_SCRATCH | WINED3DUSAGE_PRIVATE | WINED3DUSAGE_LEGACY_CUBEMAP - | WINED3DUSAGE_TEXTURE; + | ~WINED3DUSAGE_MASK; - /* WINED3DUSAGE_WRITEONLY is supposed to result in write-combined mappings + /* Write-only CPU access is supposed to result in write-combined mappings * being returned. OpenGL doesn't give us explicit control over that, but * the hints and access flags we set for typical access patterns on * dynamic resources should in theory have the same effect on the OpenGL * driver. */ if (usage & ~handled) - { FIXME("Unhandled usage flags %#x.\n", usage & ~handled); - handled |= usage; - } - if ((usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY)) == WINED3DUSAGE_DYNAMIC) - WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used without WINED3DUSAGE_WRITEONLY.\n"); + if (usage & WINED3DUSAGE_DYNAMIC && access & WINED3D_RESOURCE_ACCESS_MAP_R) + WARN_(d3d_perf)("WINED3DUSAGE_DYNAMIC used with WINED3D_RESOURCE_ACCESS_MAP_R.\n"); } HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, - enum wined3d_multisample_type multisample_type, unsigned int multisample_quality, - unsigned int usage, unsigned int access, unsigned int width, unsigned int height, unsigned int depth, + enum wined3d_multisample_type multisample_type, unsigned int multisample_quality, unsigned int usage, + unsigned int bind_flags, unsigned int access, unsigned int width, unsigned int height, unsigned int depth, unsigned int size, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) { + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; enum wined3d_gl_resource_type base_type = WINED3D_GL_RES_TYPE_COUNT; enum wined3d_gl_resource_type gl_type = WINED3D_GL_RES_TYPE_COUNT; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; @@ -86,7 +81,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * {WINED3D_RTYPE_TEXTURE_3D, 0, WINED3D_GL_RES_TYPE_TEX_3D}, }; - resource_check_usage(usage); + resource_check_usage(usage, access); if (usage & WINED3DUSAGE_SCRATCH && access & WINED3D_RESOURCE_ACCESS_GPU) { @@ -95,6 +90,27 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * return WINED3DERR_INVALIDCALL; } + if (bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL)) + { + if ((access & (WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_GPU)) != WINED3D_RESOURCE_ACCESS_GPU) + { + WARN("Bind flags %s are incompatible with resource access %s.\n", + wined3d_debug_bind_flags(bind_flags), wined3d_debug_resource_access(access)); + return WINED3DERR_INVALIDCALL; + } + + /* Dynamic usage is incompatible with GPU writes. */ + if (usage & WINED3DUSAGE_DYNAMIC) + { + WARN("Bind flags %s are incompatible with resource usage %s.\n", + wined3d_debug_bind_flags(bind_flags), debug_d3dusage(usage)); + return WINED3DERR_INVALIDCALL; + } + } + + if (!size) + ERR("Attempting to create a zero-sized resource.\n"); + for (i = 0; i < ARRAY_SIZE(resource_types); ++i) { if (resource_types[i].type != type @@ -105,31 +121,36 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * if (base_type == WINED3D_GL_RES_TYPE_COUNT) base_type = gl_type; - if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET)) - { - WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id)); - continue; - } - if ((usage & WINED3DUSAGE_DEPTHSTENCIL) - && !(format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) + if (type != WINED3D_RTYPE_BUFFER) { - WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id)); - continue; - } - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL) - && !(format->flags[gl_type] & WINED3DFMT_FLAG_FBO_ATTACHABLE)) - { - WARN("Render target or depth stencil is not FBO attachable.\n"); - continue; - } - if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags[gl_type] & WINED3DFMT_FLAG_TEXTURE)) - { - WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id)); - continue; + if ((bind_flags & WINED3D_BIND_RENDER_TARGET) + && !(format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET)) + { + WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id)); + continue; + } + if ((bind_flags & WINED3D_BIND_DEPTH_STENCIL) + && !(format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) + { + WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id)); + continue; + } + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL) + && !(format->flags[gl_type] & WINED3DFMT_FLAG_FBO_ATTACHABLE)) + { + WARN("Render target or depth stencil is not FBO attachable.\n"); + continue; + } + if ((bind_flags & WINED3D_BIND_SHADER_RESOURCE) + && !(format->flags[gl_type] & WINED3DFMT_FLAG_TEXTURE)) + { + WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id)); + continue; + } } if (((width & (width - 1)) || (height & (height - 1))) - && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] + && !d3d_info->texture_npot && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] && gl_type == WINED3D_GL_RES_TYPE_TEX_2D) { @@ -181,6 +202,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->multisample_type = multisample_type; resource->multisample_quality = multisample_quality; resource->usage = usage; + resource->bind_flags = bind_flags; + if (resource->format_flags & WINED3DFMT_FLAG_MAPPABLE) + access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; resource->access = access; resource->width = width; resource->height = height; @@ -191,19 +215,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; resource->map_binding = WINED3D_LOCATION_SYSMEM; - - if (size) - { - if (!wined3d_resource_allocate_sysmem(resource)) - { - ERR("Failed to allocate system memory.\n"); - return E_OUTOFMEMORY; - } - } - else - { - resource->heap_memory = NULL; - } + resource->heap_memory = NULL; if (!(usage & WINED3DUSAGE_PRIVATE)) { @@ -212,8 +224,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * { if (size > wined3d_device_get_available_texture_mem(device)) { - ERR("Out of adapter memory\n"); - wined3d_resource_free_sysmem(resource); + ERR("Out of adapter memory.\n"); return WINED3DERR_OUTOFVIDEOMEMORY; } adapter_adjust_memory(device->adapter, size); @@ -230,7 +241,7 @@ static void wined3d_resource_destroy_object(void *object) struct wined3d_resource *resource = object; wined3d_resource_free_sysmem(resource); - context_resource_released(resource->device, resource, resource->type); + context_resource_released(resource->device, resource); wined3d_resource_release(resource); } @@ -299,6 +310,7 @@ void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, st desc->multisample_type = resource->multisample_type; desc->multisample_quality = resource->multisample_quality; desc->usage = resource->usage; + desc->bind_flags = resource->bind_flags; desc->access = resource->access; desc->width = resource->width; desc->height = resource->height; @@ -484,14 +496,17 @@ void CDECL wined3d_resource_preload(struct wined3d_resource *resource) wined3d_cs_emit_preload_resource(resource->device->cs, resource); } -BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) +static BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) { void **p; SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p); void *mem; if (!(mem = heap_alloc_zero(resource->size + align))) + { + ERR("Failed to allocate system memory.\n"); return FALSE; + } p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; *p = mem; @@ -501,6 +516,14 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) return TRUE; } +BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource) +{ + if (resource->heap_memory) + return TRUE; + + return wined3d_resource_allocate_sysmem(resource); +} + void wined3d_resource_free_sysmem(struct wined3d_resource *resource) { void **p = resource->heap_memory; @@ -567,17 +590,15 @@ BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) { + const struct wined3d_d3d_info *d3d_info = &resource->device->adapter->d3d_info; + if (!wined3d_resource_is_offscreen(resource) || wined3d_settings.offscreen_rendering_mode != ORM_FBO) { resource->draw_binding = WINED3D_LOCATION_DRAWABLE; } else if (resource->multisample_type) { - const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info; - if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) - resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; - else - resource->draw_binding = WINED3D_LOCATION_RB_MULTISAMPLE; + resource->draw_binding = d3d_info->multisample_draw_location; } else if (resource->gl_type == WINED3D_GL_RES_TYPE_RB) { @@ -588,3 +609,44 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; } } + +const struct wined3d_format *wined3d_resource_get_decompress_format(const struct wined3d_resource *resource) +{ + const struct wined3d_adapter *adapter = resource->device->adapter; + if (resource->format_flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE) + && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) + return wined3d_get_format(adapter, WINED3DFMT_B8G8R8A8_UNORM_SRGB, resource->bind_flags); + return wined3d_get_format(adapter, WINED3DFMT_B8G8R8A8_UNORM, resource->bind_flags); +} + +unsigned int wined3d_resource_get_sample_count(const struct wined3d_resource *resource) +{ + const struct wined3d_format *format = resource->format; + + /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA) + * feature through type == MULTISAMPLE_XX and quality != 0. This could + * be mapped to GL_NV_framebuffer_multisample_coverage. + * + * AMD have a similar feature called Enhanced Quality Anti-Aliasing + * (EQAA), but it does not have an equivalent OpenGL extension. */ + + /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality + * levels as the count of advertised multisample types for the texture + * format. */ + if (resource->multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) + { + unsigned int i, count = 0; + + for (i = 0; i < sizeof(format->multisample_types) * CHAR_BIT; ++i) + { + if (format->multisample_types & 1u << i) + { + if (resource->multisample_quality == count++) + break; + } + } + return i + 1; + } + + return resource->multisample_type; +} diff --git a/dll/directx/wine/wined3d/sampler.c b/dll/directx/wine/wined3d/sampler.c index 82fbe2c3be7..c4f4d3eec30 100644 --- a/dll/directx/wine/wined3d/sampler.c +++ b/dll/directx/wine/wined3d/sampler.c @@ -33,23 +33,6 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler) return refcount; } -static void wined3d_sampler_destroy_object(void *object) -{ - struct wined3d_sampler *sampler = object; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - if (sampler->name) - { - context = context_acquire(sampler->device, NULL, 0); - gl_info = context->gl_info; - GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); - context_release(context); - } - - heap_free(sampler); -} - ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) { ULONG refcount = InterlockedDecrement(&sampler->refcount); @@ -59,7 +42,7 @@ ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) if (!refcount) { sampler->parent_ops->wined3d_object_destroyed(sampler->parent); - wined3d_cs_destroy_object(sampler->device->cs, wined3d_sampler_destroy_object, sampler); + sampler->device->adapter->adapter_ops->adapter_destroy_sampler(sampler); } return refcount; @@ -72,67 +55,89 @@ void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler) return sampler->parent; } -static void wined3d_sampler_cs_init(void *object) +static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device, + const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("sampler %p, device %p, desc %p, parent %p, parent_ops %p.\n", + sampler, device, desc, parent, parent_ops); + + sampler->refcount = 1; + sampler->device = device; + sampler->parent = parent; + sampler->parent_ops = parent_ops; + sampler->desc = *desc; +} + +static void wined3d_sampler_gl_cs_init(void *object) { - struct wined3d_sampler *sampler = object; + struct wined3d_sampler_gl *sampler_gl = object; const struct wined3d_sampler_desc *desc; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; + GLuint name; - context = context_acquire(sampler->device, NULL, 0); - gl_info = context->gl_info; + context = context_acquire(sampler_gl->s.device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; - desc = &sampler->desc; - GL_EXTCALL(glGenSamplers(1, &sampler->name)); - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_S, + desc = &sampler_gl->s.desc; + GL_EXTCALL(glGenSamplers(1, &name)); + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_WRAP_S, gl_info->wrap_lookup[desc->address_u - WINED3D_TADDRESS_WRAP])); - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_T, + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_WRAP_T, gl_info->wrap_lookup[desc->address_v - WINED3D_TADDRESS_WRAP])); - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_R, + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_WRAP_R, gl_info->wrap_lookup[desc->address_w - WINED3D_TADDRESS_WRAP])); - GL_EXTCALL(glSamplerParameterfv(sampler->name, GL_TEXTURE_BORDER_COLOR, &desc->border_color[0])); - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAG_FILTER, + GL_EXTCALL(glSamplerParameterfv(name, GL_TEXTURE_BORDER_COLOR, &desc->border_color[0])); + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(desc->mag_filter))); - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MIN_FILTER, + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_MIN_FILTER, wined3d_gl_min_mip_filter(desc->min_filter, desc->mip_filter))); - GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_LOD_BIAS, desc->lod_bias)); - GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MIN_LOD, desc->min_lod)); - GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MAX_LOD, desc->max_lod)); + GL_EXTCALL(glSamplerParameterf(name, GL_TEXTURE_LOD_BIAS, desc->lod_bias)); + GL_EXTCALL(glSamplerParameterf(name, GL_TEXTURE_MIN_LOD, desc->min_lod)); + GL_EXTCALL(glSamplerParameterf(name, GL_TEXTURE_MAX_LOD, desc->max_lod)); if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC]) - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAX_ANISOTROPY, desc->max_anisotropy)); + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_MAX_ANISOTROPY, desc->max_anisotropy)); if (desc->compare) - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)); - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_FUNC, + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)); + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_COMPARE_FUNC, wined3d_gl_compare_func(desc->comparison_func))); if ((context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) && gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && !desc->srgb_decode) - GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)); + GL_EXTCALL(glSamplerParameteri(name, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)); checkGLcall("sampler creation"); - TRACE("Created sampler %u.\n", sampler->name); + TRACE("Created sampler %u.\n", name); + sampler_gl->name = name; context_release(context); } -static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device, +void wined3d_sampler_gl_init(struct wined3d_sampler_gl *sampler_gl, struct wined3d_device *device, const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { - sampler->refcount = 1; - sampler->device = device; - sampler->parent = parent; - sampler->parent_ops = parent_ops; - sampler->desc = *desc; + TRACE("sampler_gl %p, device %p, desc %p, parent %p, parent_ops %p.\n", + sampler_gl, device, desc, parent, parent_ops); + + wined3d_sampler_init(&sampler_gl->s, device, desc, parent, parent_ops); if (device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS]) - wined3d_cs_init_object(device->cs, wined3d_sampler_cs_init, sampler); + wined3d_cs_init_object(device->cs, wined3d_sampler_gl_cs_init, sampler_gl); +} + +void wined3d_sampler_vk_init(struct wined3d_sampler *sampler_vk, struct wined3d_device *device, + const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("sampler_vk %p, device %p, desc %p, parent %p, parent_ops %p.\n", + sampler_vk, device, desc, parent, parent_ops); + + wined3d_sampler_init(sampler_vk, device, desc, parent, parent_ops); } HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler) { - struct wined3d_sampler *object; - - TRACE("device %p, desc %p, parent %p, sampler %p.\n", device, desc, parent, sampler); + TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n", + device, desc, parent, parent_ops, sampler); if (desc->address_u < WINED3D_TADDRESS_WRAP || desc->address_u > WINED3D_TADDRESS_MIRROR_ONCE || desc->address_v < WINED3D_TADDRESS_WRAP || desc->address_v > WINED3D_TADDRESS_MIRROR_ONCE @@ -144,62 +149,54 @@ HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct || desc->mip_filter > WINED3D_TEXF_LINEAR) return WINED3DERR_INVALIDCALL; - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; - - wined3d_sampler_init(object, device, desc, parent, parent_ops); - - TRACE("Created sampler %p.\n", object); - *sampler = object; - - return WINED3D_OK; + return device->adapter->adapter_ops->adapter_create_sampler(device, desc, parent, parent_ops, sampler); } -static void texture_apply_base_level(struct wined3d_texture *texture, +static void texture_gl_apply_base_level(struct wined3d_texture_gl *texture_gl, const struct wined3d_sampler_desc *desc, const struct wined3d_gl_info *gl_info) { struct gl_texture *gl_tex; unsigned int base_level; - if (texture->flags & WINED3D_TEXTURE_COND_NP2) + if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) base_level = 0; else if (desc->mip_filter == WINED3D_TEXF_NONE) - base_level = texture->lod; + base_level = texture_gl->t.lod; else - base_level = min(max(desc->mip_base_level, texture->lod), texture->level_count - 1); + base_level = min(max(desc->mip_base_level, texture_gl->t.lod), texture_gl->t.level_count - 1); - gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB); + gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, texture_gl->t.flags & WINED3D_TEXTURE_IS_SRGB); if (base_level != gl_tex->base_level) { /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest * mipmap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL * corresponds to GL_TEXTURE_BASE_LEVEL. */ - gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level); + gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_BASE_LEVEL, base_level); gl_tex->base_level = base_level; } } /* This function relies on the correct texture being bound and loaded. */ -void wined3d_sampler_bind(struct wined3d_sampler *sampler, unsigned int unit, - struct wined3d_texture *texture, const struct wined3d_context *context) +void wined3d_sampler_gl_bind(struct wined3d_sampler_gl *sampler_gl, unsigned int unit, + struct wined3d_texture_gl *texture_gl, const struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; if (gl_info->supported[ARB_SAMPLER_OBJECTS]) { - GL_EXTCALL(glBindSampler(unit, sampler->name)); + GL_EXTCALL(glBindSampler(unit, sampler_gl->name)); checkGLcall("bind sampler"); } - else if (texture) + else if (texture_gl) { - wined3d_texture_apply_sampler_desc(texture, &sampler->desc, context); + wined3d_texture_gl_apply_sampler_desc(texture_gl, &sampler_gl->s.desc, context_gl); } else { ERR("Could not apply sampler state.\n"); } - if (texture) - texture_apply_base_level(texture, &sampler->desc, gl_info); + if (texture_gl) + texture_gl_apply_base_level(texture_gl, &sampler_gl->s.desc, gl_info); } diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c index 0513c9e2053..de4776b30c1 100644 --- a/dll/directx/wine/wined3d/shader.c +++ b/dll/directx/wine/wined3d/shader.c @@ -32,10 +32,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); -/* pow, mul_high, sub_high, mul_low */ -const float wined3d_srgb_const0[] = {0.41666f, 1.055f, 0.055f, 12.92f}; -/* cmp */ -const float wined3d_srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f}; +const struct wined3d_vec4 wined3d_srgb_const[] = +{ + /* pow, mul_high, sub_high, mul_low */ + {0.41666f, 1.055f, 0.055f, 12.92f}, + /* cmp */ + {0.0031308f, 0.0f, 0.0f, 0.0f}, +}; static const char * const shader_opcode_names[] = { @@ -125,7 +128,6 @@ static const char * const shader_opcode_names[] = /* WINED3DSIH_DSY */ "dsy", /* WINED3DSIH_DSY_COARSE */ "deriv_rty_coarse", /* WINED3DSIH_DSY_FINE */ "deriv_rty_fine", - /* WINED3DSIH_EVAL_SAMPLE_INDEX */ "eval_sample_index", /* WINED3DSIH_ELSE */ "else", /* WINED3DSIH_EMIT */ "emit", /* WINED3DSIH_EMIT_STREAM */ "emit_stream", @@ -134,6 +136,7 @@ static const char * const shader_opcode_names[] = /* WINED3DSIH_ENDREP */ "endrep", /* WINED3DSIH_ENDSWITCH */ "endswitch", /* WINED3DSIH_EQ */ "eq", + /* WINED3DSIH_EVAL_SAMPLE_INDEX */ "eval_sample_index", /* WINED3DSIH_EXP */ "exp", /* WINED3DSIH_EXPP */ "expp", /* WINED3DSIH_F16TOF32 */ "f16tof32", @@ -589,7 +592,7 @@ static void shader_delete_constant_list(struct list *clist) list_init(clist); } -static void shader_set_limits(struct wined3d_shader *shader) +static void shader_set_limits(struct wined3d_shader *shader, BOOL swvp) { static const struct limits_entry { @@ -612,6 +615,19 @@ static void shader_set_limits(struct wined3d_shader *shader) {WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}}, {0} }, + vs_limits_swvp[] = + { + /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */ + {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0, 0, 8192, 0, 12, 0}}, + {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 255), { 0, 16, 8192, 16, 12, 0}}, + /* DX10 cards on Windows advertise a D3D9 constant limit of 256 + * even though they are capable of supporting much more (GL + * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the + * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 + * shaders to 256. */ + {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 255), { 4, 16, 8192, 16, 12, 0}}, + {0} + }, hs_limits[] = { /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */ @@ -656,7 +672,7 @@ static void shader_set_limits(struct wined3d_shader *shader) FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type); /* Fall-through. */ case WINED3D_SHADER_TYPE_VERTEX: - limits_array = vs_limits; + limits_array = swvp ? vs_limits_swvp : vs_limits; break; case WINED3D_SHADER_TYPE_HULL: limits_array = hs_limits; @@ -764,6 +780,8 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w } else { + if (reg->idx[0].offset >= reg_maps->constant_float_count) + reg_maps->constant_float_count = reg->idx[0].offset + 1; wined3d_insert_bits(reg_maps->constf, reg->idx[0].offset, 1, 0x1); } } @@ -801,6 +819,10 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w reg_maps->vocp = 1; break; + case WINED3DSPR_SAMPLEMASK: + reg_maps->sample_mask = 1; + break; + default: TRACE("Not recording register of type %#x and [%#x][%#x].\n", reg->type, reg->idx[0].offset, reg->idx[1].offset); @@ -915,7 +937,7 @@ static HRESULT shader_record_shader_phase(struct wined3d_shader *shader, if (shader->reg_maps.shader_version.type != WINED3D_SHADER_TYPE_HULL) { - ERR("Unexpected shader type %#x.\n", shader->reg_maps.shader_version.type); + ERR("Unexpected shader type %s.\n", debug_shader_type(shader->reg_maps.shader_version.type)); return E_FAIL; } @@ -962,7 +984,7 @@ static HRESULT shader_calculate_clip_or_cull_distance_mask( /* Clip and cull distances are packed in 4 component registers. 0 and 1 are * the only allowed semantic indices. */ - if (e->semantic_idx >= MAX_CLIP_DISTANCES / 4) + if (e->semantic_idx >= WINED3D_MAX_CLIP_DISTANCES / 4) { *mask = 0; WARN("Invalid clip/cull distance index %u.\n", e->semantic_idx); @@ -983,13 +1005,49 @@ static void wined3d_insert_interpolation_mode(DWORD *packed_interpolation_mode, register_idx * WINED3D_PACKED_INTERPOLATION_BIT_COUNT, WINED3D_PACKED_INTERPOLATION_BIT_COUNT, mode); } +static HRESULT shader_scan_output_signature(struct wined3d_shader *shader) +{ + const struct wined3d_shader_signature *output_signature = &shader->output_signature; + struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + unsigned int i; + HRESULT hr; + + for (i = 0; i < output_signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *e = &output_signature->elements[i]; + unsigned int mask; + + reg_maps->output_registers |= 1u << e->register_idx; + if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE) + { + if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) + return hr; + reg_maps->clip_distance_mask |= mask; + } + else if (e->sysval_semantic == WINED3D_SV_CULL_DISTANCE) + { + if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) + return hr; + reg_maps->cull_distance_mask |= mask; + } + else if (e->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX) + { + reg_maps->viewport_array = 1; + } + } + + return WINED3D_OK; +} + /* Note that this does not count the loop register as an address register. */ -static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe, - struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature, - struct wined3d_shader_signature *output_signature, DWORD constf_size) +static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size, BOOL swvp) { struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)]; struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT]; + struct wined3d_shader_signature *output_signature = &shader->output_signature; + struct wined3d_shader_signature *input_signature = &shader->input_signature; + struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_shader_frontend *fe = shader->frontend; unsigned int cur_loop_depth = 0, max_loop_depth = 0; struct wined3d_shader_version shader_version; struct wined3d_shader_phase *phase = NULL; @@ -1008,7 +1066,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st prev_ins = current_ins = ptr; reg_maps->shader_version = shader_version; - shader_set_limits(shader); + shader_set_limits(shader, swvp); if (!(reg_maps->constf = heap_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32), sizeof(*reg_maps->constf)))) @@ -1667,7 +1725,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st shader_record_sample(reg_maps, ins.src[2].reg.idx[0].offset, ins.src[3].reg.idx[0].offset, reg_maps->sampler_map.count); } - else if (ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE) + else if ((ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE) + || (ins.handler_idx == WINED3DSIH_SAMPLE_INFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE)) { shader_record_sample(reg_maps, ins.src[0].reg.idx[0].offset, WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count); @@ -1780,25 +1839,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st if (output_signature->elements) { - for (i = 0; i < output_signature->element_count; ++i) - { - const struct wined3d_shader_signature_element *e = &output_signature->elements[i]; - unsigned int mask; - - reg_maps->output_registers |= 1u << e->register_idx; - if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE) - { - if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) - return hr; - reg_maps->clip_distance_mask |= mask; - } - else if (e->sysval_semantic == WINED3D_SV_CULL_DISTANCE) - { - if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask))) - return hr; - reg_maps->cull_distance_mask |= mask; - } - } + if (FAILED(hr = shader_scan_output_signature(shader))) + return hr; } else if (reg_maps->output_registers) { @@ -1889,6 +1931,23 @@ static void shader_dump_sync_flags(struct wined3d_string_buffer *buffer, DWORD s shader_addline(buffer, "_unknown_flags(%#x)", sync_flags); } +static void shader_dump_precise_flags(struct wined3d_string_buffer *buffer, DWORD flags) +{ + if (!(flags & WINED3DSI_PRECISE_XYZW)) + return; + + shader_addline(buffer, " [precise"); + if (flags != WINED3DSI_PRECISE_XYZW) + { + shader_addline(buffer, "(%s%s%s%s)", + flags & WINED3DSI_PRECISE_X ? "x" : "", + flags & WINED3DSI_PRECISE_Y ? "y" : "", + flags & WINED3DSI_PRECISE_Z ? "z" : "", + flags & WINED3DSI_PRECISE_W ? "w" : ""); + } + shader_addline(buffer, "]"); +} + static void shader_dump_uav_flags(struct wined3d_string_buffer *buffer, DWORD uav_flags) { if (uav_flags & WINED3DSUF_GLOBALLY_COHERENT) @@ -2291,6 +2350,10 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer, shader_addline(buffer, "null"); break; + case WINED3DSPR_RASTERIZER: + shader_addline(buffer, "rasterizer"); + break; + case WINED3DSPR_RESOURCE: shader_addline(buffer, "t"); break; @@ -3052,6 +3115,10 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe { shader_dump_sync_flags(&buffer, ins.flags); } + else + { + shader_dump_precise_flags(&buffer, ins.flags); + } if (wined3d_shader_instruction_has_texel_offset(&ins)) shader_addline(&buffer, "(%d,%d,%d)", ins.texel_offset.u, ins.texel_offset.v, ins.texel_offset.w); @@ -3095,16 +3162,15 @@ static void shader_cleanup(struct wined3d_shader *shader) } else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) { - heap_free(shader->u.gs.so_desc.elements); + heap_free((void *)shader->u.gs.so_desc.elements); } heap_free(shader->patch_constant_signature.elements); heap_free(shader->output_signature.elements); heap_free(shader->input_signature.elements); - heap_free(shader->signature_strings); shader->device->shader_backend->shader_destroy(shader); shader_cleanup_reg_maps(&shader->reg_maps); - heap_free(shader->function); + heap_free(shader->byte_code); shader_delete_constant_list(&shader->constantsF); shader_delete_constant_list(&shader->constantsB); shader_delete_constant_list(&shader->constantsI); @@ -3117,7 +3183,7 @@ static void shader_cleanup(struct wined3d_shader *shader) struct shader_none_priv { const struct wined3d_vertex_pipe_ops *vertex_pipe; - const struct fragment_pipeline *fragment_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; BOOL ffp_proj_control; }; @@ -3137,21 +3203,19 @@ static void shader_none_init_context_state(struct wined3d_context *context) {} static void shader_none_select(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) { - const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_none_priv *priv = shader_priv; - priv->vertex_pipe->vp_enable(gl_info, !use_vs(state)); - priv->fragment_pipe->enable_extension(gl_info, !use_ps(state)); + priv->vertex_pipe->vp_enable(context, !use_vs(state)); + priv->fragment_pipe->fp_enable(context, !use_ps(state)); } /* Context activation is done by the caller. */ static void shader_none_disable(void *shader_priv, struct wined3d_context *context) { struct shader_none_priv *priv = shader_priv; - const struct wined3d_gl_info *gl_info = context->gl_info; - priv->vertex_pipe->vp_enable(gl_info, FALSE); - priv->fragment_pipe->enable_extension(gl_info, FALSE); + priv->vertex_pipe->vp_enable(context, FALSE); + priv->fragment_pipe->fp_enable(context, FALSE); context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) @@ -3162,7 +3226,7 @@ static void shader_none_disable(void *shader_priv, struct wined3d_context *conte } static HRESULT shader_none_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, - const struct fragment_pipeline *fragment_pipe) + const struct wined3d_fragment_pipe_ops *fragment_pipe) { struct fragment_caps fragment_caps; void *vertex_priv, *fragment_priv; @@ -3181,14 +3245,14 @@ static HRESULT shader_none_alloc(struct wined3d_device *device, const struct win if (!(fragment_priv = fragment_pipe->alloc_private(&none_shader_backend, priv))) { ERR("Failed to initialize fragment pipe.\n"); - vertex_pipe->vp_free(device); + vertex_pipe->vp_free(device, NULL); heap_free(priv); return E_FAIL; } priv->vertex_pipe = vertex_pipe; priv->fragment_pipe = fragment_pipe; - fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps); + fragment_pipe->get_caps(device->adapter, &fragment_caps); priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; device->vertex_priv = vertex_priv; @@ -3198,12 +3262,12 @@ static HRESULT shader_none_alloc(struct wined3d_device *device, const struct win return WINED3D_OK; } -static void shader_none_free(struct wined3d_device *device) +static void shader_none_free(struct wined3d_device *device, struct wined3d_context *context) { struct shader_none_priv *priv = device->shader_priv; - priv->fragment_pipe->free_private(device); - priv->vertex_pipe->vp_free(device); + priv->fragment_pipe->free_private(device, context); + priv->vertex_pipe->vp_free(device, context); heap_free(priv); } @@ -3212,20 +3276,10 @@ static BOOL shader_none_allocate_context_data(struct wined3d_context *context) return TRUE; } -static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) +static void shader_none_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps) { /* Set the shader caps to 0 for the none shader backend */ - caps->vs_version = 0; - caps->hs_version = 0; - caps->ds_version = 0; - caps->gs_version = 0; - caps->ps_version = 0; - caps->cs_version = 0; - caps->vs_uniform_count = 0; - caps->ps_uniform_count = 0; - caps->ps_1x_max_value = 0.0f; - caps->varying_count = 0; - caps->wined3d_caps = 0; + memset(caps, 0, sizeof(*caps)); } static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup) @@ -3263,17 +3317,38 @@ const struct wined3d_shader_backend_ops none_shader_backend = shader_none_has_ffp_proj_control, }; -static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_const_count, - enum wined3d_shader_type type, unsigned int max_version) +static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_level level) { + switch (level) + { + case WINED3D_FEATURE_LEVEL_11_1: + case WINED3D_FEATURE_LEVEL_11: + return 5; + case WINED3D_FEATURE_LEVEL_10_1: + case WINED3D_FEATURE_LEVEL_10: + return 4; + case WINED3D_FEATURE_LEVEL_9_3: + return 3; + case WINED3D_FEATURE_LEVEL_9_2: + case WINED3D_FEATURE_LEVEL_9_1: + return 2; + default: + return 1; + } +} + +static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, + enum wined3d_shader_type type, unsigned int float_const_count, BOOL swvp) +{ + const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_shader_version *version = ®_maps->shader_version; const struct wined3d_shader_frontend *fe; - HRESULT hr; unsigned int backend_version; - const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; + HRESULT hr; - TRACE("shader %p, float_const_count %u, type %#x, max_version %u.\n", - shader, float_const_count, type, max_version); + TRACE("shader %p, device %p, type %s, float_const_count %u.\n", + shader, device, debug_shader_type(type), float_const_count); fe = shader->frontend; if (!(shader->frontend_data = fe->shader_init(shader->function, @@ -3288,18 +3363,17 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_co shader_trace_init(fe, shader->frontend_data); /* Second pass: figure out which registers are used, what the semantics are, etc. */ - if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, &shader->input_signature, - &shader->output_signature, float_const_count))) + if (FAILED(hr = shader_get_registers_used(shader, float_const_count, swvp))) return hr; - if (reg_maps->shader_version.type != type) + if (version->type != type) { - WARN("Wrong shader type %d.\n", reg_maps->shader_version.type); + WARN("Wrong shader type %s.\n", debug_shader_type(reg_maps->shader_version.type)); return WINED3DERR_INVALIDCALL; } - if (reg_maps->shader_version.major > max_version) + if (version->major > shader_max_version_from_feature_level(device->feature_level)) { - WARN("Shader version %d not supported by this D3D API version.\n", reg_maps->shader_version.major); + WARN("Shader version %u not supported by this device.\n", version->major); return WINED3DERR_INVALIDCALL; } switch (type) @@ -3326,13 +3400,15 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_co FIXME("No backend version-checking for this shader type.\n"); backend_version = 0; } - if (reg_maps->shader_version.major > backend_version) + if (version->major > backend_version) { - WARN("Shader version %d.%d not supported by your GPU with the current shader backend.\n", - reg_maps->shader_version.major, reg_maps->shader_version.minor); + WARN("Shader version %u.%u not supported by the current shader backend.\n", + version->major, version->minor); return WINED3DERR_INVALIDCALL; } + shader->load_local_constsF = shader->lconst_inf_or_nan; + return WINED3D_OK; } @@ -3390,11 +3466,11 @@ HRESULT CDECL wined3d_shader_get_byte_code(const struct wined3d_shader *shader, if (!byte_code) { - *byte_code_size = shader->functionLength; + *byte_code_size = shader->byte_code_size; return WINED3D_OK; } - if (*byte_code_size < shader->functionLength) + if (*byte_code_size < shader->byte_code_size) { /* MSDN claims (for d3d8 at least) that if *byte_code_size is smaller * than the required size we should write the required size and @@ -3402,7 +3478,7 @@ HRESULT CDECL wined3d_shader_get_byte_code(const struct wined3d_shader *shader, return WINED3DERR_INVALIDCALL; } - memcpy(byte_code, shader->function, shader->functionLength); + memcpy(byte_code, shader->byte_code, shader->byte_code_size); return WINED3D_OK; } @@ -3447,10 +3523,10 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh } static void init_interpolation_compile_args(DWORD *interpolation_args, - const struct wined3d_shader *pixel_shader, const struct wined3d_gl_info *gl_info) + const struct wined3d_shader *pixel_shader, const struct wined3d_d3d_info *d3d_info) { - if (!needs_interpolation_qualifiers_for_shader_outputs(gl_info) - || !pixel_shader || pixel_shader->reg_maps.shader_version.major < 4) + if (!d3d_info->shader_output_interpolation || !pixel_shader + || pixel_shader->reg_maps.shader_version.major < 4) { memset(interpolation_args, 0, sizeof(pixel_shader->u.ps.interpolation_mode)); return; @@ -3467,7 +3543,6 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3 const struct wined3d_shader *pixel_shader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct wined3d_shader *hull_shader = state->shader[WINED3D_SHADER_TYPE_HULL]; const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z; @@ -3475,7 +3550,7 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3 && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; args->point_size = state->gl_primitive_type == GL_POINTS; args->per_vertex_point_size = shader->reg_maps.point_size; - args->next_shader_type = hull_shader? WINED3D_SHADER_TYPE_HULL + args->next_shader_type = hull_shader ? WINED3D_SHADER_TYPE_HULL : geometry_shader ? WINED3D_SHADER_TYPE_GEOMETRY : WINED3D_SHADER_TYPE_PIXEL; if (shader->reg_maps.shader_version.major >= 4) args->next_shader_input_count = hull_shader ? hull_shader->limits->packed_input @@ -3490,7 +3565,7 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3 args->flatshading = 0; init_interpolation_compile_args(args->interpolation_mode, - args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL ? pixel_shader : NULL, gl_info); + args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL ? pixel_shader : NULL, d3d_info); } static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) @@ -3527,114 +3602,21 @@ BOOL vshader_get_input(const struct wined3d_shader *shader, return FALSE; } -static HRESULT shader_signature_calculate_strings_length(const struct wined3d_shader_signature *signature, - SIZE_T *total) -{ - struct wined3d_shader_signature_element *e; - unsigned int i; - SIZE_T len; - - for (i = 0; i < signature->element_count; ++i) - { - e = &signature->elements[i]; - len = strlen(e->semantic_name); - if (len >= ~(SIZE_T)0 - *total) - return E_OUTOFMEMORY; - - *total += len + 1; - } - return WINED3D_OK; -} - -static HRESULT shader_signature_copy(struct wined3d_shader_signature *dst, - const struct wined3d_shader_signature *src, char **signature_strings) -{ - struct wined3d_shader_signature_element *e; - unsigned int i; - SIZE_T len; - char *ptr; - - if (!src->element_count) - return WINED3D_OK; - - ptr = *signature_strings; - - dst->element_count = src->element_count; - if (!(dst->elements = heap_calloc(dst->element_count, sizeof(*dst->elements)))) - return E_OUTOFMEMORY; - - for (i = 0; i < src->element_count; ++i) - { - e = &src->elements[i]; - dst->elements[i] = *e; - - len = strlen(e->semantic_name); - memcpy(ptr, e->semantic_name, len + 1); - dst->elements[i].semantic_name = ptr; - ptr += len + 1; - } - - *signature_strings = ptr; - - return WINED3D_OK; -} - static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device *device, - const struct wined3d_shader_desc *desc, DWORD float_const_count, enum wined3d_shader_type type, - void *parent, const struct wined3d_parent_ops *parent_ops) + const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { - size_t byte_code_size; - SIZE_T total; HRESULT hr; - char *ptr; - TRACE("byte_code %p, byte_code_size %#lx, format %#x, max_version %#x.\n", - desc->byte_code, (long)desc->byte_code_size, desc->format, desc->max_version); + TRACE("byte_code %p, byte_code_size %#lx.\n", desc->byte_code, (long)desc->byte_code_size); if (!desc->byte_code) return WINED3DERR_INVALIDCALL; - if (!(shader->frontend = shader_select_frontend(desc->format))) - { - FIXME("Unable to find frontend for shader.\n"); - return WINED3DERR_INVALIDCALL; - } - shader->ref = 1; shader->device = device; shader->parent = parent; shader->parent_ops = parent_ops; - total = 0; - if (FAILED(hr = shader_signature_calculate_strings_length(&desc->input_signature, &total))) - return hr; - if (FAILED(hr = shader_signature_calculate_strings_length(&desc->output_signature, &total))) - return hr; - if (FAILED(hr = shader_signature_calculate_strings_length(&desc->patch_constant_signature, &total))) - return hr; - if (total && !(shader->signature_strings = heap_alloc(total))) - return E_OUTOFMEMORY; - ptr = shader->signature_strings; - - if (FAILED(hr = shader_signature_copy(&shader->input_signature, &desc->input_signature, &ptr))) - { - heap_free(shader->signature_strings); - return hr; - } - if (FAILED(hr = shader_signature_copy(&shader->output_signature, &desc->output_signature, &ptr))) - { - heap_free(shader->input_signature.elements); - heap_free(shader->signature_strings); - return hr; - } - if (FAILED(hr = shader_signature_copy(&shader->patch_constant_signature, &desc->patch_constant_signature, &ptr))) - { - heap_free(shader->output_signature.elements); - heap_free(shader->input_signature.elements); - heap_free(shader->signature_strings); - return hr; - } - list_init(&shader->linked_programs); list_init(&shader->constantsF); list_init(&shader->constantsB); @@ -3643,20 +3625,27 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device list_init(&shader->reg_maps.indexable_temps); list_init(&shader->shader_list_entry); - byte_code_size = desc->byte_code_size; - if (byte_code_size == ~(size_t)0) + if (desc->byte_code_size == ~(size_t)0) { - const struct wined3d_shader_frontend *fe = shader->frontend; struct wined3d_shader_version shader_version; + const struct wined3d_shader_frontend *fe; struct wined3d_shader_instruction ins; const DWORD *ptr; void *fe_data; - if (!(fe_data = fe->shader_init(desc->byte_code, byte_code_size, &shader->output_signature))) + if (!(shader->frontend = shader_select_frontend(WINED3D_SHADER_BYTE_CODE_FORMAT_SM1))) + { + FIXME("Unable to find frontend for shader.\n"); + hr = WINED3DERR_INVALIDCALL; + goto fail; + } + + fe = shader->frontend; + if (!(fe_data = fe->shader_init(desc->byte_code, desc->byte_code_size, &shader->output_signature))) { WARN("Failed to initialise frontend data.\n"); - shader_cleanup(shader); - return WINED3DERR_INVALIDCALL; + hr = WINED3DERR_INVALIDCALL; + goto fail; } fe->shader_read_header(fe_data, &ptr, &shader_version); @@ -3665,28 +3654,47 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device fe->shader_free(fe_data); - byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr); - } + shader->byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr); - if (!(shader->function = heap_alloc(byte_code_size))) - { - shader_cleanup(shader); - return E_OUTOFMEMORY; - } - memcpy(shader->function, desc->byte_code, byte_code_size); - shader->functionLength = byte_code_size; + if (!(shader->byte_code = heap_alloc(shader->byte_code_size))) + { + hr = E_OUTOFMEMORY; + goto fail; + } + memcpy(shader->byte_code, desc->byte_code, shader->byte_code_size); - if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version))) - { - WARN("Failed to set function, hr %#x.\n", hr); - shader_cleanup(shader); - return hr; + shader->function = shader->byte_code; + shader->functionLength = shader->byte_code_size; } + else + { + enum wined3d_shader_byte_code_format format; + unsigned int max_version; - shader->load_local_constsF = shader->lconst_inf_or_nan; + if (!(shader->byte_code = heap_alloc(desc->byte_code_size))) + { + hr = E_OUTOFMEMORY; + goto fail; + } + memcpy(shader->byte_code, desc->byte_code, desc->byte_code_size); + shader->byte_code_size = desc->byte_code_size; + + max_version = shader_max_version_from_feature_level(device->feature_level); + if (FAILED(hr = shader_extract_from_dxbc(shader, max_version, &format))) + goto fail; + + if (!(shader->frontend = shader_select_frontend(format))) + { + FIXME("Unable to find frontend for shader.\n"); + hr = WINED3DERR_INVALIDCALL; + goto fail; + } + } - wined3d_cs_init_object(shader->device->cs, wined3d_shader_init_object, shader); + return WINED3D_OK; +fail: + shader_cleanup(shader); return hr; } @@ -3694,13 +3702,24 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + unsigned int vs_uniform_count; unsigned int i; HRESULT hr; + BOOL swvp = device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING + | WINED3DCREATE_MIXED_VERTEXPROCESSING); - if (FAILED(hr = shader_init(shader, device, desc, device->adapter->d3d_info.limits.vs_uniform_count, - WINED3D_SHADER_TYPE_VERTEX, parent, parent_ops))) + if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) return hr; + vs_uniform_count = swvp ? device->adapter->d3d_info.limits.vs_uniform_count_swvp + : device->adapter->d3d_info.limits.vs_uniform_count; + if (FAILED(hr = shader_set_function(shader, device, + WINED3D_SHADER_TYPE_VERTEX, vs_uniform_count, swvp))) + { + shader_cleanup(shader); + return hr; + } + for (i = 0; i < shader->input_signature.element_count; ++i) { const struct wined3d_shader_signature_element *input = &shader->input_signature.elements[i]; @@ -3719,30 +3738,147 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ return WINED3D_OK; } -static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, - const struct wined3d_shader_desc *desc, const struct wined3d_stream_output_desc *so_desc, - void *parent, const struct wined3d_parent_ops *parent_ops) +static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s, + unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx) +{ + struct wined3d_shader_signature_element *e = s->elements; + unsigned int i; + + for (i = 0; i < s->element_count; ++i) + { + if (e[i].stream_idx == stream_idx + && !_strnicmp(e[i].semantic_name, semantic_name, -1) + && e[i].semantic_idx == semantic_idx) + return &e[i]; + } + + return NULL; +} + +BOOL shader_get_stream_output_register_info(const struct wined3d_shader *shader, + const struct wined3d_stream_output_element *so_element, unsigned int *register_idx, unsigned int *component_idx) { - struct wined3d_stream_output_element *elements = NULL; + const struct wined3d_shader_signature_element *output; + unsigned int idx; + + if (!(output = shader_find_signature_element(&shader->output_signature, + so_element->stream_idx, so_element->semantic_name, so_element->semantic_idx))) + return FALSE; + + for (idx = 0; idx < 4; ++idx) + { + if (output->mask & (1u << idx)) + break; + } + idx += so_element->component_idx; + + *register_idx = output->register_idx; + *component_idx = idx; + return TRUE; +} + +static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, + const struct wined3d_stream_output_desc *so_desc) +{ + const struct wined3d_shader_frontend *fe = shader->frontend; + const struct wined3d_shader_signature_element *output; + unsigned int i, component_idx, register_idx, mask; + struct wined3d_stream_output_element *elements; + struct wined3d_shader_version shader_version; + const DWORD *ptr; + void *fe_data; HRESULT hr; - if (so_desc && !(elements = heap_calloc(so_desc->element_count, sizeof(*elements)))) - return E_OUTOFMEMORY; + if (!so_desc) + return WINED3D_OK; - if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops))) + if (!(fe_data = fe->shader_init(shader->function, shader->functionLength, &shader->output_signature))) { - heap_free(elements); - return hr; + WARN("Failed to initialise frontend data.\n"); + return WINED3DERR_INVALIDCALL; + } + fe->shader_read_header(fe_data, &ptr, &shader_version); + fe->shader_free(fe_data); + + switch (shader_version.type) + { + case WINED3D_SHADER_TYPE_VERTEX: + case WINED3D_SHADER_TYPE_DOMAIN: + shader->function = NULL; + shader->functionLength = 0; + break; + case WINED3D_SHADER_TYPE_GEOMETRY: + break; + default: + WARN("Wrong shader type %s.\n", debug_shader_type(shader_version.type)); + return E_INVALIDARG; } - if (so_desc) + if (!shader->function) { - shader->u.gs.so_desc = *so_desc; - shader->u.gs.so_desc.elements = elements; - memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements)); + shader->reg_maps.shader_version = shader_version; + shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; + shader_set_limits(shader, 0); + if (FAILED(hr = shader_scan_output_signature(shader))) + return hr; } + if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements)))) + return E_OUTOFMEMORY; + + shader->u.gs.so_desc = *so_desc; + shader->u.gs.so_desc.elements = elements; + memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements)); + + for (i = 0; i < so_desc->element_count; ++i) + { + struct wined3d_stream_output_element *e = &elements[i]; + + if (!e->semantic_name) + continue; + if (!(output = shader_find_signature_element(&shader->output_signature, + e->stream_idx, e->semantic_name, e->semantic_idx)) + || !shader_get_stream_output_register_info(shader, e, ®ister_idx, &component_idx)) + { + WARN("Failed to find output signature element for stream output entry.\n"); + return E_INVALIDARG; + } + + e->semantic_name = output->semantic_name; + + mask = ((1u << e->component_count) - 1) << component_idx; + if ((output->mask & 0xff & mask) != mask) + { + WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n", + component_idx, e->component_count, mask, output->mask & 0xff); + return E_INVALIDARG; + } + } + + return WINED3D_OK; +} + +static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, + const struct wined3d_shader_desc *desc, const struct wined3d_stream_output_desc *so_desc, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + HRESULT hr; + + if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) + return hr; + + if (FAILED(hr = geometry_shader_init_stream_output(shader, so_desc))) + goto fail; + + if (shader->function + && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0, 0))) + goto fail; + return WINED3D_OK; + +fail: + shader_cleanup(shader); + return hr; } void find_ds_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, @@ -3751,7 +3887,6 @@ void find_ds_compile_args(const struct wined3d_state *state, const struct wined3 const struct wined3d_shader *geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; const struct wined3d_shader *pixel_shader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct wined3d_shader *hull_shader = state->shader[WINED3D_SHADER_TYPE_HULL]; - const struct wined3d_gl_info *gl_info = context->gl_info; args->tessellator_output_primitive = hull_shader->u.hs.tessellator_output_primitive; args->tessellator_partitioning = hull_shader->u.hs.tessellator_partitioning; @@ -3763,7 +3898,7 @@ void find_ds_compile_args(const struct wined3d_state *state, const struct wined3 args->render_offscreen = context->render_offscreen; init_interpolation_compile_args(args->interpolation_mode, - args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL ? pixel_shader : NULL, gl_info); + args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL ? pixel_shader : NULL, context->d3d_info); args->padding = 0; } @@ -3772,23 +3907,25 @@ void find_gs_compile_args(const struct wined3d_state *state, const struct wined3 struct gs_compile_args *args, const struct wined3d_context *context) { const struct wined3d_shader *pixel_shader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - const struct wined3d_gl_info *gl_info = context->gl_info; args->output_count = pixel_shader ? pixel_shader->limits->packed_input : shader->limits->packed_output; - init_interpolation_compile_args(args->interpolation_mode, pixel_shader, gl_info); + if (!(args->primitive_type = shader->u.gs.input_type)) + args->primitive_type = d3d_primitive_type_from_gl(state->gl_primitive_type); + + init_interpolation_compile_args(args->interpolation_mode, pixel_shader, context->d3d_info); } void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = &context->device->adapter->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_texture *texture; + struct wined3d_texture *texture; unsigned int i; memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ - if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb)) + if (!d3d_info->srgb_write_control && needs_srgb_write(context, state, state->fb)) { static unsigned int warned = 0; @@ -3859,22 +3996,19 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 { for (i = 0; i < shader->limits->sampler; ++i) { - const struct wined3d_texture *texture = state->textures[i]; - if (!shader->reg_maps.resource_info[i].type) continue; /* Treat unbound textures as 2D. The dummy texture will provide * the proper sample value. The tex_types bitmap defaults to * 2D because of the memset. */ - if (!texture) + if (!(texture = state->textures[i])) continue; - switch (texture->target) + switch (wined3d_texture_gl(texture)->target) { /* RECT textures are distinguished from 2D textures via np2_fixup */ - case GL_TEXTURE_RECTANGLE_ARB: - case GL_TEXTURE_2D: + default: break; case GL_TEXTURE_3D: @@ -3887,18 +4021,54 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 } } } + else if (shader->reg_maps.shader_version.major <= 3) + { + for (i = 0; i < shader->limits->sampler; ++i) + { + enum wined3d_shader_resource_type resource_type; + enum wined3d_shader_tex_types tex_type; + + if (!(resource_type = shader->reg_maps.resource_info[i].type)) + continue; + + switch (resource_type) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_3D: + tex_type = WINED3D_SHADER_TEX_3D; + break; + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + tex_type = WINED3D_SHADER_TEX_CUBE; + break; + default: + tex_type = WINED3D_SHADER_TEX_2D; + break; + } + + if ((texture = state->textures[i])) + { + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_2D + && resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D + && !(texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP)) + tex_type = WINED3D_SHADER_TEX_2D; + else if (texture->resource.type == WINED3D_RTYPE_TEXTURE_3D + && resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D) + tex_type = WINED3D_SHADER_TEX_3D; + } + args->tex_types |= tex_type << i * WINED3D_PSARGS_TEXTYPE_SHIFT; + } + } if (shader->reg_maps.shader_version.major >= 4) { /* In SM4+ we use dcl_sampler in order to determine if we should use shadow sampler. */ args->shadow = 0; - for (i = 0 ; i < MAX_FRAGMENT_SAMPLERS; ++i) + for (i = 0 ; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) args->color_fixup[i] = COLOR_FIXUP_IDENTITY; args->np2_fixup = 0; } else { - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) { if (!shader->reg_maps.resource_info[i].type) continue; @@ -3909,7 +4079,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->color_fixup[i] = COLOR_FIXUP_IDENTITY; continue; } - if (can_use_texture_swizzle(gl_info, texture->resource.format)) + if (can_use_texture_swizzle(d3d_info, texture->resource.format)) args->color_fixup[i] = COLOR_FIXUP_IDENTITY; else args->color_fixup[i] = texture->resource.format->color_fixup; @@ -3926,16 +4096,16 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 if (shader->reg_maps.shader_version.major >= 3) { if (position_transformed) - args->vp_mode = pretransformed; + args->vp_mode = WINED3D_VP_MODE_NONE; else if (use_vs(state)) - args->vp_mode = vertexshader; + args->vp_mode = WINED3D_VP_MODE_SHADER; else - args->vp_mode = fixedfunction; + args->vp_mode = WINED3D_VP_MODE_FF; args->fog = WINED3D_FFP_PS_FOG_OFF; } else { - args->vp_mode = vertexshader; + args->vp_mode = WINED3D_VP_MODE_SHADER; if (state->render_states[WINED3D_RS_FOGENABLE]) { switch (state->render_states[WINED3D_RS_FOGTABLEMODE]) @@ -3967,12 +4137,12 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 } } - if (context->d3d_info->limits.varying_count < wined3d_max_compat_varyings(context->gl_info)) + if (!d3d_info->full_ffp_varyings) { const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; args->texcoords_initialized = 0; - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (vs) { @@ -3986,20 +4156,20 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 if ((state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT) & WINED3D_FFP_TCI_MASK - || (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))) + || (coord_idx < WINED3D_MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))) args->texcoords_initialized |= 1u << i; } } } else { - args->texcoords_initialized = (1u << MAX_TEXTURES) - 1; + args->texcoords_initialized = (1u << WINED3D_MAX_TEXTURES) - 1; } args->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->gl_primitive_type == GL_POINTS; - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + if (d3d_info->ffp_alpha_test) args->alpha_test_func = WINED3D_CMP_ALWAYS - 1; else args->alpha_test_func = (state->render_states[WINED3D_RS_ALPHATESTENABLE] @@ -4012,6 +4182,13 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] ? context->render_offscreen : 0; + for (i = 0; i < ARRAY_SIZE(state->fb->render_targets); ++i) + { + struct wined3d_rendertarget_view *rtv = state->fb->render_targets[i]; + if (rtv && rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup)) + args->rt_alpha_swizzle |= 1u << i; + } + args->dual_source_blend = wined3d_dualblend_enabled(state, gl_info); } @@ -4022,9 +4199,15 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d unsigned int i, highest_reg_used = 0, num_regs_used = 0; HRESULT hr; - if (FAILED(hr = shader_init(shader, device, desc, device->adapter->d3d_info.limits.ps_uniform_count, - WINED3D_SHADER_TYPE_PIXEL, parent, parent_ops))) + if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) + return hr; + + if (FAILED(hr = shader_set_function(shader, device, + WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count, 0))) + { + shader_cleanup(shader); return hr; + } for (i = 0; i < MAX_REG_INPUT; ++i) { @@ -4070,35 +4253,27 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d return WINED3D_OK; } -void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) +enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps, + unsigned int resource_idx, DWORD tex_types) { - struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - struct wined3d_shader_resource_info *resource_info = reg_maps->resource_info; - unsigned int i; - - if (reg_maps->shader_version.major != 1) return; - - for (i = 0; i < shader->limits->sampler; ++i) + static enum wined3d_shader_resource_type shader_resource_type_from_shader_tex_types[] = { - /* We don't sample from this sampler. */ - if (!resource_info[i].type) - continue; + WINED3D_SHADER_RESOURCE_TEXTURE_2D, /* WINED3D_SHADER_TEX_2D */ + WINED3D_SHADER_RESOURCE_TEXTURE_3D, /* WINED3D_SHADER_TEX_3D */ + WINED3D_SHADER_RESOURCE_TEXTURE_CUBE, /* WINED3D_SHADER_TEX_CUBE */ + }; - switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK) - { - case WINED3D_SHADER_TEX_2D: - resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; - break; + unsigned int idx; - case WINED3D_SHADER_TEX_3D: - resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_3D; - break; + if (reg_maps->shader_version.major > 3) + return reg_maps->resource_info[resource_idx].type; - case WINED3D_SHADER_TEX_CUBE: - resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE; - break; - } - } + if (!reg_maps->resource_info[resource_idx].type) + return 0; + + idx = (tex_types >> resource_idx * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK; + assert(idx < ARRAY_SIZE(shader_resource_type_from_shader_tex_types)); + return shader_resource_type_from_shader_tex_types[idx]; } HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, @@ -4113,13 +4288,22 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_COMPUTE, parent, parent_ops))) + if (FAILED(hr = shader_init(object, device, desc, parent, parent_ops))) { WARN("Failed to initialize compute shader, hr %#x.\n", hr); heap_free(object); return hr; } + if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0, 0))) + { + shader_cleanup(object); + heap_free(object); + return hr; + } + + wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); + TRACE("Created compute shader %p.\n", object); *shader = object; @@ -4138,13 +4322,22 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_DOMAIN, parent, parent_ops))) + if (FAILED(hr = shader_init(object, device, desc, parent, parent_ops))) { WARN("Failed to initialize domain shader, hr %#x.\n", hr); heap_free(object); return hr; } + if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0, 0))) + { + shader_cleanup(object); + heap_free(object); + return hr; + } + + wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); + TRACE("Created domain shader %p.\n", object); *shader = object; @@ -4171,6 +4364,8 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru return hr; } + wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); + TRACE("Created geometry shader %p.\n", object); *shader = object; @@ -4189,13 +4384,22 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = shader_init(object, device, desc, 0, WINED3D_SHADER_TYPE_HULL, parent, parent_ops))) + if (FAILED(hr = shader_init(object, device, desc, parent, parent_ops))) { WARN("Failed to initialize hull shader, hr %#x.\n", hr); heap_free(object); return hr; } + if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0, 0))) + { + shader_cleanup(object); + heap_free(object); + return hr; + } + + wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); + TRACE("Created hull shader %p.\n", object); *shader = object; @@ -4221,6 +4425,8 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const stru return hr; } + wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); + TRACE("Created pixel shader %p.\n", object); *shader = object; @@ -4246,6 +4452,8 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru return hr; } + wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object); + TRACE("Created vertex shader %p.\n", object); *shader = object; diff --git a/dll/directx/wine/wined3d/shader_sm1.c b/dll/directx/wine/wined3d/shader_sm1.c index 0c6bb933174..1051307e88c 100644 --- a/dll/directx/wine/wined3d/shader_sm1.c +++ b/dll/directx/wine/wined3d/shader_sm1.c @@ -543,7 +543,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size, major = WINED3D_SM1_VERSION_MAJOR(*byte_code); minor = WINED3D_SM1_VERSION_MINOR(*byte_code); - if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0)) + if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 255)) { WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code); return NULL; diff --git a/dll/directx/wine/wined3d/shader_sm4.c b/dll/directx/wine/wined3d/shader_sm4.c index 8eac746ac50..5e59b2ae324 100644 --- a/dll/directx/wine/wined3d/shader_sm4.c +++ b/dll/directx/wine/wined3d/shader_sm4.c @@ -61,6 +61,9 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_GLOBAL_FLAGS_SHIFT 11 #define WINED3D_SM4_GLOBAL_FLAGS_MASK (0xffu << WINED3D_SM4_GLOBAL_FLAGS_SHIFT) +#define WINED3D_SM5_PRECISE_SHIFT 19 +#define WINED3D_SM5_PRECISE_MASK (0xfu << WINED3D_SM5_PRECISE_SHIFT) + #define WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT 11 #define WINED3D_SM5_CONTROL_POINT_COUNT_MASK (0xffu << WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT) @@ -315,6 +318,7 @@ enum wined3d_sm4_register_type WINED3D_SM4_RT_PRIMID = 0x0b, WINED3D_SM4_RT_DEPTHOUT = 0x0c, WINED3D_SM4_RT_NULL = 0x0d, + WINED3D_SM4_RT_RASTERIZER = 0x0e, WINED3D_SM4_RT_OMASK = 0x0f, WINED3D_SM5_RT_STREAM = 0x10, WINED3D_SM5_RT_FUNCTION_BODY = 0x11, @@ -1129,7 +1133,7 @@ static const enum wined3d_shader_register_type register_type_table[] = /* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID, /* WINED3D_SM4_RT_DEPTHOUT */ WINED3DSPR_DEPTHOUT, /* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL, - /* UNKNOWN */ ~0u, + /* WINED3D_SM4_RT_RASTERIZER */ WINED3DSPR_RASTERIZER, /* WINED3D_SM4_RT_OMASK */ WINED3DSPR_SAMPLEMASK, /* WINED3D_SM5_RT_STREAM */ WINED3DSPR_STREAM, /* WINED3D_SM5_RT_FUNCTION_BODY */ WINED3DSPR_FUNCTIONBODY, @@ -1218,6 +1222,43 @@ static enum wined3d_data_type map_data_type(char t) } } +static enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code, size_t byte_code_size) +{ + DWORD shader_type; + + if (byte_code_size / sizeof(*byte_code) < 1) + { + WARN("Invalid byte code size %lu.\n", (long)byte_code_size); + return WINED3D_SHADER_TYPE_INVALID; + } + + shader_type = byte_code[0] >> 16; + switch (shader_type) + { + case WINED3D_SM4_PS: + return WINED3D_SHADER_TYPE_PIXEL; + break; + case WINED3D_SM4_VS: + return WINED3D_SHADER_TYPE_VERTEX; + break; + case WINED3D_SM4_GS: + return WINED3D_SHADER_TYPE_GEOMETRY; + break; + case WINED3D_SM5_HS: + return WINED3D_SHADER_TYPE_HULL; + break; + case WINED3D_SM5_DS: + return WINED3D_SHADER_TYPE_DOMAIN; + break; + case WINED3D_SM5_CS: + return WINED3D_SHADER_TYPE_COMPUTE; + break; + default: + FIXME("Unrecognised shader type %#x.\n", shader_type); + return WINED3D_SHADER_TYPE_INVALID; + } +} + static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, const struct wined3d_shader_signature *output_signature) { @@ -1251,35 +1292,13 @@ static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, priv->start = &byte_code[2]; priv->end = &byte_code[token_count]; - switch (version_token >> 16) + priv->shader_version.type = wined3d_get_sm4_shader_type(byte_code, byte_code_size); + if (priv->shader_version.type == WINED3D_SHADER_TYPE_INVALID) { - case WINED3D_SM4_PS: - priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL; - break; - - case WINED3D_SM4_VS: - priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX; - break; - - case WINED3D_SM4_GS: - priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; - break; - - case WINED3D_SM5_HS: - priv->shader_version.type = WINED3D_SHADER_TYPE_HULL; - break; - - case WINED3D_SM5_DS: - priv->shader_version.type = WINED3D_SHADER_TYPE_DOMAIN; - break; - - case WINED3D_SM5_CS: - priv->shader_version.type = WINED3D_SHADER_TYPE_COMPUTE; - break; - - default: - FIXME("Unrecognised shader type %#x.\n", version_token >> 16); + heap_free(priv); + return NULL; } + priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token); priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token); @@ -1628,6 +1647,7 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi unsigned int i, len; SIZE_T remaining; const DWORD *p; + DWORD precise; list_move_head(&priv->src_free, &priv->src); @@ -1702,12 +1722,13 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi shader_sm4_read_instruction_modifier(previous_token = *p++, ins); ins->flags = (opcode_token & WINED3D_SM4_INSTRUCTION_FLAGS_MASK) >> WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT; - if (ins->flags & WINED3D_SM4_INSTRUCTION_FLAG_SATURATE) { ins->flags &= ~WINED3D_SM4_INSTRUCTION_FLAG_SATURATE; instruction_dst_modifier = WINED3DSPDM_SATURATE; } + precise = (opcode_token & WINED3D_SM5_PRECISE_MASK) >> WINED3D_SM5_PRECISE_SHIFT; + ins->flags |= precise << WINED3DSI_PRECISE_SHIFT; for (i = 0; i < ins->dst_count; ++i) { @@ -1753,3 +1774,365 @@ const struct wined3d_shader_frontend sm4_shader_frontend = shader_sm4_read_instruction, shader_sm4_is_end, }; + +#define TAG_AON9 WINEMAKEFOURCC('A', 'o', 'n', '9') +#define TAG_DXBC WINEMAKEFOURCC('D', 'X', 'B', 'C') +#define TAG_ISGN WINEMAKEFOURCC('I', 'S', 'G', 'N') +#define TAG_OSG5 WINEMAKEFOURCC('O', 'S', 'G', '5') +#define TAG_OSGN WINEMAKEFOURCC('O', 'S', 'G', 'N') +#define TAG_PCSG WINEMAKEFOURCC('P', 'C', 'S', 'G') +#define TAG_SHDR WINEMAKEFOURCC('S', 'H', 'D', 'R') +#define TAG_SHEX WINEMAKEFOURCC('S', 'H', 'E', 'X') + +struct aon9_header +{ + DWORD chunk_size; + DWORD shader_version; + DWORD unknown; + DWORD byte_code_offset; +}; + +struct shader_handler_context +{ + struct wined3d_shader *shader; + enum wined3d_shader_byte_code_format *format; + unsigned int max_version; +}; + +static void read_dword(const char **ptr, DWORD *d) +{ + memcpy(d, *ptr, sizeof(*d)); + *ptr += sizeof(*d); +} + +static BOOL require_space(size_t offset, size_t count, size_t size, size_t data_size) +{ + return !count || (data_size - offset) / count >= size; +} + +static void skip_dword_unknown(const char **ptr, unsigned int count) +{ + unsigned int i; + DWORD d; + + WARN("Skipping %u unknown DWORDs:\n", count); + for (i = 0; i < count; ++i) + { + read_dword(ptr, &d); + WARN("\t0x%08x\n", d); + } +} + +static HRESULT parse_dxbc(const char *data, SIZE_T data_size, + HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) +{ + const char *ptr = data; + HRESULT hr = S_OK; + DWORD chunk_count; + DWORD total_size; + unsigned int i; + DWORD version; + DWORD tag; + + read_dword(&ptr, &tag); + TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4)); + + if (tag != TAG_DXBC) + { + WARN("Wrong tag.\n"); + return E_INVALIDARG; + } + + WARN("Ignoring DXBC checksum.\n"); + skip_dword_unknown(&ptr, 4); + + read_dword(&ptr, &version); + TRACE("version: %#x.\n", version); + if (version != 0x00000001) + { + WARN("Got unexpected DXBC version %#x.\n", version); + return E_INVALIDARG; + } + + read_dword(&ptr, &total_size); + TRACE("total size: %#x\n", total_size); + + read_dword(&ptr, &chunk_count); + TRACE("chunk count: %#x\n", chunk_count); + + for (i = 0; i < chunk_count; ++i) + { + DWORD chunk_tag, chunk_size; + const char *chunk_ptr; + DWORD chunk_offset; + + read_dword(&ptr, &chunk_offset); + TRACE("chunk %u at offset %#x\n", i, chunk_offset); + + if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid chunk offset %#x (data size %#lx).\n", chunk_offset, data_size); + return E_FAIL; + } + + chunk_ptr = data + chunk_offset; + + read_dword(&chunk_ptr, &chunk_tag); + read_dword(&chunk_ptr, &chunk_size); + + if (!require_space(chunk_ptr - data, 1, chunk_size, data_size)) + { + WARN("Invalid chunk size %#x (data size %#lx, chunk offset %#x).\n", + chunk_size, data_size, chunk_offset); + return E_FAIL; + } + + if (FAILED(hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx))) + break; + } + + return hr; +} + +const char *shader_get_string(const char *data, size_t data_size, DWORD offset) +{ + size_t len, max_len; + + if (offset >= data_size) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return NULL; + } + + max_len = data_size - offset; + +#ifdef __REACTOS__ + len = strlen(data + offset); +#else + len = strnlen(data + offset, max_len); +#endif + + if (len == max_len) + return NULL; + + return data + offset; +} + +static HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_size, + struct wined3d_shader_signature *s) +{ + struct wined3d_shader_signature_element *e; + const char *ptr = data; + unsigned int i; + DWORD count; + + if (!require_space(0, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid data size %#x.\n", data_size); + return E_INVALIDARG; + } + + read_dword(&ptr, &count); + TRACE("%u elements.\n", count); + + skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000008. */ + + if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size)) + { + WARN("Invalid count %#x (data size %#x).\n", count, data_size); + return E_INVALIDARG; + } + + if (!(e = heap_calloc(count, sizeof(*e)))) + { + ERR("Failed to allocate input signature memory.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < count; ++i) + { + DWORD name_offset; + + if (tag == TAG_OSG5) + read_dword(&ptr, &e[i].stream_idx); + else + e[i].stream_idx = 0; + read_dword(&ptr, &name_offset); + if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset))) + { + WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size); + heap_free(e); + return E_INVALIDARG; + } + read_dword(&ptr, &e[i].semantic_idx); +#ifdef __REACTOS__ + read_dword(&ptr, (DWORD*)&e[i].sysval_semantic); + read_dword(&ptr, (DWORD*)&e[i].component_type); +#else + read_dword(&ptr, &e[i].sysval_semantic); + read_dword(&ptr, &e[i].component_type); +#endif + read_dword(&ptr, &e[i].register_idx); + read_dword(&ptr, &e[i].mask); + + TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, " + "type %u, register idx: %u, use_mask %#x, input_mask %#x.\n", + e[i].stream_idx, debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic, + e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff); + } + + s->elements = e; + s->element_count = count; + + return S_OK; +} + +static HRESULT shader_dxbc_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *context) +{ + struct shader_handler_context *ctx = context; + struct wined3d_shader *shader = ctx->shader; + HRESULT hr; + + switch (tag) + { + case TAG_ISGN: + if (ctx->max_version < 4) + { + TRACE("Skipping shader input signature.\n"); + break; + } + if (shader->input_signature.elements) + { + FIXME("Multiple input signatures.\n"); + break; + } + if (FAILED(hr = shader_parse_signature(tag, data, data_size, &shader->input_signature))) + return hr; + break; + + case TAG_OSGN: + case TAG_OSG5: + if (ctx->max_version < 4) + { + TRACE("Skipping shader output signature.\n"); + break; + } + if (shader->output_signature.elements) + { + FIXME("Multiple output signatures.\n"); + break; + } + if (FAILED(hr = shader_parse_signature(tag, data, data_size, &shader->output_signature))) + return hr; + break; + + case TAG_PCSG: + if (shader->patch_constant_signature.elements) + { + FIXME("Multiple patch constant signatures.\n"); + break; + } + if (FAILED(hr = shader_parse_signature(tag, data, data_size, &shader->patch_constant_signature))) + return hr; + break; + + case TAG_SHDR: + case TAG_SHEX: + if (ctx->max_version < 4) + { + TRACE("Skipping SM4+ shader.\n"); + break; + } + if (shader->function) + FIXME("Multiple shader code chunks.\n"); + shader->function = (const DWORD *)data; + shader->functionLength = data_size; + *ctx->format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM4; + break; + + case TAG_AON9: + if (ctx->max_version < 4) + { + const struct aon9_header *header = (const struct aon9_header *)data; + unsigned int unknown_dword_count; + const char *byte_code; + + if (data_size < sizeof(*header)) + { + WARN("Invalid Aon9 data size %#x.\n", data_size); + return E_FAIL; + } + byte_code = data + header->byte_code_offset; + unknown_dword_count = (header->byte_code_offset - sizeof(*header)) / sizeof(DWORD); + + if (data_size - 2 * sizeof(DWORD) < header->byte_code_offset) + { + WARN("Invalid byte code offset %#x (size %#x).\n", header->byte_code_offset, data_size); + return E_FAIL; + } + FIXME("Skipping %u unknown DWORDs.\n", unknown_dword_count); + + if (shader->function) + FIXME("Multiple shader code chunks.\n"); + shader->function = (const DWORD *)byte_code; + shader->functionLength = data_size - header->byte_code_offset; + *ctx->format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; + TRACE("Feature level 9 shader version 0%08x, 0%08x.\n", + header->shader_version, *shader->function); + } + else + { + TRACE("Skipping feature level 9 shader code.\n"); + } + break; + + default: + TRACE("Skipping chunk %s.\n", debugstr_an((const char *)&tag, 4)); + break; + } + + return S_OK; +} + +HRESULT shader_extract_from_dxbc(struct wined3d_shader *shader, + unsigned int max_shader_version, enum wined3d_shader_byte_code_format *format) +{ + struct shader_handler_context ctx; + HRESULT hr; + + ctx.shader = shader; + ctx.format = format; + ctx.max_version = max_shader_version; + + hr = parse_dxbc(shader->byte_code, shader->byte_code_size, shader_dxbc_chunk_handler, &ctx); + if (!shader->function) + hr = E_INVALIDARG; + + if (FAILED(hr)) + WARN("Failed to parse DXBC, hr %#x.\n", hr); + + return hr; +} + +static HRESULT shader_isgn_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +{ + struct wined3d_shader_signature *is = ctx; + + if (tag != TAG_ISGN) + return S_OK; + + if (is->elements) + { + FIXME("Multiple shader signatures.\n"); + return S_OK; + } + + return shader_parse_signature(tag, data, data_size, is); +} + +HRESULT CDECL wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature, + const void *code, SIZE_T code_size) +{ + memset(signature, 0, sizeof(*signature)); + return parse_dxbc(code, code_size, shader_isgn_chunk_handler, signature); +} diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c index 890af9c2ee0..8c9be567e1c 100644 --- a/dll/directx/wine/wined3d/state.c +++ b/dll/directx/wine/wined3d/state.c @@ -36,10 +36,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); - -void (WINE_GLAPI *glDisableWINE)(GLenum cap); -void (WINE_GLAPI *glEnableWINE)(GLenum cap); ULONG CDECL wined3d_blend_state_incref(struct wined3d_blend_state *state) { @@ -177,8 +173,8 @@ void state_nop(struct wined3d_context *context, const struct wined3d_state *stat static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE]; - const struct wined3d_gl_info *gl_info = context->gl_info; switch (mode) { @@ -201,7 +197,7 @@ static void state_fillmode(struct wined3d_context *context, const struct wined3d static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; /* Lighting is not enabled if transformed vertices are drawn, but lighting * does not affect the stream sources, so it is not grouped for @@ -227,7 +223,7 @@ static void state_lighting(struct wined3d_context *context, const struct wined3d static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE]; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; /* No z test without depth stencil buffers */ if (!state->fb->depth_stencil) @@ -262,7 +258,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; /* glFrontFace() is set in context.c at context init and on an * offscreen / onscreen rendering switch. */ @@ -292,7 +288,7 @@ static void state_cullmode(struct wined3d_context *context, const struct wined3d void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; switch (state->render_states[WINED3D_RS_SHADEMODE]) { @@ -315,7 +311,7 @@ void state_shademode(struct wined3d_context *context, const struct wined3d_state static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_DITHERENABLE]) { @@ -331,7 +327,7 @@ static void state_ditherenable(struct wined3d_context *context, const struct win static void state_zwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_ZWRITEENABLE]) { @@ -377,7 +373,7 @@ GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { GLenum depth_func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]); - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (!depth_func) return; @@ -387,7 +383,7 @@ static void state_zfunc(struct wined3d_context *context, const struct wined3d_st static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; struct wined3d_color color; wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_AMBIENT]); @@ -426,7 +422,7 @@ static GLenum gl_blend_op(const struct wined3d_gl_info *gl_info, enum wined3d_bl static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; GLenum blend_equation_alpha = GL_FUNC_ADD_EXT; GLenum blend_equation = GL_FUNC_ADD_EXT; @@ -533,7 +529,7 @@ static void gl_blend_from_d3d(GLenum *src_blend, GLenum *dst_blend, static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; const struct wined3d_format *rt_format; GLenum src_blend, dst_blend; unsigned int rt_fmt_flags; @@ -541,7 +537,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st BOOL enable_blend; enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE]; - enable_dual_blend = wined3d_dualblend_enabled(state, context->gl_info); + enable_dual_blend = wined3d_dualblend_enabled(state, gl_info); if (enable_blend && !enable_dual_blend) { @@ -585,7 +581,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st GLenum src_blend_alpha, dst_blend_alpha; /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */ - if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) + if (!gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) { WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparate.\n"); return; @@ -611,26 +607,25 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP)); } -static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_blend_factor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { WARN("Unsupported in local OpenGL implementation: glBlendColor.\n"); } -static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_blend_factor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_color color; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + const struct wined3d_color *factor = &state->blend_factor; - TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]); + TRACE("Setting blend factor to %s.\n", debug_color(factor)); - wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_BLENDFACTOR]); - GL_EXTCALL(glBlendColor(color.r, color.g, color.b, color.a)); + GL_EXTCALL(glBlendColor(factor->r, factor->g, factor->b, factor->a)); checkGLcall("glBlendColor"); } static void state_blend_object(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; BOOL alpha_to_coverage = FALSE; if (!gl_info->supported[ARB_MULTISAMPLE]) @@ -652,7 +647,7 @@ static void state_blend_object(struct wined3d_context *context, const struct win void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; int glParm = 0; float ref; BOOL enable_ckey = FALSE; @@ -696,7 +691,7 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat } else { - ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f; + ref = wined3d_alpha_ref(state); glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]); } if (glParm) @@ -708,7 +703,8 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - unsigned int enable_mask; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + uint32_t enable_mask; if (use_vs(state) && !context->d3d_info->vs_clipping) { @@ -736,12 +732,13 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state */ enable_mask = state->render_states[WINED3D_RS_CLIPPING] ? state->render_states[WINED3D_RS_CLIPPLANEENABLE] : 0; - context_enable_clip_distances(context, enable_mask); + wined3d_context_gl_enable_clip_distances(context_gl, enable_mask); } static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR) * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled * specular color. This is wrong: @@ -842,7 +839,8 @@ static void state_specularenable(struct wined3d_context *context, const struct w static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_color color; unsigned int i; @@ -855,7 +853,7 @@ static void state_texfactor(struct wined3d_context *context, const struct wined3 { /* Note the WINED3D_RS value applies to all textures, but GL has one * per texture, so apply it now ready to be used! */ - context_active_texture(context, gl_info, i); + wined3d_context_gl_active_texture(context_gl, gl_info, i); gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color.r); checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);"); @@ -865,7 +863,7 @@ static void state_texfactor(struct wined3d_context *context, const struct wined3 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)"); @@ -908,7 +906,7 @@ static GLenum gl_stencil_op(enum wined3d_stencil_op op) static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; DWORD onesided_enable; DWORD twosided_enable; GLint func; @@ -936,8 +934,8 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ func = GL_ALWAYS; if (!(func_back = wined3d_gl_compare_func(state->render_states[WINED3D_RS_BACK_STENCILFUNC]))) func_back = GL_ALWAYS; - ref = state->render_states[WINED3D_RS_STENCILREF]; mask = state->render_states[WINED3D_RS_STENCILMASK]; + ref = state->render_states[WINED3D_RS_STENCILREF] & ((1 << state->fb->depth_stencil->format->stencil_size) - 1); stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]); depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]); stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]); @@ -1017,10 +1015,10 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ } } -static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_stencilwrite2s_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); @@ -1034,7 +1032,7 @@ static void state_stencilwrite2s(struct wined3d_context *context, const struct w static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; gl_info->gl_ops.gl.p_glStencilMask(mask); checkGLcall("glStencilMask"); @@ -1042,7 +1040,7 @@ static void state_stencilwrite(struct wined3d_context *context, const struct win static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); @@ -1114,7 +1112,7 @@ static void state_fog_vertexpart(struct wined3d_context *context, const struct w void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; float fogstart, fogend; get_fog_start_end(context, state, &fogstart, &fogend); @@ -1130,7 +1128,7 @@ void state_fogstartend(struct wined3d_context *context, const struct wined3d_sta void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; enum fogsource new_source; DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART]; DWORD fogend = state->render_states[WINED3D_RS_FOGEND]; @@ -1140,7 +1138,7 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st if (!state->render_states[WINED3D_RS_FOGENABLE]) { /* No fog? Disable it, and we're done :-) */ - glDisableWINE(GL_FOG); + gl_info->p_glDisableWINE(GL_FOG); checkGLcall("glDisable GL_FOG"); return; } @@ -1277,7 +1275,7 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st } } - glEnableWINE(GL_FOG); + gl_info->p_glEnableWINE(GL_FOG); checkGLcall("glEnable GL_FOG"); if (new_source != context->fog_source || fogstart == fogend) { @@ -1288,7 +1286,7 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; struct wined3d_color color; wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_FOGCOLOR]); @@ -1298,7 +1296,7 @@ void state_fogcolor(struct wined3d_context *context, const struct wined3d_state void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; union { DWORD d; float f; @@ -1311,19 +1309,18 @@ void state_fogdensity(struct wined3d_context *context, const struct wined3d_stat static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; GLenum Parm = 0; - /* Depends on the decoded vertex declaration to read the existence of diffuse data. - * The vertex declaration will call this function if the fixed function pipeline is used. - */ - - if(isStateDirty(context, STATE_VDECL)) { + /* Depends on the decoded vertex declaration to read the existence of + * diffuse data. The vertex declaration will call this function if the + * fixed function pipeline is used. */ + if (isStateDirty(&context_gl->c, STATE_VDECL)) return; - } - context->num_untracked_materials = 0; - if ((context->stream_info.use_map & (1u << WINED3D_FFP_DIFFUSE)) + context_gl->untracked_material_count = 0; + if ((context_gl->c.stream_info.use_map & (1u << WINED3D_FFP_DIFFUSE)) && state->render_states[WINED3D_RS_COLORVERTEX]) { TRACE("diff %d, amb %d, emis %d, spec %d\n", @@ -1339,38 +1336,23 @@ static void state_colormat(struct wined3d_context *context, const struct wined3d else Parm = GL_DIFFUSE; if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1) - { - context->untracked_materials[context->num_untracked_materials] = GL_EMISSION; - context->num_untracked_materials++; - } + context_gl->untracked_materials[context_gl->untracked_material_count++] = GL_EMISSION; if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1) - { - context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR; - context->num_untracked_materials++; - } + context_gl->untracked_materials[context_gl->untracked_material_count++] = GL_SPECULAR; } else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1) { Parm = GL_AMBIENT; if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1) - { - context->untracked_materials[context->num_untracked_materials] = GL_EMISSION; - context->num_untracked_materials++; - } + context_gl->untracked_materials[context_gl->untracked_material_count++] = GL_EMISSION; if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1) - { - context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR; - context->num_untracked_materials++; - } + context_gl->untracked_materials[context_gl->untracked_material_count++] = GL_SPECULAR; } else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1) { Parm = GL_EMISSION; if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1) - { - context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR; - context->num_untracked_materials++; - } + context_gl->untracked_materials[context_gl->untracked_material_count++] = GL_SPECULAR; } else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1) { @@ -1379,7 +1361,8 @@ static void state_colormat(struct wined3d_context *context, const struct wined3d } /* Nothing changed, return. */ - if (Parm == context->tracking_parm) return; + if (Parm == context_gl->tracking_parm) + return; if (!Parm) { @@ -1396,7 +1379,7 @@ static void state_colormat(struct wined3d_context *context, const struct wined3d /* Apparently calls to glMaterialfv are ignored for properties we're * tracking with glColorMaterial, so apply those here. */ - switch (context->tracking_parm) + switch (context_gl->tracking_parm) { case GL_AMBIENT_AND_DIFFUSE: gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient); @@ -1435,12 +1418,12 @@ static void state_colormat(struct wined3d_context *context, const struct wined3d break; } - context->tracking_parm = Parm; + context_gl->tracking_parm = Parm; } static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; union { DWORD d; @@ -1474,7 +1457,7 @@ static void state_linepattern_w(struct wined3d_context *context, const struct wi static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (isStateDirty(context, STATE_VDECL)) return; @@ -1510,7 +1493,7 @@ static void state_psizemin_w(struct wined3d_context *context, const struct wined static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; float min, max; get_pointsize_minmax(context, state, &min, &max); @@ -1523,7 +1506,7 @@ static void state_psizemin_ext(struct wined3d_context *context, const struct win static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; float min, max; get_pointsize_minmax(context, state, &min, &max); @@ -1536,7 +1519,7 @@ static void state_psizemin_arb(struct wined3d_context *context, const struct win static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; float att[3]; float pointsize; @@ -1568,8 +1551,8 @@ static void state_debug_monitor(struct wined3d_context *context, const struct wi static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE]; - const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, @@ -1597,7 +1580,7 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW static void state_colorwrite_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; int index; if (state_id == WINED3D_RS_COLORWRITEENABLE) index = 0; @@ -1608,12 +1591,30 @@ static void state_colorwrite_i(struct wined3d_context *context, const struct win if (index >= gl_info->limits.buffers) WARN("Ignoring color write value for index %d, because gpu only supports %d render targets\n", index, gl_info->limits.buffers); - set_color_mask(context->gl_info, index, state->render_states[state_id]); + set_color_mask(gl_info, index, state->render_states[state_id]); +} + +#ifdef __REACTOS__ +#else +static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + set_color_mask(wined3d_context_gl(context)->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]); +} + +static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + set_color_mask(wined3d_context_gl(context)->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]); +} + +static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + set_color_mask(wined3d_context_gl(context)->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]); } +#endif static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_LOCALVIEWER]) { @@ -1660,7 +1661,7 @@ void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_s void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_POINTSPRITEENABLE]) { @@ -1706,7 +1707,7 @@ static void state_msaa_w(struct wined3d_context *context, const struct wined3d_s static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS]) { @@ -1722,7 +1723,7 @@ static void state_msaa(struct wined3d_context *context, const struct wined3d_sta static void state_line_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_EDGEANTIALIAS] || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE]) @@ -1739,7 +1740,7 @@ static void state_line_antialias(struct wined3d_context *context, const struct w static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_SCISSORTESTENABLE]) { @@ -1770,23 +1771,23 @@ static void state_scissor(struct wined3d_context *context, const struct wined3d_ * doesn't need to be scaled to account for GL vs D3D differences. */ static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] || state->render_states[WINED3D_RS_DEPTHBIAS]) { const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; - float factor, units, scale; + float factor, units, scale, clamp; union { DWORD d; float f; - } scale_bias, const_bias, bias_clamp; + } scale_bias, const_bias; + clamp = state->rasterizer_state ? state->rasterizer_state->desc.depth_bias_clamp : 0.0f; scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]; const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS]; - bias_clamp.d = state->render_states[WINED3D_RS_DEPTHBIASCLAMP]; if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_DEPTH_BIAS) { @@ -1813,16 +1814,14 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 } gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL); - if (gl_info->supported[EXT_POLYGON_OFFSET_CLAMP]) + if (gl_info->supported[ARB_POLYGON_OFFSET_CLAMP]) { - GL_EXTCALL(glPolygonOffsetClampEXT(factor, units, bias_clamp.f)); - checkGLcall("glPolygonOffsetClampEXT(...)"); + gl_info->gl_ops.ext.p_glPolygonOffsetClamp(factor, units, clamp); } else { - if (bias_clamp.f) - WARN("EXT_polygon_offset_clamp extension missing, no support for depth bias clamping.\n"); - + if (clamp != 0.0f) + WARN("Ignoring depth bias clamp %.8e.\n", clamp); gl_info->gl_ops.gl.p_glPolygonOffset(factor, units); } } @@ -1834,28 +1833,6 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 checkGLcall("depth bias"); } -static void state_depthclip(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (state->render_states[WINED3D_RS_DEPTHCLIP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP); - checkGLcall("glDisable(GL_DEPTH_CLAMP)"); - } - else - { - gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP); - checkGLcall("glEnable(GL_DEPTH_CLAMP)"); - } -} - -static void state_depthclip_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - if (!state->render_states[WINED3D_RS_DEPTHCLIP]) - FIXME("Depth clamping not supported by GL.\n"); -} - static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (state->render_states[WINED3D_RS_ZVISIBLE]) @@ -1931,13 +1908,13 @@ static void state_tessellation(struct wined3d_context *context, const struct win static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - union { - DWORD d; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + union + { + uint32_t d; float f; } zmin, zmax; - const struct wined3d_gl_info *gl_info = context->gl_info; - if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB) { zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z]; @@ -3153,10 +3130,11 @@ static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + unsigned int stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); BOOL tex_used = context->fixed_function_usage_map & (1u << stage); - DWORD mapped_stage = context->tex_unit_map[stage]; - const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int mapped_stage = context_gl->tex_unit_map[stage]; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; TRACE("Setting color op for stage %d\n", stage); @@ -3172,7 +3150,7 @@ static void tex_colorop(struct wined3d_context *context, const struct wined3d_st FIXME("Attempt to enable unsupported stage!\n"); return; } - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); } if (stage >= context->lowest_disabled_stage) @@ -3214,10 +3192,11 @@ static void tex_colorop(struct wined3d_context *context, const struct wined3d_st void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + unsigned int stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); BOOL tex_used = context->fixed_function_usage_map & (1u << stage); - DWORD mapped_stage = context->tex_unit_map[stage]; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int mapped_stage = context_gl->tex_unit_map[stage]; DWORD op, arg1, arg2, arg0; TRACE("Setting alpha op for stage %d\n", stage); @@ -3229,7 +3208,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st FIXME("Attempt to enable unsupported stage!\n"); return; } - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); } op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP]; @@ -3239,12 +3218,13 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0]) { - struct wined3d_texture *texture = state->textures[0]; - GLenum texture_dimensions = texture->target; + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[0]); + GLenum texture_dimensions = texture_gl->target; if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size) + if (texture_gl->t.async.color_key_flags & WINED3D_CKEY_SRC_BLT + && !texture_gl->t.resource.format->alpha_size) { /* Color keying needs to pass alpha values from the texture through to have the alpha test work * properly. On the other hand applications can still use texture combiners apparently. This code @@ -3312,9 +3292,10 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int tex = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - unsigned int mapped_stage = context->tex_unit_map[tex]; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int mapped_stage = context_gl->tex_unit_map[tex]; struct wined3d_matrix mat; /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */ @@ -3327,7 +3308,7 @@ static void transform_texture(struct wined3d_context *context, const struct wine if (mapped_stage == WINED3D_UNMAPPED_STAGE) return; if (mapped_stage >= gl_info->limits.textures) return; - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE); checkGLcall("glMatrixMode(GL_TEXTURE)"); @@ -3337,85 +3318,17 @@ static void transform_texture(struct wined3d_context *context, const struct wine checkGLcall("glLoadMatrixf"); } -static void unload_tex_coords(const struct wined3d_gl_info *gl_info) -{ - unsigned int texture_idx; - - for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx) - { - GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx)); - gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si, - GLuint *curVBO, const struct wined3d_state *state) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int mapped_stage = 0; - unsigned int textureNo; - - for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo) - { - int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX]; - - mapped_stage = context->tex_unit_map[textureNo]; - if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; - - if (mapped_stage >= gl_info->limits.texture_coords) - { - FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage); - continue; - } - - if (coordIdx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx)))) - { - const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx]; - - TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n", - textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr); - - if (*curVBO != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - *curVBO = e->data.buffer_object; - } - - GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); - checkGLcall("glClientActiveTextureARB"); - - /* The coords to supply depend completely on the fvf / vertex shader */ - gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else - { - GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1)); - } - } - if (gl_info->supported[NV_REGISTER_COMBINERS]) - { - /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */ - for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo) - { - GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1)); - } - } - - checkGLcall("loadTexCoords"); -} - static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + unsigned int stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int mapped_stage = context_gl->tex_unit_map[stage]; + static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f }; static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f }; static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f }; static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD mapped_stage = context->tex_unit_map[stage]; if (mapped_stage == WINED3D_UNMAPPED_STAGE) { @@ -3423,12 +3336,12 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d return; } - if (mapped_stage >= min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_FRAGMENT_SAMPLERS)) + if (mapped_stage >= min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], WINED3D_MAX_FRAGMENT_SAMPLERS)) { WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage); return; } - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive * @@ -3577,8 +3490,8 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d */ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - unload_tex_coords(gl_info); - load_tex_coords(context, &context->stream_info, &curVBO, state); + wined3d_context_gl_unload_tex_coords(context_gl); + wined3d_context_gl_load_tex_coords(context_gl, &context->stream_info, &curVBO, state); } } @@ -3596,7 +3509,7 @@ static void sampler_texmatrix(struct wined3d_context *context, const struct wine * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the * scaling is reapplied or removed, the texture matrix has to be reapplied. */ - if (sampler < MAX_TEXTURES) + if (sampler < WINED3D_MAX_TEXTURES) { const BOOL tex_is_pow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT); @@ -3612,7 +3525,7 @@ static void sampler_texmatrix(struct wined3d_context *context, const struct wine } } -static enum wined3d_texture_address wined3d_texture_address_mode(const struct wined3d_texture *texture, +static enum wined3d_texture_address wined3d_texture_gl_address_mode(const struct wined3d_texture_gl *texture_gl, enum wined3d_texture_address t) { if (t < WINED3D_TADDRESS_WRAP || t > WINED3D_TADDRESS_MIRROR_ONCE) @@ -3622,7 +3535,7 @@ static enum wined3d_texture_address wined3d_texture_address_mode(const struct wi } /* Cubemaps are always set to clamp, regardless of the sampler state. */ - if (texture->target == GL_TEXTURE_CUBE_MAP_ARB || ((texture->flags & WINED3D_TEXTURE_COND_NP2) + if (texture_gl->target == GL_TEXTURE_CUBE_MAP_ARB || ((texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) && t == WINED3D_TADDRESS_WRAP)) return WINED3D_TADDRESS_CLAMP; @@ -3630,7 +3543,8 @@ static enum wined3d_texture_address wined3d_texture_address_mode(const struct wi } static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc, - const struct wined3d_context *context, const DWORD *sampler_states, const struct wined3d_texture *texture) + const struct wined3d_context_gl *context_gl, const DWORD *sampler_states, + const struct wined3d_texture_gl *texture_gl) { union { @@ -3638,9 +3552,9 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc DWORD d; } lod_bias; - desc->address_u = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]); - desc->address_v = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]); - desc->address_w = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]); + desc->address_u = wined3d_texture_gl_address_mode(texture_gl, sampler_states[WINED3D_SAMP_ADDRESS_U]); + desc->address_v = wined3d_texture_gl_address_mode(texture_gl, sampler_states[WINED3D_SAMP_ADDRESS_V]); + desc->address_w = wined3d_texture_gl_address_mode(texture_gl, sampler_states[WINED3D_SAMP_ADDRESS_W]); wined3d_color_from_d3dcolor((struct wined3d_color *)desc->border_color, sampler_states[WINED3D_SAMP_BORDER_COLOR]); if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC) @@ -3664,23 +3578,23 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC && sampler_states[WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_ANISOTROPIC) - || (texture->flags & WINED3D_TEXTURE_COND_NP2)) + || (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2)) desc->max_anisotropy = 1; - desc->compare = texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW; + desc->compare = texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_SHADOW; desc->comparison_func = WINED3D_CMP_LESSEQUAL; - desc->srgb_decode = sampler_states[WINED3D_SAMP_SRGB_TEXTURE]; + desc->srgb_decode = is_srgb_enabled(sampler_states); - if (!(texture->resource.format_flags & WINED3DFMT_FLAG_FILTERING)) + if (!(texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_FILTERING)) { desc->mag_filter = WINED3D_TEXF_POINT; desc->min_filter = WINED3D_TEXF_POINT; desc->mip_filter = WINED3D_TEXF_NONE; } - if (texture->flags & WINED3D_TEXTURE_COND_NP2) + if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) { desc->mip_filter = WINED3D_TEXF_NONE; - if (context->gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) + if (context_gl->gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) desc->min_filter = WINED3D_TEXF_POINT; } } @@ -3690,9 +3604,10 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc * texture states. */ static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - DWORD sampler_idx = state_id - STATE_SAMPLER(0); - DWORD mapped_stage = context->tex_unit_map[sampler_idx]; - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + unsigned int sampler_idx = state_id - STATE_SAMPLER(0); + unsigned int mapped_stage = context_gl->tex_unit_map[sampler_idx]; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; TRACE("Sampler %u.\n", sampler_idx); @@ -3704,21 +3619,21 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state if (mapped_stage >= gl_info->limits.graphics_samplers) return; - context_active_texture(context, gl_info, mapped_stage); + wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage); if (state->textures[sampler_idx]) { - BOOL srgb = state->sampler_states[sampler_idx][WINED3D_SAMP_SRGB_TEXTURE]; + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[sampler_idx]); const DWORD *sampler_states = state->sampler_states[sampler_idx]; - struct wined3d_texture *texture = state->textures[sampler_idx]; struct wined3d_device *device = context->device; + BOOL srgb = is_srgb_enabled(sampler_states); struct wined3d_sampler_desc desc; struct wined3d_sampler *sampler; struct wine_rb_entry *entry; - wined3d_sampler_desc_from_sampler_states(&desc, context, sampler_states, texture); + wined3d_sampler_desc_from_sampler_states(&desc, context_gl, sampler_states, texture_gl); - wined3d_texture_bind(texture, context, srgb); + wined3d_texture_gl_bind(texture_gl, context_gl, srgb); if ((entry = wine_rb_get(&device->samplers, &desc))) { @@ -3739,15 +3654,15 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state } } - wined3d_sampler_bind(sampler, mapped_stage, texture, context); + wined3d_sampler_gl_bind(wined3d_sampler_gl(sampler), mapped_stage, texture_gl, context_gl); /* Trigger shader constant reloading (for NP2 texcoord fixup) */ - if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) + if (!(texture_gl->t.flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; } else { - context_bind_texture(context, GL_NONE, 0); + wined3d_context_gl_bind_texture(context_gl, GL_NONE, 0); if (gl_info->supported[ARB_SAMPLER_OBJECTS]) { GL_EXTCALL(glBindSampler(mapped_stage, 0)); @@ -3767,7 +3682,7 @@ void apply_pixelshader(struct wined3d_context *context, const struct wined3d_sta /* Former draw without a pixel shader, some samplers may be * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE * make sure to enable them. */ - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) { if (!isStateDirty(context, STATE_SAMPLER(i))) sampler(context, state, STATE_SAMPLER(i)); @@ -3814,7 +3729,7 @@ static void shader_bumpenv(struct wined3d_context *context, const struct wined3d static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; struct wined3d_matrix mat; /* This function is called by transform_view below if the view matrix was changed too @@ -3835,7 +3750,7 @@ static void transform_world(struct wined3d_context *context, const struct wined3 void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; UINT index = state_id - STATE_CLIPPLANE(0); GLdouble plane[4]; @@ -3868,41 +3783,9 @@ void clipplane(struct wined3d_context *context, const struct wined3d_state *stat static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)); - const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum glMat; - - TRACE("Setting world matrix %d\n", matrix); - - if (matrix >= gl_info->limits.blends) - { - WARN("Unsupported blend matrix set\n"); - return; - } + unsigned int matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)); - if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW))) - return; - - /* GL_MODELVIEW0_ARB: 0x1700 - * GL_MODELVIEW1_ARB: 0x850a - * GL_MODELVIEW2_ARB: 0x8722 - * GL_MODELVIEW3_ARB: 0x8723 - * etc - * GL_MODELVIEW31_ARB: 0x873f - */ - if(matrix == 1) glMat = GL_MODELVIEW1_ARB; - else glMat = GL_MODELVIEW2_ARB - 2 + matrix; - - gl_info->gl_ops.gl.p_glMatrixMode(glMat); - checkGLcall("glMatrixMode(glMat)"); - - /* World matrix 0 is multiplied with the view matrix because d3d uses 3 - * matrices while gl uses only 2. To avoid weighting the view matrix - * incorrectly it has to be multiplied into every GL modelview matrix. */ - gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); - checkGLcall("glLoadMatrixf"); - gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)]._11); - checkGLcall("glMultMatrixf"); + WARN("Unsupported world matrix %u set.\n", matrix); } static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -3917,53 +3800,9 @@ static void state_vertexblend_w(struct wined3d_context *context, const struct wi else WARN("Vertex blend flags %#x not supported.\n", f); } -static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND]; - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_device *device = context->device; - static unsigned int once; - - switch (val) - { - case WINED3D_VBF_1WEIGHTS: - case WINED3D_VBF_2WEIGHTS: - case WINED3D_VBF_3WEIGHTS: - gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB); - checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)"); - - /* D3D adds one more matrix which has weight (1 - sum(weights)). - * This is enabled at context creation with enabling - * GL_WEIGHT_SUM_UNITY_ARB. */ - GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1)); - - if (!device->vertexBlendUsed) - { - unsigned int i; - for (i = 1; i < gl_info->limits.blends; ++i) - { - if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)))) - transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))); - } - device->vertexBlendUsed = TRUE; - } - break; - - case WINED3D_VBF_TWEENING: - case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */ - if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val); - else WARN("Vertex blend flags %#x not supported.\n", val); - /* Fall through. */ - case WINED3D_VBF_DISABLE: - gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB); - checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)"); - break; - } -} - static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; const struct wined3d_light_info *light = NULL; unsigned int k; @@ -3981,7 +3820,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d /* Reset lights. TODO: Call light apply func */ for (k = 0; k < gl_info->limits.lights; ++k) { - if (!(light = state->lights[k])) + if (!(light = state->light_state.lights[k])) continue; if (light->OriginalParms.type == WINED3D_LIGHT_DIRECTIONAL) gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, &light->direction.x); @@ -4011,21 +3850,11 @@ static void transform_view(struct wined3d_context *context, const struct wined3d * No need to do it here if the state is scheduled for update. */ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))) transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); - - /* Avoid looping over a number of matrices if the app never used the functionality */ - if (context->device->vertexBlendUsed) - { - for (k = 1; k < gl_info->limits.blends; ++k) - { - if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)))) - transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))); - } - } } static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; struct wined3d_matrix projection; gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); @@ -4036,523 +3865,24 @@ static void transform_projection(struct wined3d_context *context, const struct w checkGLcall("glLoadMatrixf"); } -/* This should match any arrays loaded in load_vertex_data. - * TODO: Only load / unload arrays if we have to. */ -static void unload_vertex_data(const struct wined3d_gl_info *gl_info) -{ - gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY); - gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY); - gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY); - if (gl_info->supported[EXT_SECONDARY_COLOR]) - gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); - if (gl_info->supported[ARB_VERTEX_BLEND]) - gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB); - unload_tex_coords(gl_info); -} - -static inline void unload_numbered_array(struct wined3d_context *context, int i) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - GL_EXTCALL(glDisableVertexAttribArray(i)); - checkGLcall("glDisableVertexAttribArray"); - if (gl_info->supported[ARB_INSTANCED_ARRAYS]) - GL_EXTCALL(glVertexAttribDivisor(i, 0)); - - context->numbered_array_mask &= ~(1u << i); -} - -/* This should match any arrays loaded in loadNumberedArrays - * TODO: Only load / unload arrays if we have to. */ -static void unload_numbered_arrays(struct wined3d_context *context) -{ - /* disable any attribs (this is the same for both GLSL and ARB modes) */ - int i; - - for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) { - unload_numbered_array(context, i); - } -} - -static void load_numbered_arrays(struct wined3d_context *context, - const struct wined3d_stream_info *stream_info, const struct wined3d_state *state) -{ - const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - const struct wined3d_gl_info *gl_info = context->gl_info; - GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - unsigned int i; - - /* Default to no instancing */ - context->instance_count = 0; - - for (i = 0; i < MAX_ATTRIBS; ++i) - { - const struct wined3d_stream_info_element *element = &stream_info->elements[i]; - const struct wined3d_stream_state *stream; - - if (!(stream_info->use_map & (1u << i))) - { - if (context->numbered_array_mask & (1u << i)) - unload_numbered_array(context, i); - if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE) - GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f)); - else - GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f)); - continue; - } - - stream = &state->streams[element->stream_idx]; - - if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count) - context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; - - if (gl_info->supported[ARB_INSTANCED_ARRAYS]) - { - GL_EXTCALL(glVertexAttribDivisor(i, element->divisor)); - } - else if (element->divisor) - { - /* Unload instanced arrays, they will be loaded using - * immediate mode instead. */ - if (context->numbered_array_mask & (1u << i)) - unload_numbered_array(context, i); - continue; - } - - TRACE_(d3d_shader)("Loading array %u [VBO=%u].\n", i, element->data.buffer_object); - - if (element->stride) - { - if (curVBO != element->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object)); - checkGLcall("glBindBuffer"); - curVBO = element->data.buffer_object; - } - /* Use the VBO to find out if a vertex buffer exists, not the vb - * pointer. vb can point to a user pointer data blob. In that case - * curVBO will be 0. If there is a vertex buffer but no vbo we - * won't be load converted attributes anyway. */ - if (vs && vs->reg_maps.shader_version.major >= 4 - && (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER)) - { - GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, - element->stride, element->data.addr + state->load_base_vertex_index * element->stride)); - } - else - { - GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, - element->format->gl_normalized, element->stride, - element->data.addr + state->load_base_vertex_index * element->stride)); - } - - if (!(context->numbered_array_mask & (1u << i))) - { - GL_EXTCALL(glEnableVertexAttribArray(i)); - context->numbered_array_mask |= (1u << i); - } - } - else - { - /* Stride = 0 means always the same values. - * glVertexAttribPointer doesn't do that. Instead disable the - * pointer and set up the attribute statically. But we have to - * figure out the system memory address. */ - const BYTE *ptr = element->data.addr; - if (element->data.buffer_object) - ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context); - - if (context->numbered_array_mask & (1u << i)) - unload_numbered_array(context, i); - - switch (element->format->id) - { - case WINED3DFMT_R32_FLOAT: - GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R32G32_FLOAT: - GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R32G32B32_FLOAT: - GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr)); - break; - case WINED3DFMT_R32G32B32A32_FLOAT: - GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr)); - break; - - case WINED3DFMT_R8G8B8A8_UINT: - GL_EXTCALL(glVertexAttrib4ubv(i, ptr)); - break; - case WINED3DFMT_B8G8R8A8_UNORM: - if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) - { - const DWORD *src = (const DWORD *)ptr; - DWORD c = *src & 0xff00ff00u; - c |= (*src & 0xff0000u) >> 16; - c |= (*src & 0xffu) << 16; - GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c)); - break; - } - /* else fallthrough */ - case WINED3DFMT_R8G8B8A8_UNORM: - GL_EXTCALL(glVertexAttrib4Nubv(i, ptr)); - break; - - case WINED3DFMT_R16G16_SINT: - GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr)); - break; - case WINED3DFMT_R16G16B16A16_SINT: - GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr)); - break; - - case WINED3DFMT_R16G16_SNORM: - { - const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1}; - GL_EXTCALL(glVertexAttrib4Nsv(i, s)); - break; - } - case WINED3DFMT_R16G16_UNORM: - { - const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1}; - GL_EXTCALL(glVertexAttrib4Nusv(i, s)); - break; - } - case WINED3DFMT_R16G16B16A16_SNORM: - GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr)); - break; - case WINED3DFMT_R16G16B16A16_UNORM: - GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr)); - break; - - case WINED3DFMT_R10G10B10X2_UINT: - FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n"); - /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */ - break; - case WINED3DFMT_R10G10B10X2_SNORM: - FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n"); - /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */ - break; - - case WINED3DFMT_R16G16_FLOAT: - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - /* Not supported by GL_ARB_half_float_vertex. */ - GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr)); - } - else - { - float x = float_16_to_32(((const unsigned short *)ptr) + 0); - float y = float_16_to_32(((const unsigned short *)ptr) + 1); - GL_EXTCALL(glVertexAttrib2f(i, x, y)); - } - break; - case WINED3DFMT_R16G16B16A16_FLOAT: - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - /* Not supported by GL_ARB_half_float_vertex. */ - GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr)); - } - else - { - float x = float_16_to_32(((const unsigned short *)ptr) + 0); - float y = float_16_to_32(((const unsigned short *)ptr) + 1); - float z = float_16_to_32(((const unsigned short *)ptr) + 2); - float w = float_16_to_32(((const unsigned short *)ptr) + 3); - GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w)); - } - break; - - default: - ERR("Unexpected declaration in stride 0 attributes.\n"); - break; - - } - } - } - checkGLcall("Loading numbered arrays"); -} - -static void load_vertex_data(struct wined3d_context *context, - const struct wined3d_stream_info *si, const struct wined3d_state *state) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - const struct wined3d_stream_info_element *e; - - TRACE("Using fast vertex array code\n"); - - /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */ - context->instance_count = 0; - - /* Blend Data ---------------------------------------------- */ - if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT)) - || si->use_map & (1u << WINED3D_FFP_BLENDINDICES)) - { - e = &si->elements[WINED3D_FFP_BLENDWEIGHT]; - - if (gl_info->supported[ARB_VERTEX_BLEND]) - { - TRACE("Blend %u %p %u\n", e->format->component_count, - e->data.addr + state->load_base_vertex_index * e->stride, e->stride); - - gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB); - checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)"); - - GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1)); - - if (curVBO != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - curVBO = e->data.buffer_object; - } - - TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n", - e->format->gl_vtx_format, - e->format->gl_vtx_type, - e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - - checkGLcall("glWeightPointerARB"); - - if (si->use_map & (1u << WINED3D_FFP_BLENDINDICES)) - { - static BOOL warned; - if (!warned) - { - FIXME("blendMatrixIndices support\n"); - warned = TRUE; - } - } - } - else - { - /* TODO: Support vertex blending in immediate mode draws. No need - * to write a FIXME here, this is done after the general vertex - * declaration decoding. */ - WARN("Vertex blending not supported.\n"); - } - } - else - { - if (gl_info->supported[ARB_VERTEX_BLEND]) - { - static const GLbyte one = 1; - GL_EXTCALL(glWeightbvARB(1, &one)); - checkGLcall("glWeightbvARB(gl_info->max_blends, weights)"); - } - } - - /* Point Size ----------------------------------------------*/ - if (si->use_map & (1u << WINED3D_FFP_PSIZE)) - { - /* no such functionality in the fixed function GL pipeline */ - TRACE("Cannot change ptSize here in openGl\n"); - /* TODO: Implement this function in using shaders if they are available */ - } - - /* Vertex Pointers -----------------------------------------*/ - if (si->use_map & (1u << WINED3D_FFP_POSITION)) - { - e = &si->elements[WINED3D_FFP_POSITION]; - - if (curVBO != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - curVBO = e->data.buffer_object; - } - - TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", - e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - checkGLcall("glVertexPointer(...)"); - gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY); - checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); - } - - /* Normals -------------------------------------------------*/ - if (si->use_map & (1u << WINED3D_FFP_NORMAL)) - { - e = &si->elements[WINED3D_FFP_NORMAL]; - - if (curVBO != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - curVBO = e->data.buffer_object; - } - - TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - checkGLcall("glNormalPointer(...)"); - gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY); - checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); - - } - else - { - gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0); - checkGLcall("glNormal3f(0, 0, 0)"); - } - - /* Diffuse Colour --------------------------------------------*/ - if (si->use_map & (1u << WINED3D_FFP_DIFFUSE)) - { - e = &si->elements[WINED3D_FFP_DIFFUSE]; - - if (curVBO != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - curVBO = e->data.buffer_object; - } - - TRACE("glColorPointer(%#x, %#x %#x, %p);\n", - e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); - gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY); - checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); - - } - else - { - gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - checkGLcall("glColor4f(1, 1, 1, 1)"); - } - - /* Specular Colour ------------------------------------------*/ - if (si->use_map & (1u << WINED3D_FFP_SPECULAR)) - { - TRACE("setting specular colour\n"); - - e = &si->elements[WINED3D_FFP_SPECULAR]; - - if (gl_info->supported[EXT_SECONDARY_COLOR]) - { - GLenum type = e->format->gl_vtx_type; - GLint format = e->format->gl_vtx_format; - - if (curVBO != e->data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object)); - checkGLcall("glBindBuffer"); - curVBO = e->data.buffer_object; - } - - if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA)) - { - /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha - * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function - * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts - * 4 component secondary colors use it - */ - TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); - } - else - { - switch(type) - { - case GL_UNSIGNED_BYTE: - TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); - break; - - default: - FIXME("Add 4 component specular color pointers for type %x\n", type); - /* Make sure that the right color component is dropped */ - TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride); - GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, - e->data.addr + state->load_base_vertex_index * e->stride)); - checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); - } - } - gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); - checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - } - else - { - WARN("Specular colour is not supported in this GL implementation.\n"); - } - } - else - { - if (gl_info->supported[EXT_SECONDARY_COLOR]) - { - GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); - checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); - } - else - { - WARN("Specular colour is not supported in this GL implementation.\n"); - } - } - - /* Texture coords -------------------------------------------*/ - load_tex_coords(context, si, &curVBO, state); -} - static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - BOOL load_numbered = context->d3d_info->ffp_generic_attributes - || (use_vs(state) && !context->use_immediate_mode_draw); - BOOL load_named = !context->d3d_info->ffp_generic_attributes - && !use_vs(state) && !context->use_immediate_mode_draw; - - if (isStateDirty(context, STATE_VDECL)) return; - if (context->numberedArraysLoaded && !load_numbered) - { - unload_numbered_arrays(context); - context->numberedArraysLoaded = FALSE; - context->numbered_array_mask = 0; - } - else if (context->namedArraysLoaded) - { - unload_vertex_data(context->gl_info); - context->namedArraysLoaded = FALSE; - } - - if (load_numbered) - { - TRACE("Loading numbered arrays\n"); - load_numbered_arrays(context, &context->stream_info, state); - context->numberedArraysLoaded = TRUE; - } - else if (load_named) - { - TRACE("Loading vertex data\n"); - load_vertex_data(context, &context->stream_info, state); - context->namedArraysLoaded = TRUE; - } + if (isStateDirty(context, STATE_VDECL)) + return; + wined3d_context_gl_update_stream_sources(wined3d_context_gl(context), state); } static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (isStateDirty(context, STATE_STREAMSRC)) return; - streamsrc(context, state, STATE_STREAMSRC); + wined3d_context_gl_update_stream_sources(wined3d_context_gl(context), state); } static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; BOOL useVertexShaderFunction = use_vs(state); BOOL updateFog = FALSE; BOOL transformed; @@ -4628,7 +3958,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine /* Disable all clip planes to get defined results on all drivers. See comment in the * state_clipping state handler */ - context_enable_clip_distances(context, 0); + wined3d_context_gl_enable_clip_distances(context_gl, 0); if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE]) { @@ -4673,7 +4003,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine { unsigned int i; - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i))) transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); @@ -4685,30 +4015,18 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine } } -static void get_viewport(struct wined3d_context *context, const struct wined3d_state *state, - struct wined3d_viewport *viewport) +static void get_viewports(struct wined3d_context *context, const struct wined3d_state *state, + unsigned int viewport_count, struct wined3d_viewport *viewports) { const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; - unsigned int width, height; - - *viewport = state->viewport; + unsigned int width, height, i; - if (target) - { - if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT) - { - if (viewport->width > target->width) - viewport->width = target->width; - if (viewport->height > target->height) - viewport->height = target->height; - } - } + for (i = 0; i < viewport_count; ++i) + viewports[i] = state->viewports[i]; - /* - * Note: GL requires lower left, DirectX supplies upper left. This is - * reversed when using offscreen rendering. - */ + /* Note: GL uses a lower left origin while DirectX uses upper left. This + * is reversed when using offscreen rendering. */ if (context->render_offscreen) return; @@ -4726,42 +4044,96 @@ static void get_viewport(struct wined3d_context *context, const struct wined3d_s return; } - viewport->y = height - (viewport->y + viewport->height); + for (i = 0; i < viewport_count; ++i) + viewports[i].y = height - (viewports[i].y + viewports[i].height); } static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS]; - get_viewport(context, state, &vp); + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS]; + GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS]; - gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); + unsigned int i, reset_count = 0; - if (gl_info->supported[ARB_VIEWPORT_ARRAY]) - GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height)); + get_viewports(context, state, state->viewport_count, vp); + for (i = 0; i < state->viewport_count; ++i) + { + depth_ranges[i * 2] = vp[i].min_z; + depth_ranges[i * 2 + 1] = vp[i].max_z; + + viewports[i * 4] = vp[i].x; + viewports[i * 4 + 1] = vp[i].y; + viewports[i * 4 + 2] = vp[i].width; + viewports[i * 4 + 3] = vp[i].height; + } + + if (context->viewport_count > state->viewport_count) + reset_count = context->viewport_count - state->viewport_count; + + if (reset_count) + { + memset(&depth_ranges[state->viewport_count * 2], 0, reset_count * 2 * sizeof(*depth_ranges)); + memset(&viewports[state->viewport_count * 4], 0, reset_count * 4 * sizeof(*viewports)); + } + + GL_EXTCALL(glDepthRangeArrayv(0, state->viewport_count + reset_count, depth_ranges)); + GL_EXTCALL(glViewportArrayv(0, state->viewport_count + reset_count, viewports)); + context->viewport_count = state->viewport_count; + } else - gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height); + { + get_viewports(context, state, 1, vp); + gl_info->gl_ops.gl.p_glDepthRange(vp[0].min_z, vp[0].max_z); + gl_info->gl_ops.gl.p_glViewport(vp[0].x, vp[0].y, vp[0].width, vp[0].height); + } checkGLcall("setting clip space and viewport"); } static void viewport_miscpart_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; /* See get_projection_matrix() in utils.c for a discussion about those values. */ float pixel_center_offset = context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f; - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp; + struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS]; + GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS]; + GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS]; + unsigned int i, reset_count = 0; - get_viewport(context, state, &vp); - vp.x += pixel_center_offset; - vp.y += pixel_center_offset; - - gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); + get_viewports(context, state, state->viewport_count, vp); GL_EXTCALL(glClipControl(context->render_offscreen ? GL_UPPER_LEFT : GL_LOWER_LEFT, GL_ZERO_TO_ONE)); - GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height)); + + for (i = 0; i < state->viewport_count; ++i) + { + depth_ranges[i * 2] = vp[i].min_z; + depth_ranges[i * 2 + 1] = vp[i].max_z; + + viewports[i * 4] = vp[i].x + pixel_center_offset; + viewports[i * 4 + 1] = vp[i].y + pixel_center_offset; + viewports[i * 4 + 2] = vp[i].width; + viewports[i * 4 + 3] = vp[i].height; + } + + if (context->viewport_count > state->viewport_count) + reset_count = context->viewport_count - state->viewport_count; + + if (reset_count) + { + memset(&depth_ranges[state->viewport_count * 2], 0, reset_count * 2 * sizeof(*depth_ranges)); + memset(&viewports[state->viewport_count * 4], 0, reset_count * 4 * sizeof(*viewports)); + } + + GL_EXTCALL(glDepthRangeArrayv(0, state->viewport_count + reset_count, depth_ranges)); + GL_EXTCALL(glViewportArrayv(0, state->viewport_count + reset_count, viewports)); + context->viewport_count = state->viewport_count; + checkGLcall("setting clip space and viewport"); } @@ -4778,9 +4150,9 @@ static void viewport_vertexpart(struct wined3d_context *context, const struct wi static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; UINT Index = state_id - STATE_ACTIVELIGHT(0); - const struct wined3d_light_info *lightInfo = state->lights[Index]; + const struct wined3d_light_info *lightInfo = state->light_state.lights[Index]; if (!lightInfo) { @@ -4790,35 +4162,15 @@ static void light(struct wined3d_context *context, const struct wined3d_state *s else { float quad_att; - float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); gl_info->gl_ops.gl.p_glPushMatrix(); gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); - /* Diffuse: */ - colRGBA[0] = lightInfo->OriginalParms.diffuse.r; - colRGBA[1] = lightInfo->OriginalParms.diffuse.g; - colRGBA[2] = lightInfo->OriginalParms.diffuse.b; - colRGBA[3] = lightInfo->OriginalParms.diffuse.a; - gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA); - checkGLcall("glLightfv"); - - /* Specular */ - colRGBA[0] = lightInfo->OriginalParms.specular.r; - colRGBA[1] = lightInfo->OriginalParms.specular.g; - colRGBA[2] = lightInfo->OriginalParms.specular.b; - colRGBA[3] = lightInfo->OriginalParms.specular.a; - gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA); - checkGLcall("glLightfv"); - - /* Ambient */ - colRGBA[0] = lightInfo->OriginalParms.ambient.r; - colRGBA[1] = lightInfo->OriginalParms.ambient.g; - colRGBA[2] = lightInfo->OriginalParms.ambient.b; - colRGBA[3] = lightInfo->OriginalParms.ambient.a; - gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA); + gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, &lightInfo->OriginalParms.diffuse.r); + gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, &lightInfo->OriginalParms.specular.r); + gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, &lightInfo->OriginalParms.ambient.r); checkGLcall("glLightfv"); if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN) @@ -4901,49 +4253,87 @@ static void light(struct wined3d_context *context, const struct wined3d_state *s static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const RECT *r = &state->scissor_rect; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + unsigned int height = 0; + const RECT *r; /* Warning: glScissor uses window coordinates, not viewport coordinates, * so our viewport correction does not apply. Warning2: Even in windowed * mode the coords are relative to the window, not the screen. */ - TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r)); - if (context->render_offscreen) - { - gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top); - } - else + if (!context->render_offscreen) { const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; - UINT height; - UINT width; + unsigned int width; wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); - gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top); } - checkGLcall("glScissor"); + + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + GLint sr[4 * WINED3D_MAX_VIEWPORTS]; + unsigned int i, reset_count = 0; + + for (i = 0; i < state->scissor_rect_count; ++i) + { + r = &state->scissor_rects[i]; + + sr[i * 4] = r->left; + sr[i * 4 + 1] = height ? height - r->top : r->top; + sr[i * 4 + 2] = r->right - r->left; + sr[i * 4 + 3] = r->bottom - r->top; + } + + if (context->scissor_rect_count > state->scissor_rect_count) + reset_count = context->scissor_rect_count - state->scissor_rect_count; + + if (reset_count) + memset(&sr[state->scissor_rect_count * 4], 0, reset_count * 4 * sizeof(GLint)); + + GL_EXTCALL(glScissorArrayv(0, state->scissor_rect_count + reset_count, sr)); + checkGLcall("glScissorArrayv"); + context->scissor_rect_count = state->scissor_rect_count; + } + else + { + r = &state->scissor_rects[0]; + gl_info->gl_ops.gl.p_glScissor(r->left, height ? height - r->top : r->top, + r->right - r->left, r->bottom - r->top); + checkGLcall("glScissor"); + } } static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; const struct wined3d_stream_info *stream_info = &context->stream_info; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_buffer *ib = state->index_buffer; - if (!state->index_buffer || !stream_info->all_vbo) - { + if (!ib || !stream_info->all_vbo) GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } else - { - struct wined3d_buffer *ib = state->index_buffer; GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer_object)); +} + +static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) +{ + if (!gl_info->supported[ARB_DEPTH_CLAMP]) + { + if (r && !r->desc.depth_clip) + FIXME("Depth clamp not supported by this GL implementation.\n"); + return; } + + if (r && !r->desc.depth_clip) + gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP); + else + gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP); + checkGLcall("depth clip"); } -static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void rasterizer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; GLenum mode; mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW; @@ -4952,17 +4342,23 @@ static void frontface(struct wined3d_context *context, const struct wined3d_stat gl_info->gl_ops.gl.p_glFrontFace(mode); checkGLcall("glFrontFace"); + if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_DEPTHBIAS))) + state_depthbias(context, state, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + depth_clip(state->rasterizer_state, gl_info); } -static void frontface_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; GLenum mode; mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW; gl_info->gl_ops.gl.p_glFrontFace(mode); checkGLcall("glFrontFace"); + if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_DEPTHBIAS))) + state_depthbias(context, state, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); + depth_clip(state->rasterizer_state, gl_info); } static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4978,7 +4374,7 @@ static void psorigin_w(struct wined3d_context *context, const struct wined3d_sta static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT; GL_EXTCALL(glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin)); @@ -4987,7 +4383,7 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); @@ -4999,7 +4395,7 @@ void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state static void state_cb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; enum wined3d_shader_type shader_type; struct wined3d_buffer *buffer; unsigned int i, base, count; @@ -5063,13 +4459,14 @@ static void state_uav_warn(struct wined3d_context *context, const struct wined3d static void state_so(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_buffer *buffer; unsigned int offset, size, i; TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - context_end_transform_feedback(context); + wined3d_context_gl_end_transform_feedback(context_gl); for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) { @@ -5086,8 +4483,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state offset = 0; } size = buffer->resource.size - offset; - GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, - buffer->buffer_object, offset, size)); + GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, buffer->buffer_object, offset, size)); } checkGLcall("bind transform feedback buffers"); } @@ -5097,7 +4493,7 @@ static void state_so_warn(struct wined3d_context *context, const struct wined3d_ WARN("Transform feedback not supported.\n"); } -const struct StateEntryTemplate misc_state_template[] = +const struct wined3d_state_entry_template misc_state_template[] = { { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb_warn, }, WINED3D_GL_EXT_NONE }, @@ -5130,10 +4526,12 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_BLEND, { STATE_BLEND, state_blend_object }, WINED3D_GL_EXT_NONE }, + { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor }, EXT_BLEND_COLOR }, + { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor_w}, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, - { STATE_FRONTFACE, { STATE_FRONTFACE, frontface_cc }, ARB_CLIP_CONTROL }, - { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, + { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer_cc }, ARB_CLIP_CONTROL }, + { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, state_nop }, ARB_CLIP_CONTROL }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 }, @@ -5226,7 +4624,7 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE }, + { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s_ext}, EXT_STENCIL_TWO_SIDE }, { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -5288,13 +4686,8 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR }, - { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_DEPTHBIASCLAMP), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip }, ARB_DEPTH_CLAMP }, - { STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip_w }, WINED3D_GL_EXT_NONE }, /* Samplers */ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE }, @@ -5327,7 +4720,7 @@ const struct StateEntryTemplate misc_state_template[] = {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; -static const struct StateEntryTemplate vp_ffp_states[] = +static const struct wined3d_state_entry_template vp_ffp_states[] = { { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, { STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, @@ -5653,7 +5046,6 @@ static const struct StateEntryTemplate vp_ffp_states[] = { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND }, { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, @@ -5703,7 +5095,7 @@ static const struct StateEntryTemplate vp_ffp_states[] = {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; -static const struct StateEntryTemplate ffp_fragmentstate_template[] = { +static const struct wined3d_state_entry_template ffp_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE }, @@ -5812,21 +5204,23 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { }; /* Context activation is done by the caller. */ -static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {} +static void ffp_pipe_enable(const struct wined3d_context *context, BOOL enable) {} static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { return shader_priv; } -static void ffp_free(struct wined3d_device *device) {} +static void ffp_free(struct wined3d_device *device, struct wined3d_context *context) {} -static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps) +static void vp_ffp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + caps->xyzrhw = FALSE; caps->ffp_generic_attributes = FALSE; caps->max_active_lights = gl_info->limits.lights; - caps->max_vertex_blend_matrices = gl_info->limits.blends; + caps->max_vertex_blend_matrices = 1; caps->max_vertex_blend_matrix_index = 0; caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS | WINED3DVTXPCAPS_MATERIALSOURCE7 @@ -5849,7 +5243,7 @@ static DWORD vp_ffp_get_emul_mask(const struct wined3d_gl_info *gl_info) const struct wined3d_vertex_pipe_ops ffp_vertex_pipe = { - ffp_enable, + ffp_pipe_enable, vp_ffp_get_caps, vp_ffp_get_emul_mask, ffp_alloc, @@ -5857,8 +5251,10 @@ const struct wined3d_vertex_pipe_ops ffp_vertex_pipe = vp_ffp_states, }; -static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) +static void ffp_fragment_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + caps->wined3d_caps = 0; caps->PrimitiveMiscCaps = 0; caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD @@ -5918,8 +5314,9 @@ static void ffp_none_context_free(struct wined3d_context *context) { } -const struct fragment_pipeline ffp_fragment_pipeline = { - ffp_enable, +const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline = +{ + ffp_pipe_enable, ffp_fragment_get_caps, ffp_fragment_get_emul_mask, ffp_alloc, @@ -5930,16 +5327,16 @@ const struct fragment_pipeline ffp_fragment_pipeline = { ffp_fragmentstate_template, }; -static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {} +static void none_pipe_enable(const struct wined3d_context *context, BOOL enable) {} static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv) { return shader_priv; } -static void none_free(struct wined3d_device *device) {} +static void none_free(struct wined3d_device *device, struct wined3d_context *context) {} -static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps) +static void vp_none_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps) { memset(caps, 0, sizeof(*caps)); } @@ -5951,7 +5348,7 @@ static DWORD vp_none_get_emul_mask(const struct wined3d_gl_info *gl_info) const struct wined3d_vertex_pipe_ops none_vertex_pipe = { - none_enable, + none_pipe_enable, vp_none_get_caps, vp_none_get_emul_mask, none_alloc, @@ -5959,7 +5356,7 @@ const struct wined3d_vertex_pipe_ops none_vertex_pipe = NULL, }; -static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) +static void fp_none_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps) { memset(caps, 0, sizeof(*caps)); } @@ -5974,9 +5371,9 @@ static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup) return is_identity_fixup(fixup); } -const struct fragment_pipeline none_fragment_pipe = +const struct wined3d_fragment_pipe_ops none_fragment_pipe = { - none_enable, + none_pipe_enable, fp_none_get_caps, fp_none_get_emul_mask, none_alloc, @@ -6007,13 +5404,12 @@ static void multistate_apply_3(struct wined3d_context *context, const struct win context->device->multistate_funcs[state_id][2](context, state, state_id); } -static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info) +static void prune_invalid_states(struct wined3d_state_entry *state_table, const struct wined3d_d3d_info *d3d_info) { unsigned int start, last, i; start = STATE_TEXTURESTAGE(d3d_info->limits.ffp_blend_stages, 0); - last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE); + last = STATE_TEXTURESTAGE(WINED3D_MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE); for (i = start; i <= last; ++i) { state_table[i].representative = 0; @@ -6021,14 +5417,15 @@ static void prune_invalid_states(struct StateEntry *state_table, const struct wi } start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + d3d_info->limits.ffp_blend_stages); - last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1); + last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + WINED3D_MAX_TEXTURES - 1); for (i = start; i <= last; ++i) { state_table[i].representative = 0; state_table[i].apply = state_undefined; } - start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(d3d_info->limits.ffp_vertex_blend_matrices)); + start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(max(d3d_info->limits.ffp_vertex_blend_matrices, + d3d_info->limits.ffp_max_vertex_blend_matrix_index + 1))); last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)); for (i = start; i <= last; ++i) { @@ -6037,7 +5434,7 @@ static void prune_invalid_states(struct StateEntry *state_table, const struct wi } } -static void validate_state_table(struct StateEntry *state_table) +static void validate_state_table(struct wined3d_state_entry *state_table) { static const struct { @@ -6056,6 +5453,7 @@ static void validate_state_table(struct StateEntry *state_table) {149, 150}, {169, 169}, {177, 177}, + {193, 193}, {196, 197}, { 0, 0}, }; @@ -6084,13 +5482,14 @@ static void validate_state_table(struct StateEntry *state_table) STATE_VIEWPORT, STATE_LIGHT_TYPE, STATE_SCISSORRECT, - STATE_FRONTFACE, + STATE_RASTERIZER, STATE_POINTSPRITECOORDORIGIN, STATE_BASEVERTEXINDEX, STATE_FRAMEBUFFER, STATE_POINT_ENABLE, STATE_COLOR_KEY, STATE_BLEND, + STATE_BLEND_FACTOR, }; unsigned int i, current; @@ -6139,39 +5538,43 @@ static void validate_state_table(struct StateEntry *state_table) } } -HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs, - const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, - const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment, - const struct StateEntryTemplate *misc) +HRESULT compile_state_table(struct wined3d_state_entry *state_table, APPLYSTATEFUNC **dev_multistate_funcs, + const struct wined3d_d3d_info *d3d_info, const BOOL *supported_extensions, + const struct wined3d_vertex_pipe_ops *vertex, const struct wined3d_fragment_pipe_ops *fragment, + const struct wined3d_state_entry_template *misc) { - unsigned int i, type, handlers; APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3]; - const struct StateEntryTemplate *cur; + const struct wined3d_state_entry_template *cur; + unsigned int i, type, handlers; BOOL set[STATE_HIGHEST + 1]; memset(multistate_funcs, 0, sizeof(multistate_funcs)); - for(i = 0; i < STATE_HIGHEST + 1; i++) { - StateTable[i].representative = 0; - StateTable[i].apply = state_undefined; + for (i = 0; i < STATE_HIGHEST + 1; ++i) + { + state_table[i].representative = 0; + state_table[i].apply = state_undefined; } - for(type = 0; type < 3; type++) { + for (type = 0; type < 3; ++type) + { /* This switch decides the order in which the states are applied */ - switch(type) { + switch (type) + { case 0: cur = misc; break; case 1: cur = fragment->states; break; case 2: cur = vertex->vp_states; break; default: cur = NULL; /* Stupid compiler */ } - if(!cur) continue; + if (!cur) continue; /* GL extension filtering should not prevent multiple handlers being applied from different * pipeline parts */ memset(set, 0, sizeof(set)); - for(i = 0; cur[i].state; i++) { + for (i = 0; cur[i].state; ++i) + { APPLYSTATEFUNC *funcs_array; /* Only use the first matching state with the available extension from one template. @@ -6181,9 +5584,9 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ * * if GL_XYZ_fancy is supported, ignore the 2nd line */ - if(set[cur[i].state]) continue; + if (set[cur[i].state]) continue; /* Skip state lines depending on unsupported extensions */ - if (!gl_info->supported[cur[i].extension]) continue; + if (!supported_extensions[cur[i].extension]) continue; set[cur[i].state] = TRUE; /* In some cases having an extension means that nothing has to be * done for a state, e.g. if GL_ARB_texture_non_power_of_two is @@ -6196,12 +5599,13 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ handlers = num_handlers(multistate_funcs[cur[i].state]); multistate_funcs[cur[i].state][handlers] = cur[i].content.apply; - switch(handlers) { + switch (handlers) + { case 0: - StateTable[cur[i].state].apply = cur[i].content.apply; + state_table[cur[i].state].apply = cur[i].content.apply; break; case 1: - StateTable[cur[i].state].apply = multistate_apply_2; + state_table[cur[i].state].apply = multistate_apply_2; if (!(dev_multistate_funcs[cur[i].state] = heap_calloc(2, sizeof(**dev_multistate_funcs)))) goto out_of_mem; @@ -6209,7 +5613,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1]; break; case 2: - StateTable[cur[i].state].apply = multistate_apply_3; + state_table[cur[i].state].apply = multistate_apply_3; if (!(funcs_array = heap_realloc(dev_multistate_funcs[cur[i].state], sizeof(**dev_multistate_funcs) * 3))) goto out_of_mem; @@ -6218,22 +5622,22 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2]; break; default: - ERR("Unexpected amount of state handlers for state %u: %u\n", - cur[i].state, handlers + 1); + ERR("Unexpected amount of state handlers for state %u: %u.\n", + cur[i].state, handlers + 1); } - if (StateTable[cur[i].state].representative - && StateTable[cur[i].state].representative != cur[i].content.representative) + if (state_table[cur[i].state].representative + && state_table[cur[i].state].representative != cur[i].content.representative) { FIXME("State %s (%#x) has different representatives in different pipeline parts.\n", debug_d3dstate(cur[i].state), cur[i].state); } - StateTable[cur[i].state].representative = cur[i].content.representative; + state_table[cur[i].state].representative = cur[i].content.representative; } } - prune_invalid_states(StateTable, gl_info, d3d_info); - validate_state_table(StateTable); + prune_invalid_states(state_table, d3d_info); + validate_state_table(state_table); return WINED3D_OK; @@ -6243,7 +5647,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ heap_free(dev_multistate_funcs[i]); } - memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs)); + memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1) * sizeof(*dev_multistate_funcs)); return E_OUTOFMEMORY; -} +} \ No newline at end of file diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c index c9b3527d891..e6383550e21 100644 --- a/dll/directx/wine/wined3d/stateblock.c +++ b/dll/directx/wine/wined3d/stateblock.c @@ -35,7 +35,6 @@ static const DWORD pixel_states_render[] = WINED3D_RS_ALPHAREF, WINED3D_RS_ALPHATESTENABLE, WINED3D_RS_ANTIALIASEDLINEENABLE, - WINED3D_RS_BLENDFACTOR, WINED3D_RS_BLENDOP, WINED3D_RS_BLENDOPALPHA, WINED3D_RS_BACK_STENCILFAIL, @@ -94,7 +93,6 @@ static const DWORD pixel_states_render[] = WINED3D_RS_ZENABLE, WINED3D_RS_ZFUNC, WINED3D_RS_ZWRITEENABLE, - WINED3D_RS_DEPTHCLIP, }; static const DWORD pixel_states_texture[] = @@ -214,16 +212,17 @@ static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, states->pixelShader = 1; states->vertexShader = 1; states->scissorRect = 1; + states->blend_state = 1; /* Fixed size arrays */ states->streamSource = 0xffff; states->streamFreq = 0xffff; states->textures = 0xfffff; - stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1); + stateblock_set_bits(states->transform, WINED3D_HIGHEST_TRANSFORM_STATE + 1); stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1); - for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff; - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3ffe; - states->clipplane = (1u << MAX_CLIP_DISTANCES) - 1; + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff; + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3ffe; + states->clipplane = (1u << WINED3D_MAX_CLIP_DISTANCES) - 1; states->pixelShaderConstantsB = 0xffff; states->pixelShaderConstantsI = 0xffff; states->vertexShaderConstantsB = 0xffff; @@ -241,6 +240,7 @@ static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states unsigned int i; states->pixelShader = 1; + states->blend_state = 1; for (i = 0; i < ARRAY_SIZE(pixel_states_render); ++i) { @@ -250,10 +250,10 @@ static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states for (i = 0; i < ARRAY_SIZE(pixel_states_texture); ++i) texture_mask |= 1u << pixel_states_texture[i]; - for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask; + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) states->textureState[i] = texture_mask; for (i = 0; i < ARRAY_SIZE(pixel_states_sampler); ++i) sampler_mask |= 1u << pixel_states_sampler[i]; - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask; + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask; states->pixelShaderConstantsB = 0xffff; states->pixelShaderConstantsI = 0xffff; @@ -277,10 +277,10 @@ static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *state for (i = 0; i < ARRAY_SIZE(vertex_states_texture); ++i) texture_mask |= 1u << vertex_states_texture[i]; - for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask; + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) states->textureState[i] = texture_mask; for (i = 0; i < ARRAY_SIZE(vertex_states_sampler); ++i) sampler_mask |= 1u << vertex_states_sampler[i]; - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask; + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask; states->vertexShaderConstantsB = 0xffff; states->vertexShaderConstantsI = 0xffff; @@ -304,7 +304,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } - for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i) + for (i = 0; i <= WINED3D_HIGHEST_TRANSFORM_STATE >> 5; ++i) { DWORD map = stateblock->changed.transform[i]; for (j = 0; map; map >>= 1, ++j) @@ -316,7 +316,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } - for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i) + for (i = 0; i < d3d_info->limits.vs_uniform_count_swvp; ++i) { if (stateblock->changed.vs_consts_f[i]) { @@ -370,7 +370,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { DWORD map = stateblock->changed.textureState[i]; @@ -384,7 +384,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { DWORD map = stateblock->changed.samplerState[i]; @@ -399,7 +399,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } -static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct list *light_map) +static void stateblock_init_lights(struct list *dst_map, struct list *src_map) { unsigned int i; @@ -407,12 +407,12 @@ static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct { const struct wined3d_light_info *src_light; - LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry) + LIST_FOR_EACH_ENTRY(src_light, &src_map[i], struct wined3d_light_info, entry) { struct wined3d_light_info *dst_light = heap_alloc(sizeof(*dst_light)); *dst_light = *src_light; - list_add_tail(&stateblock->state.light_map[i], &dst_light->entry); + list_add_tail(&dst_map[i], &dst_light->entry); } } } @@ -443,7 +443,7 @@ void state_unbind_resources(struct wined3d_state *state) wined3d_vertex_declaration_decref(decl); } - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { if ((texture = state->textures[i])) { @@ -461,7 +461,7 @@ void state_unbind_resources(struct wined3d_state *state) } } - for (i = 0; i < MAX_STREAMS; ++i) + for (i = 0; i < WINED3D_MAX_STREAMS; ++i) { if ((buffer = state->streams[i].buffer)) { @@ -525,6 +525,67 @@ void state_unbind_resources(struct wined3d_state *state) } } +void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) +{ + struct wined3d_light_info *light, *cursor; + struct wined3d_vertex_declaration *decl; + struct wined3d_texture *texture; + struct wined3d_buffer *buffer; + struct wined3d_shader *shader; + unsigned int i; + + if ((decl = state->vertex_declaration)) + { + state->vertex_declaration = NULL; + wined3d_vertex_declaration_decref(decl); + } + + for (i = 0; i < WINED3D_MAX_STREAMS; ++i) + { + if ((buffer = state->streams[i].buffer)) + { + state->streams[i].buffer = NULL; + wined3d_buffer_decref(buffer); + } + } + + if ((buffer = state->index_buffer)) + { + state->index_buffer = NULL; + wined3d_buffer_decref(buffer); + } + + if ((shader = state->vs)) + { + state->vs = NULL; + wined3d_shader_decref(shader); + } + + if ((shader = state->ps)) + { + state->ps = NULL; + wined3d_shader_decref(shader); + } + + for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) + { + if ((texture = state->textures[i])) + { + state->textures[i] = NULL; + wined3d_texture_decref(texture); + } + } + + for (i = 0; i < LIGHTMAP_SIZE; ++i) + { + LIST_FOR_EACH_ENTRY_SAFE(light, cursor, &state->light_state.light_map[i], struct wined3d_light_info, entry) + { + list_remove(&light->entry); + heap_free(light); + } + } +} + void state_cleanup(struct wined3d_state *state) { unsigned int counter; @@ -532,15 +593,15 @@ void state_cleanup(struct wined3d_state *state) if (!(state->flags & WINED3D_STATE_NO_REF)) state_unbind_resources(state); - for (counter = 0; counter < MAX_ACTIVE_LIGHTS; ++counter) + for (counter = 0; counter < WINED3D_MAX_ACTIVE_LIGHTS; ++counter) { - state->lights[counter] = NULL; + state->light_state.lights[counter] = NULL; } for (counter = 0; counter < LIGHTMAP_SIZE; ++counter) { struct list *e1, *e2; - LIST_FOR_EACH_SAFE(e1, e2, &state->light_map[counter]) + LIST_FOR_EACH_SAFE(e1, e2, &state->light_state.light_map[counter]) { struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry); list_remove(&light->entry); @@ -557,14 +618,14 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) if (!refcount) { - state_cleanup(&stateblock->state); + wined3d_stateblock_state_cleanup(&stateblock->stateblock_state); heap_free(stateblock); } return refcount; } -struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *state, unsigned int idx) +struct wined3d_light_info *wined3d_light_state_get_light(const struct wined3d_light_state *state, unsigned int idx) { struct wined3d_light_info *light_info; unsigned int hash_idx; @@ -579,7 +640,34 @@ struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *s return NULL; } -void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, +HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, DWORD light_idx, + const struct wined3d_light *params, struct wined3d_light_info **light_info) +{ + struct wined3d_light_info *object; + unsigned int hash_idx; + + if (!(object = wined3d_light_state_get_light(state, light_idx))) + { + TRACE("Adding new light.\n"); + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate light info.\n"); + return E_OUTOFMEMORY; + } + + hash_idx = LIGHTMAP_HASHFUNC(light_idx); + list_add_head(&state->light_map[hash_idx], &object->entry); + object->glIndex = -1; + object->OriginalIndex = light_idx; + } + + object->OriginalParms = *params; + + *light_info = object; + return WINED3D_OK; +} + +void wined3d_light_state_enable_light(struct wined3d_light_state *state, const struct wined3d_d3d_info *d3d_info, struct wined3d_light_info *light_info, BOOL enable) { unsigned int light_count, i; @@ -624,8 +712,11 @@ void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3 WARN("Too many concurrently active lights.\n"); } -static void wined3d_state_record_lights(struct wined3d_state *dst_state, const struct wined3d_state *src_state) +static void wined3d_state_record_lights(struct wined3d_light_state *dst_state, + const struct wined3d_light_state *src_state) { + const struct wined3d_light_info *src; + struct wined3d_light_info *dst; UINT i; /* Lights... For a recorded state block, we just had a chain of actions @@ -633,48 +724,36 @@ static void wined3d_state_record_lights(struct wined3d_state *dst_state, const s * differ. */ for (i = 0; i < LIGHTMAP_SIZE; ++i) { - struct list *e, *f; - LIST_FOR_EACH(e, &dst_state->light_map[i]) + LIST_FOR_EACH_ENTRY(dst, &dst_state->light_map[i], struct wined3d_light_info, entry) { - BOOL updated = FALSE; - struct wined3d_light_info *src = LIST_ENTRY(e, struct wined3d_light_info, entry), *realLight; - - /* Look up the light in the destination */ - LIST_FOR_EACH(f, &src_state->light_map[i]) + if ((src = wined3d_light_state_get_light(src_state, dst->OriginalIndex))) { - realLight = LIST_ENTRY(f, struct wined3d_light_info, entry); - if (realLight->OriginalIndex == src->OriginalIndex) + dst->OriginalParms = src->OriginalParms; + + if (src->glIndex == -1 && dst->glIndex != -1) + { + /* Light disabled. */ + dst_state->lights[dst->glIndex] = NULL; + } + else if (src->glIndex != -1 && dst->glIndex == -1) { - src->OriginalParms = realLight->OriginalParms; - - if (realLight->glIndex == -1 && src->glIndex != -1) - { - /* Light disabled */ - dst_state->lights[src->glIndex] = NULL; - } - else if (realLight->glIndex != -1 && src->glIndex == -1) - { - /* Light enabled */ - dst_state->lights[realLight->glIndex] = src; - } - src->glIndex = realLight->glIndex; - updated = TRUE; - break; + /* Light enabled. */ + dst_state->lights[src->glIndex] = dst; } + dst->glIndex = src->glIndex; } - - if (!updated) + else { /* This can happen if the light was originally created as a * default light for SetLightEnable() while recording. */ WARN("Light %u in dst_state %p does not exist in src_state %p.\n", - src->OriginalIndex, dst_state, src_state); + dst->OriginalIndex, dst_state, src_state); - src->OriginalParms = WINED3D_default_light; - if (src->glIndex != -1) + dst->OriginalParms = WINED3D_default_light; + if (dst->glIndex != -1) { - dst_state->lights[src->glIndex] = NULL; - src->glIndex = -1; + dst_state->lights[dst->glIndex] = NULL; + dst->glIndex = -1; } } } @@ -683,26 +762,21 @@ static void wined3d_state_record_lights(struct wined3d_state *dst_state, const s void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { - const struct wined3d_state *src_state = &stateblock->device->state; + const struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state; unsigned int i; DWORD map; TRACE("stateblock %p.\n", stateblock); - TRACE("Capturing state %p.\n", src_state); - - if (stateblock->changed.vertexShader && stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] - != src_state->shader[WINED3D_SHADER_TYPE_VERTEX]) + if (stateblock->changed.vertexShader && stateblock->stateblock_state.vs != state->vs) { - TRACE("Updating vertex shader from %p to %p\n", - stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX], - src_state->shader[WINED3D_SHADER_TYPE_VERTEX]); + TRACE("Updating vertex shader from %p to %p.\n", stateblock->stateblock_state.vs, state->vs); - if (src_state->shader[WINED3D_SHADER_TYPE_VERTEX]) - wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_VERTEX]); - if (stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]) - wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]); - stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] = src_state->shader[WINED3D_SHADER_TYPE_VERTEX]; + if (state->vs) + wined3d_shader_incref(state->vs); + if (stateblock->stateblock_state.vs) + wined3d_shader_decref(stateblock->stateblock_state.vs); + stateblock->stateblock_state.vs = state->vs; } /* Vertex shader float constants. */ @@ -710,9 +784,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_vs_consts_f[i]; - TRACE("Setting vs_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->vs_consts_f[idx])); + TRACE("Setting vs_consts_f[%u] to %s.\n", idx, debug_vec4(&state->vs_consts_f[idx])); - stateblock->state.vs_consts_f[idx] = src_state->vs_consts_f[idx]; + stateblock->stateblock_state.vs_consts_f[idx] = state->vs_consts_f[idx]; } /* Vertex shader integer constants. */ @@ -720,9 +794,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_vs_consts_i[i]; - TRACE("Setting vs_consts[%u] to %s.\n", idx, debug_ivec4(&src_state->vs_consts_i[idx])); + TRACE("Setting vs_consts_i[%u] to %s.\n", idx, debug_ivec4(&state->vs_consts_i[idx])); - stateblock->state.vs_consts_i[idx] = src_state->vs_consts_i[idx]; + stateblock->stateblock_state.vs_consts_i[idx] = state->vs_consts_i[idx]; } /* Vertex shader boolean constants. */ @@ -731,9 +805,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) unsigned int idx = stateblock->contained_vs_consts_b[i]; TRACE("Setting vs_consts_b[%u] to %s.\n", - idx, src_state->vs_consts_b[idx] ? "TRUE" : "FALSE"); + idx, state->vs_consts_b[idx] ? "TRUE" : "FALSE"); - stateblock->state.vs_consts_b[idx] = src_state->vs_consts_b[idx]; + stateblock->stateblock_state.vs_consts_b[idx] = state->vs_consts_b[idx]; } /* Pixel shader float constants. */ @@ -741,9 +815,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_ps_consts_f[i]; - TRACE("Setting ps_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->ps_consts_f[idx])); + TRACE("Setting ps_consts_f[%u] to %s.\n", idx, debug_vec4(&state->ps_consts_f[idx])); - stateblock->state.ps_consts_f[idx] = src_state->ps_consts_f[idx]; + stateblock->stateblock_state.ps_consts_f[idx] = state->ps_consts_f[idx]; } /* Pixel shader integer constants. */ @@ -751,19 +825,20 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_ps_consts_i[i]; - TRACE("Setting ps_consts_i[%u] to %s.\n", idx, debug_ivec4(&src_state->ps_consts_i[idx])); + TRACE("Setting ps_consts_i[%u] to %s.\n", idx, debug_ivec4(&state->ps_consts_i[idx])); - stateblock->state.ps_consts_i[idx] = src_state->ps_consts_i[idx]; + stateblock->stateblock_state.ps_consts_i[idx] = state->ps_consts_i[idx]; } /* Pixel shader boolean constants. */ for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i) { unsigned int idx = stateblock->contained_ps_consts_b[i]; + TRACE("Setting ps_consts_b[%u] to %s.\n", - idx, src_state->ps_consts_b[idx] ? "TRUE" : "FALSE"); + idx, state->ps_consts_b[idx] ? "TRUE" : "FALSE"); - stateblock->state.ps_consts_b[idx] = src_state->ps_consts_b[idx]; + stateblock->stateblock_state.ps_consts_b[idx] = state->ps_consts_b[idx]; } /* Others + Render & Texture */ @@ -773,62 +848,70 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) TRACE("Updating transform %#x.\n", transform); - stateblock->state.transforms[transform] = src_state->transforms[transform]; + stateblock->stateblock_state.transforms[transform] = state->transforms[transform]; } if (stateblock->changed.indices - && ((stateblock->state.index_buffer != src_state->index_buffer) - || (stateblock->state.base_vertex_index != src_state->base_vertex_index) - || (stateblock->state.index_format != src_state->index_format) - || (stateblock->state.index_offset != src_state->index_offset))) + && ((stateblock->stateblock_state.index_buffer != state->index_buffer) + || (stateblock->stateblock_state.base_vertex_index != state->base_vertex_index) + || (stateblock->stateblock_state.index_format != state->index_format))) { TRACE("Updating index buffer to %p, base vertex index to %d.\n", - src_state->index_buffer, src_state->base_vertex_index); + state->index_buffer, state->base_vertex_index); - if (src_state->index_buffer) - wined3d_buffer_incref(src_state->index_buffer); - if (stateblock->state.index_buffer) - wined3d_buffer_decref(stateblock->state.index_buffer); - stateblock->state.index_buffer = src_state->index_buffer; - stateblock->state.base_vertex_index = src_state->base_vertex_index; - stateblock->state.index_format = src_state->index_format; - stateblock->state.index_offset = src_state->index_offset; + if (state->index_buffer) + wined3d_buffer_incref(state->index_buffer); + if (stateblock->stateblock_state.index_buffer) + wined3d_buffer_decref(stateblock->stateblock_state.index_buffer); + stateblock->stateblock_state.index_buffer = state->index_buffer; + stateblock->stateblock_state.base_vertex_index = state->base_vertex_index; + stateblock->stateblock_state.index_format = state->index_format; } - if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration != src_state->vertex_declaration) + if (stateblock->changed.vertexDecl && stateblock->stateblock_state.vertex_declaration != state->vertex_declaration) { TRACE("Updating vertex declaration from %p to %p.\n", - stateblock->state.vertex_declaration, src_state->vertex_declaration); + stateblock->stateblock_state.vertex_declaration, state->vertex_declaration); - if (src_state->vertex_declaration) - wined3d_vertex_declaration_incref(src_state->vertex_declaration); - if (stateblock->state.vertex_declaration) - wined3d_vertex_declaration_decref(stateblock->state.vertex_declaration); - stateblock->state.vertex_declaration = src_state->vertex_declaration; + if (state->vertex_declaration) + wined3d_vertex_declaration_incref(state->vertex_declaration); + if (stateblock->stateblock_state.vertex_declaration) + wined3d_vertex_declaration_decref(stateblock->stateblock_state.vertex_declaration); + stateblock->stateblock_state.vertex_declaration = state->vertex_declaration; } if (stateblock->changed.material - && memcmp(&src_state->material, &stateblock->state.material, sizeof(stateblock->state.material))) + && memcmp(&state->material, &stateblock->stateblock_state.material, + sizeof(stateblock->stateblock_state.material))) { TRACE("Updating material.\n"); - stateblock->state.material = src_state->material; + stateblock->stateblock_state.material = state->material; } if (stateblock->changed.viewport - && memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport))) + && memcmp(&state->viewport, &stateblock->stateblock_state.viewport, sizeof(state->viewport))) { TRACE("Updating viewport.\n"); - stateblock->state.viewport = src_state->viewport; + stateblock->stateblock_state.viewport = state->viewport; } - if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect, - &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect))) + if (stateblock->changed.scissorRect + && memcmp(&state->scissor_rect, &stateblock->stateblock_state.scissor_rect, sizeof(state->scissor_rect))) { TRACE("Updating scissor rect.\n"); - stateblock->state.scissor_rect = src_state->scissor_rect; + stateblock->stateblock_state.scissor_rect = state->scissor_rect; + } + + if (stateblock->changed.blend_state + && memcmp(&state->blend_factor, &stateblock->stateblock_state.blend_factor, + sizeof(stateblock->stateblock_state.blend_factor))) + { + TRACE("Updating blend factor.\n"); + + stateblock->stateblock_state.blend_factor = state->blend_factor; } map = stateblock->changed.streamSource; @@ -836,19 +919,23 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { if (!(map & 1)) continue; - if (stateblock->state.streams[i].stride != src_state->streams[i].stride - || stateblock->state.streams[i].buffer != src_state->streams[i].buffer) + if (stateblock->stateblock_state.streams[i].stride != state->streams[i].stride + || stateblock->stateblock_state.streams[i].offset != state->streams[i].offset + || stateblock->stateblock_state.streams[i].buffer != state->streams[i].buffer) { - TRACE("Updating stream source %u to %p, stride to %u.\n", - i, src_state->streams[i].buffer, - src_state->streams[i].stride); - - stateblock->state.streams[i].stride = src_state->streams[i].stride; - if (src_state->streams[i].buffer) - wined3d_buffer_incref(src_state->streams[i].buffer); - if (stateblock->state.streams[i].buffer) - wined3d_buffer_decref(stateblock->state.streams[i].buffer); - stateblock->state.streams[i].buffer = src_state->streams[i].buffer; + TRACE("stateblock %p, stream source %u, buffer %p, stride %u, offset %u.\n", + stateblock, i, state->streams[i].buffer, state->streams[i].stride, + state->streams[i].offset); + + stateblock->stateblock_state.streams[i].stride = state->streams[i].stride; + if (stateblock->changed.store_stream_offset) + stateblock->stateblock_state.streams[i].offset = state->streams[i].offset; + + if (state->streams[i].buffer) + wined3d_buffer_incref(state->streams[i].buffer); + if (stateblock->stateblock_state.streams[i].buffer) + wined3d_buffer_decref(stateblock->stateblock_state.streams[i].buffer); + stateblock->stateblock_state.streams[i].buffer = state->streams[i].buffer; } } @@ -857,14 +944,14 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { if (!(map & 1)) continue; - if (stateblock->state.streams[i].frequency != src_state->streams[i].frequency - || stateblock->state.streams[i].flags != src_state->streams[i].flags) + if (stateblock->stateblock_state.streams[i].frequency != state->streams[i].frequency + || stateblock->stateblock_state.streams[i].flags != state->streams[i].flags) { TRACE("Updating stream frequency %u to %u flags to %#x.\n", - i, src_state->streams[i].frequency, src_state->streams[i].flags); + i, state->streams[i].frequency, state->streams[i].flags); - stateblock->state.streams[i].frequency = src_state->streams[i].frequency; - stateblock->state.streams[i].flags = src_state->streams[i].flags; + stateblock->stateblock_state.streams[i].frequency = state->streams[i].frequency; + stateblock->stateblock_state.streams[i].flags = state->streams[i].flags; } } @@ -873,10 +960,10 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { if (!(map & 1)) continue; - if (memcmp(&stateblock->state.clip_planes[i], &src_state->clip_planes[i], sizeof(src_state->clip_planes[i]))) + if (memcmp(&stateblock->stateblock_state.clip_planes[i], &state->clip_planes[i], sizeof(state->clip_planes[i]))) { TRACE("Updating clipplane %u.\n", i); - stateblock->state.clip_planes[i] = src_state->clip_planes[i]; + stateblock->stateblock_state.clip_planes[i] = state->clip_planes[i]; } } @@ -885,21 +972,22 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { enum wined3d_render_state rs = stateblock->contained_render_states[i]; - TRACE("Updating render state %#x to %u.\n", rs, src_state->render_states[rs]); + TRACE("Updating render state %#x to %u.\n", rs, state->rs[rs]); - stateblock->state.render_states[rs] = src_state->render_states[rs]; + stateblock->stateblock_state.rs[rs] = state->rs[rs]; } /* Texture states */ for (i = 0; i < stateblock->num_contained_tss_states; ++i) { DWORD stage = stateblock->contained_tss_states[i].stage; - DWORD state = stateblock->contained_tss_states[i].state; + DWORD texture_state = stateblock->contained_tss_states[i].state; - TRACE("Updating texturestage state %u, %u to %#x (was %#x).\n", stage, state, - src_state->texture_states[stage][state], stateblock->state.texture_states[stage][state]); + TRACE("Updating texturestage state %u, %u to %#x (was %#x).\n", stage, texture_state, + state->texture_states[stage][texture_state], + stateblock->stateblock_state.texture_states[stage][texture_state]); - stateblock->state.texture_states[stage][state] = src_state->texture_states[stage][state]; + stateblock->stateblock_state.texture_states[stage][texture_state] = state->texture_states[stage][texture_state]; } /* Samplers */ @@ -909,61 +997,44 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) if (!(map & 1)) continue; TRACE("Updating texture %u to %p (was %p).\n", - i, src_state->textures[i], stateblock->state.textures[i]); + i, state->textures[i], stateblock->stateblock_state.textures[i]); - if (src_state->textures[i]) - wined3d_texture_incref(src_state->textures[i]); - if (stateblock->state.textures[i]) - wined3d_texture_decref(stateblock->state.textures[i]); - stateblock->state.textures[i] = src_state->textures[i]; + if (state->textures[i]) + wined3d_texture_incref(state->textures[i]); + if (stateblock->stateblock_state.textures[i]) + wined3d_texture_decref(stateblock->stateblock_state.textures[i]); + stateblock->stateblock_state.textures[i] = state->textures[i]; } for (i = 0; i < stateblock->num_contained_sampler_states; ++i) { DWORD stage = stateblock->contained_sampler_states[i].stage; - DWORD state = stateblock->contained_sampler_states[i].state; + DWORD sampler_state = stateblock->contained_sampler_states[i].state; - TRACE("Updating sampler state %u, %u to %#x (was %#x).\n", stage, state, - src_state->sampler_states[stage][state], stateblock->state.sampler_states[stage][state]); + TRACE("Updating sampler state %u, %u to %#x (was %#x).\n", stage, sampler_state, + state->sampler_states[stage][sampler_state], + stateblock->stateblock_state.sampler_states[stage][sampler_state]); - stateblock->state.sampler_states[stage][state] = src_state->sampler_states[stage][state]; + stateblock->stateblock_state.sampler_states[stage][sampler_state] = state->sampler_states[stage][sampler_state]; } - if (stateblock->changed.pixelShader && stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] - != src_state->shader[WINED3D_SHADER_TYPE_PIXEL]) + if (stateblock->changed.pixelShader && stateblock->stateblock_state.ps != state->ps) { - if (src_state->shader[WINED3D_SHADER_TYPE_PIXEL]) - wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_PIXEL]); - if (stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]) - wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]); - stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] = src_state->shader[WINED3D_SHADER_TYPE_PIXEL]; + if (state->ps) + wined3d_shader_incref(state->ps); + if (stateblock->stateblock_state.ps) + wined3d_shader_decref(stateblock->stateblock_state.ps); + stateblock->stateblock_state.ps = state->ps; } - wined3d_state_record_lights(&stateblock->state, src_state); + wined3d_state_record_lights(&stateblock->stateblock_state.light_state, &state->light_state); TRACE("Capture done.\n"); } -static void apply_lights(struct wined3d_device *device, const struct wined3d_state *state) -{ - UINT i; - - for (i = 0; i < LIGHTMAP_SIZE; ++i) - { - struct list *e; - - LIST_FOR_EACH(e, &state->light_map[i]) - { - const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry); - - wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms); - wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1); - } - } -} - void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) { + struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state; struct wined3d_device *device = stateblock->device; unsigned int i; DWORD map; @@ -971,115 +1042,212 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) TRACE("Applying stateblock %p to device %p.\n", stateblock, device); if (stateblock->changed.vertexShader) - wined3d_device_set_vertex_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]); + { + if (stateblock->stateblock_state.vs) + wined3d_shader_incref(stateblock->stateblock_state.vs); + if (state->vs) + wined3d_shader_decref(state->vs); + state->vs = stateblock->stateblock_state.vs; + wined3d_device_set_vertex_shader(device, stateblock->stateblock_state.vs); + } /* Vertex Shader Constants. */ for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i) { - wined3d_device_set_vs_consts_f(device, stateblock->contained_vs_consts_f[i], - 1, &stateblock->state.vs_consts_f[stateblock->contained_vs_consts_f[i]]); + unsigned int idx = stateblock->contained_vs_consts_f[i]; + + state->vs_consts_f[idx] = stateblock->stateblock_state.vs_consts_f[idx]; + wined3d_device_set_vs_consts_f(device, idx, 1, &stateblock->stateblock_state.vs_consts_f[idx]); } for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i) { - wined3d_device_set_vs_consts_i(device, stateblock->contained_vs_consts_i[i], - 1, &stateblock->state.vs_consts_i[stateblock->contained_vs_consts_i[i]]); + unsigned int idx = stateblock->contained_vs_consts_i[i]; + + state->vs_consts_i[idx] = stateblock->stateblock_state.vs_consts_i[idx]; + wined3d_device_set_vs_consts_i(device, idx, 1, &stateblock->stateblock_state.vs_consts_i[idx]); } for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i) { - wined3d_device_set_vs_consts_b(device, stateblock->contained_vs_consts_b[i], - 1, &stateblock->state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); + unsigned int idx = stateblock->contained_vs_consts_b[i]; + + state->vs_consts_b[idx] = stateblock->stateblock_state.vs_consts_b[idx]; + wined3d_device_set_vs_consts_b(device, idx, 1, &stateblock->stateblock_state.vs_consts_b[idx]); } - apply_lights(device, &stateblock->state); + for (i = 0; i < ARRAY_SIZE(stateblock->stateblock_state.light_state.light_map); ++i) + { + const struct wined3d_light_info *light; + struct wined3d_light_info *new_light; + + LIST_FOR_EACH_ENTRY(light, &stateblock->stateblock_state.light_state.light_map[i], struct wined3d_light_info, entry) + { + if (SUCCEEDED(wined3d_light_state_set_light(&state->light_state, light->OriginalIndex, + &light->OriginalParms, &new_light))) + { + wined3d_light_state_enable_light(&state->light_state, &device->adapter->d3d_info, new_light, light->glIndex != -1); + } + wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms); + wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1); + } + } if (stateblock->changed.pixelShader) - wined3d_device_set_pixel_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]); + { + if (stateblock->stateblock_state.ps) + wined3d_shader_incref(stateblock->stateblock_state.ps); + if (state->ps) + wined3d_shader_decref(state->ps); + state->ps = stateblock->stateblock_state.ps; + wined3d_device_set_pixel_shader(device, stateblock->stateblock_state.ps); + } /* Pixel Shader Constants. */ for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i) { - wined3d_device_set_ps_consts_f(device, stateblock->contained_ps_consts_f[i], - 1, &stateblock->state.ps_consts_f[stateblock->contained_ps_consts_f[i]]); + unsigned int idx = stateblock->contained_ps_consts_f[i]; + + state->ps_consts_f[idx] = stateblock->stateblock_state.ps_consts_f[idx]; + wined3d_device_set_ps_consts_f(device, idx, 1, &stateblock->stateblock_state.ps_consts_f[idx]); } for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i) { - wined3d_device_set_ps_consts_i(device, stateblock->contained_ps_consts_i[i], - 1, &stateblock->state.ps_consts_i[stateblock->contained_ps_consts_i[i]]); + unsigned int idx = stateblock->contained_ps_consts_i[i]; + + state->ps_consts_i[idx] = stateblock->stateblock_state.ps_consts_i[idx]; + wined3d_device_set_ps_consts_i(device, idx, 1, &stateblock->stateblock_state.ps_consts_i[idx]); } for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i) { - wined3d_device_set_ps_consts_b(device, stateblock->contained_ps_consts_b[i], - 1, &stateblock->state.ps_consts_b[stateblock->contained_ps_consts_b[i]]); + unsigned int idx = stateblock->contained_ps_consts_b[i]; + + state->ps_consts_b[idx] = stateblock->stateblock_state.ps_consts_b[idx]; + wined3d_device_set_ps_consts_b(device, idx, 1, &stateblock->stateblock_state.ps_consts_b[idx]); } /* Render states. */ for (i = 0; i < stateblock->num_contained_render_states; ++i) { - wined3d_device_set_render_state(device, stateblock->contained_render_states[i], - stateblock->state.render_states[stateblock->contained_render_states[i]]); + enum wined3d_render_state rs = stateblock->contained_render_states[i]; + + state->rs[rs] = stateblock->stateblock_state.rs[rs]; + wined3d_device_set_render_state(device, rs, stateblock->stateblock_state.rs[rs]); } /* Texture states. */ for (i = 0; i < stateblock->num_contained_tss_states; ++i) { DWORD stage = stateblock->contained_tss_states[i].stage; - DWORD state = stateblock->contained_tss_states[i].state; + DWORD texture_state = stateblock->contained_tss_states[i].state; - wined3d_device_set_texture_stage_state(device, stage, state, stateblock->state.texture_states[stage][state]); + state->texture_states[stage][texture_state] = stateblock->stateblock_state.texture_states[stage][texture_state]; + wined3d_device_set_texture_stage_state(device, stage, texture_state, + stateblock->stateblock_state.texture_states[stage][texture_state]); } /* Sampler states. */ for (i = 0; i < stateblock->num_contained_sampler_states; ++i) { DWORD stage = stateblock->contained_sampler_states[i].stage; - DWORD state = stateblock->contained_sampler_states[i].state; - DWORD value = stateblock->state.sampler_states[stage][state]; + DWORD sampler_state = stateblock->contained_sampler_states[i].state; + DWORD value = stateblock->stateblock_state.sampler_states[stage][sampler_state]; - if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS; - wined3d_device_set_sampler_state(device, stage, state, value); + state->sampler_states[stage][sampler_state] = value; + if (stage >= WINED3D_MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - WINED3D_MAX_FRAGMENT_SAMPLERS; + wined3d_device_set_sampler_state(device, stage, sampler_state, value); } /* Transform states. */ for (i = 0; i < stateblock->num_contained_transform_states; ++i) { - wined3d_device_set_transform(device, stateblock->contained_transform_states[i], - &stateblock->state.transforms[stateblock->contained_transform_states[i]]); + enum wined3d_transform_state transform = stateblock->contained_transform_states[i]; + + state->transforms[transform] = stateblock->stateblock_state.transforms[transform]; + wined3d_device_set_transform(device, transform, &stateblock->stateblock_state.transforms[transform]); } if (stateblock->changed.indices) { - wined3d_device_set_index_buffer(device, stateblock->state.index_buffer, - stateblock->state.index_format, stateblock->state.index_offset); - wined3d_device_set_base_vertex_index(device, stateblock->state.base_vertex_index); + if (stateblock->stateblock_state.index_buffer) + wined3d_buffer_incref(stateblock->stateblock_state.index_buffer); + if (state->index_buffer) + wined3d_buffer_decref(state->index_buffer); + state->index_buffer = stateblock->stateblock_state.index_buffer; + state->index_format = stateblock->stateblock_state.index_format; + state->base_vertex_index = stateblock->stateblock_state.base_vertex_index; + + wined3d_device_set_index_buffer(device, stateblock->stateblock_state.index_buffer, + stateblock->stateblock_state.index_format, 0); + wined3d_device_set_base_vertex_index(device, stateblock->stateblock_state.base_vertex_index); } - if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration) - wined3d_device_set_vertex_declaration(device, stateblock->state.vertex_declaration); + if (stateblock->changed.vertexDecl && stateblock->stateblock_state.vertex_declaration) + { + if (stateblock->stateblock_state.vertex_declaration) + wined3d_vertex_declaration_incref(stateblock->stateblock_state.vertex_declaration); + if (state->vertex_declaration) + wined3d_vertex_declaration_decref(state->vertex_declaration); + state->vertex_declaration = stateblock->stateblock_state.vertex_declaration; + wined3d_device_set_vertex_declaration(device, stateblock->stateblock_state.vertex_declaration); + } if (stateblock->changed.material) - wined3d_device_set_material(device, &stateblock->state.material); + { + state->material = stateblock->stateblock_state.material; + wined3d_device_set_material(device, &stateblock->stateblock_state.material); + } if (stateblock->changed.viewport) - wined3d_device_set_viewport(device, &stateblock->state.viewport); + { + state->viewport = stateblock->stateblock_state.viewport; + + wined3d_device_set_viewports(device, 1, &stateblock->stateblock_state.viewport); + } if (stateblock->changed.scissorRect) - wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect); + { + state->scissor_rect = stateblock->stateblock_state.scissor_rect; + + wined3d_device_set_scissor_rects(device, 1, &stateblock->stateblock_state.scissor_rect); + } + + if (stateblock->changed.blend_state) + { + state->blend_factor = stateblock->stateblock_state.blend_factor; + wined3d_device_set_blend_state(device, NULL, &stateblock->stateblock_state.blend_factor); + } map = stateblock->changed.streamSource; for (i = 0; map; map >>= 1, ++i) { - if (map & 1) - wined3d_device_set_stream_source(device, i, - stateblock->state.streams[i].buffer, - 0, stateblock->state.streams[i].stride); + unsigned int offset, stride; + + if (!(map & 1)) continue; + + if (stateblock->stateblock_state.streams[i].buffer) + wined3d_buffer_incref(stateblock->stateblock_state.streams[i].buffer); + if (state->streams[i].buffer) + wined3d_buffer_decref(state->streams[i].buffer); + state->streams[i].buffer = stateblock->stateblock_state.streams[i].buffer; + + offset = stateblock->stateblock_state.streams[i].offset; + stride = stateblock->stateblock_state.streams[i].stride; + + state->streams[i].stride = stride; + state->streams[i].offset = offset; + wined3d_device_set_stream_source(device, i, + stateblock->stateblock_state.streams[i].buffer, offset, stride); } map = stateblock->changed.streamFreq; for (i = 0; map; map >>= 1, ++i) { - if (map & 1) - wined3d_device_set_stream_source_freq(device, i, - stateblock->state.streams[i].frequency | stateblock->state.streams[i].flags); + if (!(map & 1)) continue; + + state->streams[i].frequency = stateblock->stateblock_state.streams[i].frequency; + state->streams[i].flags = stateblock->stateblock_state.streams[i].flags; + + wined3d_device_set_stream_source_freq(device, i, + stateblock->stateblock_state.streams[i].frequency | stateblock->stateblock_state.streams[i].flags); } map = stateblock->changed.textures; @@ -1089,8 +1257,13 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) if (!(map & 1)) continue; - stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS; - wined3d_device_set_texture(device, stage, stateblock->state.textures[i]); + stage = i < WINED3D_MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - WINED3D_MAX_FRAGMENT_SAMPLERS; + if (stateblock->stateblock_state.textures[i]) + wined3d_texture_incref(stateblock->stateblock_state.textures[i]); + if (state->textures[i]) + wined3d_texture_decref(state->textures[i]); + state->textures[i] = stateblock->stateblock_state.textures[i]; + wined3d_device_set_texture(device, stage, stateblock->stateblock_state.textures[i]); } map = stateblock->changed.clipplane; @@ -1098,218 +1271,416 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) { if (!(map & 1)) continue; - wined3d_device_set_clip_plane(device, i, &stateblock->state.clip_planes[i]); + state->clip_planes[i] = stateblock->stateblock_state.clip_planes[i]; + wined3d_device_set_clip_plane(device, i, &stateblock->stateblock_state.clip_planes[i]); } TRACE("Applied stateblock %p.\n", stateblock); } -static void state_init_default(struct wined3d_state *state, const struct wined3d_gl_info *gl_info) +void CDECL wined3d_stateblock_set_vertex_shader(struct wined3d_stateblock *stateblock, struct wined3d_shader *shader) +{ + TRACE("stateblock %p, shader %p.\n", stateblock, shader); + + if (shader) + wined3d_shader_incref(shader); + if (stateblock->stateblock_state.vs) + wined3d_shader_decref(stateblock->stateblock_state.vs); + stateblock->stateblock_state.vs = shader; + stateblock->changed.vertexShader = TRUE; +} + +HRESULT CDECL wined3d_stateblock_set_vs_consts_f(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) +{ + const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info; + unsigned int constants_count; + + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + + constants_count = stateblock->device->create_parms.flags + & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) + ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count; + + if (!constants || start_idx >= constants_count || count > constants_count - start_idx) + return WINED3DERR_INVALIDCALL; + + memcpy(&stateblock->stateblock_state.vs_consts_f[start_idx], constants, count * sizeof(*constants)); + memset(&stateblock->changed.vs_consts_f[start_idx], 1, count * sizeof(*stateblock->changed.vs_consts_f)); + return WINED3D_OK; +} + +HRESULT CDECL wined3d_stateblock_set_vs_consts_i(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants) +{ + unsigned int i; + + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + + if (!constants || start_idx >= WINED3D_MAX_CONSTS_I) + return WINED3DERR_INVALIDCALL; + + if (count > WINED3D_MAX_CONSTS_I - start_idx) + count = WINED3D_MAX_CONSTS_I - start_idx; + + memcpy(&stateblock->stateblock_state.vs_consts_i[start_idx], constants, count * sizeof(*constants)); + for (i = start_idx; i < count + start_idx; ++i) + stateblock->changed.vertexShaderConstantsI |= (1u << i); + return WINED3D_OK; +} + +HRESULT CDECL wined3d_stateblock_set_vs_consts_b(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const BOOL *constants) +{ + unsigned int i; + + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + + if (!constants || start_idx >= WINED3D_MAX_CONSTS_B) + return WINED3DERR_INVALIDCALL; + + if (count > WINED3D_MAX_CONSTS_B - start_idx) + count = WINED3D_MAX_CONSTS_B - start_idx; + + memcpy(&stateblock->stateblock_state.vs_consts_b[start_idx], constants, count * sizeof(*constants)); + for (i = start_idx; i < count + start_idx; ++i) + stateblock->changed.vertexShaderConstantsB |= (1u << i); + return WINED3D_OK; +} + +void CDECL wined3d_stateblock_set_pixel_shader(struct wined3d_stateblock *stateblock, struct wined3d_shader *shader) +{ + TRACE("stateblock %p, shader %p.\n", stateblock, shader); + + if (shader) + wined3d_shader_incref(shader); + if (stateblock->stateblock_state.ps) + wined3d_shader_decref(stateblock->stateblock_state.ps); + stateblock->stateblock_state.ps = shader; + stateblock->changed.pixelShader = TRUE; +} + +HRESULT CDECL wined3d_stateblock_set_ps_consts_f(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) +{ + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + + if (!constants || start_idx >= WINED3D_MAX_PS_CONSTS_F || count > WINED3D_MAX_PS_CONSTS_F - start_idx) + return WINED3DERR_INVALIDCALL; + + memcpy(&stateblock->stateblock_state.ps_consts_f[start_idx], constants, count * sizeof(*constants)); + memset(&stateblock->changed.ps_consts_f[start_idx], 1, count * sizeof(*stateblock->changed.ps_consts_f)); + return WINED3D_OK; +} + +HRESULT CDECL wined3d_stateblock_set_ps_consts_i(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants) +{ + unsigned int i; + + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + + if (!constants || start_idx >= WINED3D_MAX_CONSTS_I) + return WINED3DERR_INVALIDCALL; + + if (count > WINED3D_MAX_CONSTS_I - start_idx) + count = WINED3D_MAX_CONSTS_I - start_idx; + + memcpy(&stateblock->stateblock_state.ps_consts_i[start_idx], constants, count * sizeof(*constants)); + for (i = start_idx; i < count + start_idx; ++i) + stateblock->changed.pixelShaderConstantsI |= (1u << i); + return WINED3D_OK; +} + +HRESULT CDECL wined3d_stateblock_set_ps_consts_b(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const BOOL *constants) +{ + unsigned int i; + + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + + if (!constants || start_idx >= WINED3D_MAX_CONSTS_B) + return WINED3DERR_INVALIDCALL; + + if (count > WINED3D_MAX_CONSTS_B - start_idx) + count = WINED3D_MAX_CONSTS_B - start_idx; + + memcpy(&stateblock->stateblock_state.ps_consts_b[start_idx], constants, count * sizeof(*constants)); + for (i = start_idx; i < count + start_idx; ++i) + stateblock->changed.pixelShaderConstantsB |= (1u << i); + return WINED3D_OK; +} + +void CDECL wined3d_stateblock_set_vertex_declaration(struct wined3d_stateblock *stateblock, + struct wined3d_vertex_declaration *declaration) +{ + TRACE("stateblock %p, declaration %p.\n", stateblock, declaration); + + if (declaration) + wined3d_vertex_declaration_incref(declaration); + if (stateblock->stateblock_state.vertex_declaration) + wined3d_vertex_declaration_decref(stateblock->stateblock_state.vertex_declaration); + stateblock->stateblock_state.vertex_declaration = declaration; + stateblock->changed.vertexDecl = TRUE; +} + +void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateblock, + enum wined3d_render_state state, DWORD value) +{ + TRACE("stateblock %p, state %s (%#x), value %#x.\n", stateblock, debug_d3drenderstate(state), state, value); + + if (state > WINEHIGHEST_RENDER_STATE) + { + WARN("Unhandled render state %#x.\n", state); + return; + } + + stateblock->stateblock_state.rs[state] = value; + stateblock->changed.renderState[state >> 5] |= 1u << (state & 0x1f); +} + +void CDECL wined3d_stateblock_set_blend_factor(struct wined3d_stateblock *stateblock, + const struct wined3d_color *blend_factor) +{ + TRACE("stateblock %p, blend_factor %p.\n", stateblock, blend_factor); + + stateblock->stateblock_state.blend_factor = *blend_factor; + stateblock->changed.blend_state = TRUE; +} + +static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], const struct wined3d_d3d_info *d3d_info) { + unsigned int i; union { struct wined3d_line_pattern lp; DWORD d; } lp; - union { + union + { float f; DWORD d; } tmpfloat; - unsigned int i; - struct wined3d_matrix identity; - - TRACE("state %p, gl_info %p.\n", state, gl_info); - - get_identity_matrix(&identity); - state->gl_primitive_type = ~0u; - state->gl_patch_vertices = 0; - - /* Set some of the defaults for lights, transforms etc */ - state->transforms[WINED3D_TS_PROJECTION] = identity; - state->transforms[WINED3D_TS_VIEW] = identity; - for (i = 0; i < 256; ++i) - { - state->transforms[WINED3D_TS_WORLD_MATRIX(i)] = identity; - } - TRACE("Render states\n"); - /* Render states: */ - state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE; - state->render_states[WINED3D_RS_FILLMODE] = WINED3D_FILL_SOLID; - state->render_states[WINED3D_RS_SHADEMODE] = WINED3D_SHADE_GOURAUD; + rs[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE; + rs[WINED3D_RS_FILLMODE] = WINED3D_FILL_SOLID; + rs[WINED3D_RS_SHADEMODE] = WINED3D_SHADE_GOURAUD; lp.lp.repeat_factor = 0; lp.lp.line_pattern = 0; - state->render_states[WINED3D_RS_LINEPATTERN] = lp.d; - state->render_states[WINED3D_RS_ZWRITEENABLE] = TRUE; - state->render_states[WINED3D_RS_ALPHATESTENABLE] = FALSE; - state->render_states[WINED3D_RS_LASTPIXEL] = TRUE; - state->render_states[WINED3D_RS_SRCBLEND] = WINED3D_BLEND_ONE; - state->render_states[WINED3D_RS_DESTBLEND] = WINED3D_BLEND_ZERO; - state->render_states[WINED3D_RS_CULLMODE] = WINED3D_CULL_BACK; - state->render_states[WINED3D_RS_ZFUNC] = WINED3D_CMP_LESSEQUAL; - state->render_states[WINED3D_RS_ALPHAFUNC] = WINED3D_CMP_ALWAYS; - state->render_states[WINED3D_RS_ALPHAREF] = 0; - state->render_states[WINED3D_RS_DITHERENABLE] = FALSE; - state->render_states[WINED3D_RS_ALPHABLENDENABLE] = FALSE; - state->render_states[WINED3D_RS_FOGENABLE] = FALSE; - state->render_states[WINED3D_RS_SPECULARENABLE] = FALSE; - state->render_states[WINED3D_RS_ZVISIBLE] = 0; - state->render_states[WINED3D_RS_FOGCOLOR] = 0; - state->render_states[WINED3D_RS_FOGTABLEMODE] = WINED3D_FOG_NONE; + rs[WINED3D_RS_LINEPATTERN] = lp.d; + rs[WINED3D_RS_ZWRITEENABLE] = TRUE; + rs[WINED3D_RS_ALPHATESTENABLE] = FALSE; + rs[WINED3D_RS_LASTPIXEL] = TRUE; + rs[WINED3D_RS_SRCBLEND] = WINED3D_BLEND_ONE; + rs[WINED3D_RS_DESTBLEND] = WINED3D_BLEND_ZERO; + rs[WINED3D_RS_CULLMODE] = WINED3D_CULL_BACK; + rs[WINED3D_RS_ZFUNC] = WINED3D_CMP_LESSEQUAL; + rs[WINED3D_RS_ALPHAFUNC] = WINED3D_CMP_ALWAYS; + rs[WINED3D_RS_ALPHAREF] = 0; + rs[WINED3D_RS_DITHERENABLE] = FALSE; + rs[WINED3D_RS_ALPHABLENDENABLE] = FALSE; + rs[WINED3D_RS_FOGENABLE] = FALSE; + rs[WINED3D_RS_SPECULARENABLE] = FALSE; + rs[WINED3D_RS_ZVISIBLE] = 0; + rs[WINED3D_RS_FOGCOLOR] = 0; + rs[WINED3D_RS_FOGTABLEMODE] = WINED3D_FOG_NONE; tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_FOGSTART] = tmpfloat.d; + rs[WINED3D_RS_FOGSTART] = tmpfloat.d; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_FOGEND] = tmpfloat.d; + rs[WINED3D_RS_FOGEND] = tmpfloat.d; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_FOGDENSITY] = tmpfloat.d; - state->render_states[WINED3D_RS_EDGEANTIALIAS] = FALSE; - state->render_states[WINED3D_RS_RANGEFOGENABLE] = FALSE; - state->render_states[WINED3D_RS_STENCILENABLE] = FALSE; - state->render_states[WINED3D_RS_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_STENCILREF] = 0; - state->render_states[WINED3D_RS_STENCILMASK] = 0xffffffff; - state->render_states[WINED3D_RS_STENCILFUNC] = WINED3D_CMP_ALWAYS; - state->render_states[WINED3D_RS_STENCILWRITEMASK] = 0xffffffff; - state->render_states[WINED3D_RS_TEXTUREFACTOR] = 0xffffffff; - state->render_states[WINED3D_RS_WRAP0] = 0; - state->render_states[WINED3D_RS_WRAP1] = 0; - state->render_states[WINED3D_RS_WRAP2] = 0; - state->render_states[WINED3D_RS_WRAP3] = 0; - state->render_states[WINED3D_RS_WRAP4] = 0; - state->render_states[WINED3D_RS_WRAP5] = 0; - state->render_states[WINED3D_RS_WRAP6] = 0; - state->render_states[WINED3D_RS_WRAP7] = 0; - state->render_states[WINED3D_RS_CLIPPING] = TRUE; - state->render_states[WINED3D_RS_LIGHTING] = TRUE; - state->render_states[WINED3D_RS_AMBIENT] = 0; - state->render_states[WINED3D_RS_FOGVERTEXMODE] = WINED3D_FOG_NONE; - state->render_states[WINED3D_RS_COLORVERTEX] = TRUE; - state->render_states[WINED3D_RS_LOCALVIEWER] = TRUE; - state->render_states[WINED3D_RS_NORMALIZENORMALS] = FALSE; - state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] = WINED3D_MCS_COLOR1; - state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] = WINED3D_MCS_COLOR2; - state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] = WINED3D_MCS_MATERIAL; - state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] = WINED3D_MCS_MATERIAL; - state->render_states[WINED3D_RS_VERTEXBLEND] = WINED3D_VBF_DISABLE; - state->render_states[WINED3D_RS_CLIPPLANEENABLE] = 0; - state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING] = FALSE; + rs[WINED3D_RS_FOGDENSITY] = tmpfloat.d; + rs[WINED3D_RS_EDGEANTIALIAS] = FALSE; + rs[WINED3D_RS_RANGEFOGENABLE] = FALSE; + rs[WINED3D_RS_STENCILENABLE] = FALSE; + rs[WINED3D_RS_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_STENCILREF] = 0; + rs[WINED3D_RS_STENCILMASK] = 0xffffffff; + rs[WINED3D_RS_STENCILFUNC] = WINED3D_CMP_ALWAYS; + rs[WINED3D_RS_STENCILWRITEMASK] = 0xffffffff; + rs[WINED3D_RS_TEXTUREFACTOR] = 0xffffffff; + rs[WINED3D_RS_WRAP0] = 0; + rs[WINED3D_RS_WRAP1] = 0; + rs[WINED3D_RS_WRAP2] = 0; + rs[WINED3D_RS_WRAP3] = 0; + rs[WINED3D_RS_WRAP4] = 0; + rs[WINED3D_RS_WRAP5] = 0; + rs[WINED3D_RS_WRAP6] = 0; + rs[WINED3D_RS_WRAP7] = 0; + rs[WINED3D_RS_CLIPPING] = TRUE; + rs[WINED3D_RS_LIGHTING] = TRUE; + rs[WINED3D_RS_AMBIENT] = 0; + rs[WINED3D_RS_FOGVERTEXMODE] = WINED3D_FOG_NONE; + rs[WINED3D_RS_COLORVERTEX] = TRUE; + rs[WINED3D_RS_LOCALVIEWER] = TRUE; + rs[WINED3D_RS_NORMALIZENORMALS] = FALSE; + rs[WINED3D_RS_DIFFUSEMATERIALSOURCE] = WINED3D_MCS_COLOR1; + rs[WINED3D_RS_SPECULARMATERIALSOURCE] = WINED3D_MCS_COLOR2; + rs[WINED3D_RS_AMBIENTMATERIALSOURCE] = WINED3D_MCS_MATERIAL; + rs[WINED3D_RS_EMISSIVEMATERIALSOURCE] = WINED3D_MCS_MATERIAL; + rs[WINED3D_RS_VERTEXBLEND] = WINED3D_VBF_DISABLE; + rs[WINED3D_RS_CLIPPLANEENABLE] = 0; + rs[WINED3D_RS_SOFTWAREVERTEXPROCESSING] = FALSE; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_POINTSIZE] = tmpfloat.d; + rs[WINED3D_RS_POINTSIZE] = tmpfloat.d; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_POINTSIZE_MIN] = tmpfloat.d; - state->render_states[WINED3D_RS_POINTSPRITEENABLE] = FALSE; - state->render_states[WINED3D_RS_POINTSCALEENABLE] = FALSE; + rs[WINED3D_RS_POINTSIZE_MIN] = tmpfloat.d; + rs[WINED3D_RS_POINTSPRITEENABLE] = FALSE; + rs[WINED3D_RS_POINTSCALEENABLE] = FALSE; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_POINTSCALE_A] = tmpfloat.d; + rs[WINED3D_RS_POINTSCALE_A] = tmpfloat.d; tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_POINTSCALE_B] = tmpfloat.d; + rs[WINED3D_RS_POINTSCALE_B] = tmpfloat.d; tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_POINTSCALE_C] = tmpfloat.d; - state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS] = TRUE; - state->render_states[WINED3D_RS_MULTISAMPLEMASK] = 0xffffffff; - state->render_states[WINED3D_RS_PATCHEDGESTYLE] = WINED3D_PATCH_EDGE_DISCRETE; + rs[WINED3D_RS_POINTSCALE_C] = tmpfloat.d; + rs[WINED3D_RS_MULTISAMPLEANTIALIAS] = TRUE; + rs[WINED3D_RS_MULTISAMPLEMASK] = 0xffffffff; + rs[WINED3D_RS_PATCHEDGESTYLE] = WINED3D_PATCH_EDGE_DISCRETE; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_PATCHSEGMENTS] = tmpfloat.d; - state->render_states[WINED3D_RS_DEBUGMONITORTOKEN] = 0xbaadcafe; - tmpfloat.f = gl_info->limits.pointsize_max; - state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d; - state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE; + rs[WINED3D_RS_PATCHSEGMENTS] = tmpfloat.d; + rs[WINED3D_RS_DEBUGMONITORTOKEN] = 0xbaadcafe; + tmpfloat.f = d3d_info->limits.pointsize_max; + rs[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d; + rs[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE; tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d; - state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD; - state->render_states[WINED3D_RS_POSITIONDEGREE] = WINED3D_DEGREE_CUBIC; - state->render_states[WINED3D_RS_NORMALDEGREE] = WINED3D_DEGREE_LINEAR; + rs[WINED3D_RS_TWEENFACTOR] = tmpfloat.d; + rs[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD; + rs[WINED3D_RS_POSITIONDEGREE] = WINED3D_DEGREE_CUBIC; + rs[WINED3D_RS_NORMALDEGREE] = WINED3D_DEGREE_LINEAR; /* states new in d3d9 */ - state->render_states[WINED3D_RS_SCISSORTESTENABLE] = FALSE; - state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] = 0; + rs[WINED3D_RS_SCISSORTESTENABLE] = FALSE; + rs[WINED3D_RS_SLOPESCALEDEPTHBIAS] = 0; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_MINTESSELLATIONLEVEL] = tmpfloat.d; - state->render_states[WINED3D_RS_MAXTESSELLATIONLEVEL] = tmpfloat.d; - state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE] = FALSE; + rs[WINED3D_RS_MINTESSELLATIONLEVEL] = tmpfloat.d; + rs[WINED3D_RS_MAXTESSELLATIONLEVEL] = tmpfloat.d; + rs[WINED3D_RS_ANTIALIASEDLINEENABLE] = FALSE; tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_ADAPTIVETESS_X] = tmpfloat.d; - state->render_states[WINED3D_RS_ADAPTIVETESS_Y] = tmpfloat.d; + rs[WINED3D_RS_ADAPTIVETESS_X] = tmpfloat.d; + rs[WINED3D_RS_ADAPTIVETESS_Y] = tmpfloat.d; tmpfloat.f = 1.0f; - state->render_states[WINED3D_RS_ADAPTIVETESS_Z] = tmpfloat.d; - tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_ADAPTIVETESS_W] = tmpfloat.d; - state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION] = FALSE; - state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE] = FALSE; - state->render_states[WINED3D_RS_BACK_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS; - state->render_states[WINED3D_RS_BLENDFACTOR] = 0xffffffff; - state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0; - state->render_states[WINED3D_RS_DEPTHBIAS] = 0; + rs[WINED3D_RS_ADAPTIVETESS_Z] = tmpfloat.d; tmpfloat.f = 0.0f; - state->render_states[WINED3D_RS_DEPTHBIASCLAMP] = tmpfloat.d; - state->render_states[WINED3D_RS_DEPTHCLIP] = TRUE; - state->render_states[WINED3D_RS_WRAP8] = 0; - state->render_states[WINED3D_RS_WRAP9] = 0; - state->render_states[WINED3D_RS_WRAP10] = 0; - state->render_states[WINED3D_RS_WRAP11] = 0; - state->render_states[WINED3D_RS_WRAP12] = 0; - state->render_states[WINED3D_RS_WRAP13] = 0; - state->render_states[WINED3D_RS_WRAP14] = 0; - state->render_states[WINED3D_RS_WRAP15] = 0; - state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE] = FALSE; - state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE; - state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO; - state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD; + rs[WINED3D_RS_ADAPTIVETESS_W] = tmpfloat.d; + rs[WINED3D_RS_ENABLEADAPTIVETESSELLATION] = FALSE; + rs[WINED3D_RS_TWOSIDEDSTENCILMODE] = FALSE; + rs[WINED3D_RS_BACK_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS; + rs[WINED3D_RS_SRGBWRITEENABLE] = 0; + rs[WINED3D_RS_DEPTHBIAS] = 0; + rs[WINED3D_RS_WRAP8] = 0; + rs[WINED3D_RS_WRAP9] = 0; + rs[WINED3D_RS_WRAP10] = 0; + rs[WINED3D_RS_WRAP11] = 0; + rs[WINED3D_RS_WRAP12] = 0; + rs[WINED3D_RS_WRAP13] = 0; + rs[WINED3D_RS_WRAP14] = 0; + rs[WINED3D_RS_WRAP15] = 0; + rs[WINED3D_RS_SEPARATEALPHABLENDENABLE] = FALSE; + rs[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE; + rs[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO; + rs[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD; for (i = 0; i < MAX_RENDER_TARGETS; ++i) - state->render_states[WINED3D_RS_COLORWRITE(i)] = 0x0000000f; + rs[WINED3D_RS_COLORWRITE(i)] = 0x0000000f; +} - /* Texture Stage States - Put directly into state block, we will call function below */ - for (i = 0; i < MAX_TEXTURES; ++i) - { - TRACE("Setting up default texture states for texture Stage %u.\n", i); - state->transforms[WINED3D_TS_TEXTURE0 + i] = identity; - state->texture_states[i][WINED3D_TSS_COLOR_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_MODULATE; - state->texture_states[i][WINED3D_TSS_COLOR_ARG1] = WINED3DTA_TEXTURE; - state->texture_states[i][WINED3D_TSS_COLOR_ARG2] = WINED3DTA_CURRENT; - state->texture_states[i][WINED3D_TSS_ALPHA_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_SELECT_ARG1; - state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] = WINED3DTA_TEXTURE; - state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] = WINED3DTA_CURRENT; - state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00] = 0; - state->texture_states[i][WINED3D_TSS_BUMPENV_MAT01] = 0; - state->texture_states[i][WINED3D_TSS_BUMPENV_MAT10] = 0; - state->texture_states[i][WINED3D_TSS_BUMPENV_MAT11] = 0; - state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] = i; - state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE] = 0; - state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET] = 0; - state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS] = WINED3D_TTFF_DISABLE; - state->texture_states[i][WINED3D_TSS_COLOR_ARG0] = WINED3DTA_CURRENT; - state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] = WINED3DTA_CURRENT; - state->texture_states[i][WINED3D_TSS_RESULT_ARG] = WINED3DTA_CURRENT; - } - - for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i) +static void init_default_texture_state(unsigned int i, DWORD stage[WINED3D_HIGHEST_TEXTURE_STATE + 1]) +{ + stage[WINED3D_TSS_COLOR_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_MODULATE; + stage[WINED3D_TSS_COLOR_ARG1] = WINED3DTA_TEXTURE; + stage[WINED3D_TSS_COLOR_ARG2] = WINED3DTA_CURRENT; + stage[WINED3D_TSS_ALPHA_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_SELECT_ARG1; + stage[WINED3D_TSS_ALPHA_ARG1] = WINED3DTA_TEXTURE; + stage[WINED3D_TSS_ALPHA_ARG2] = WINED3DTA_CURRENT; + stage[WINED3D_TSS_BUMPENV_MAT00] = 0; + stage[WINED3D_TSS_BUMPENV_MAT01] = 0; + stage[WINED3D_TSS_BUMPENV_MAT10] = 0; + stage[WINED3D_TSS_BUMPENV_MAT11] = 0; + stage[WINED3D_TSS_TEXCOORD_INDEX] = i; + stage[WINED3D_TSS_BUMPENV_LSCALE] = 0; + stage[WINED3D_TSS_BUMPENV_LOFFSET] = 0; + stage[WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS] = WINED3D_TTFF_DISABLE; + stage[WINED3D_TSS_COLOR_ARG0] = WINED3DTA_CURRENT; + stage[WINED3D_TSS_ALPHA_ARG0] = WINED3DTA_CURRENT; + stage[WINED3D_TSS_RESULT_ARG] = WINED3DTA_CURRENT; +} + +static void init_default_sampler_states(DWORD states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]) +{ + unsigned int i; + + for (i = 0 ; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { TRACE("Setting up default samplers states for sampler %u.\n", i); - state->sampler_states[i][WINED3D_SAMP_ADDRESS_U] = WINED3D_TADDRESS_WRAP; - state->sampler_states[i][WINED3D_SAMP_ADDRESS_V] = WINED3D_TADDRESS_WRAP; - state->sampler_states[i][WINED3D_SAMP_ADDRESS_W] = WINED3D_TADDRESS_WRAP; - state->sampler_states[i][WINED3D_SAMP_BORDER_COLOR] = 0; - state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] = WINED3D_TEXF_POINT; - state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] = WINED3D_TEXF_POINT; - state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] = WINED3D_TEXF_NONE; - state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] = 0; - state->sampler_states[i][WINED3D_SAMP_MAX_MIP_LEVEL] = 0; - state->sampler_states[i][WINED3D_SAMP_MAX_ANISOTROPY] = 1; - state->sampler_states[i][WINED3D_SAMP_SRGB_TEXTURE] = 0; + states[i][WINED3D_SAMP_ADDRESS_U] = WINED3D_TADDRESS_WRAP; + states[i][WINED3D_SAMP_ADDRESS_V] = WINED3D_TADDRESS_WRAP; + states[i][WINED3D_SAMP_ADDRESS_W] = WINED3D_TADDRESS_WRAP; + states[i][WINED3D_SAMP_BORDER_COLOR] = 0; + states[i][WINED3D_SAMP_MAG_FILTER] = WINED3D_TEXF_POINT; + states[i][WINED3D_SAMP_MIN_FILTER] = WINED3D_TEXF_POINT; + states[i][WINED3D_SAMP_MIP_FILTER] = WINED3D_TEXF_NONE; + states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] = 0; + states[i][WINED3D_SAMP_MAX_MIP_LEVEL] = 0; + states[i][WINED3D_SAMP_MAX_ANISOTROPY] = 1; + states[i][WINED3D_SAMP_SRGB_TEXTURE] = 0; /* TODO: Indicates which element of a multielement texture to use. */ - state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; + states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; /* TODO: Vertex offset in the presampled displacement map. */ - state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; + states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; + } +} + +static void state_init_default(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) +{ + unsigned int i; + struct wined3d_matrix identity; + + TRACE("state %p, d3d_info %p.\n", state, d3d_info); + + get_identity_matrix(&identity); + state->gl_primitive_type = ~0u; + state->gl_patch_vertices = 0; + + /* Set some of the defaults for lights, transforms etc */ + state->transforms[WINED3D_TS_PROJECTION] = identity; + state->transforms[WINED3D_TS_VIEW] = identity; + for (i = 0; i < 256; ++i) + { + state->transforms[WINED3D_TS_WORLD_MATRIX(i)] = identity; + } + + init_default_render_states(state->render_states, d3d_info); + + /* Texture Stage States - Put directly into state block, we will call function below */ + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + { + TRACE("Setting up default texture states for texture Stage %u.\n", i); + state->transforms[WINED3D_TS_TEXTURE0 + i] = identity; + init_default_texture_state(i, state->texture_states[i]); } + + init_default_sampler_states(state->sampler_states); + + state->blend_factor.r = 1.0f; + state->blend_factor.g = 1.0f; + state->blend_factor.b = 1.0f; + state->blend_factor.a = 1.0f; + + for (i = 0; i < WINED3D_MAX_STREAMS; ++i) + state->streams[i].frequency = 1; } void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, - DWORD flags) + const struct wined3d_d3d_info *d3d_info, DWORD flags) { unsigned int i; @@ -1318,11 +1689,60 @@ void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, for (i = 0; i < LIGHTMAP_SIZE; i++) { - list_init(&state->light_map[i]); + list_init(&state->light_state.light_map[i]); + } + + if (flags & WINED3D_STATE_INIT_DEFAULT) + state_init_default(state, d3d_info); +} + +static void stateblock_state_init_default(struct wined3d_stateblock_state *state, + const struct wined3d_d3d_info *d3d_info) +{ + struct wined3d_matrix identity; + unsigned int i; + + get_identity_matrix(&identity); + + state->transforms[WINED3D_TS_PROJECTION] = identity; + state->transforms[WINED3D_TS_VIEW] = identity; + for (i = 0; i < 256; ++i) + { + state->transforms[WINED3D_TS_WORLD_MATRIX(i)] = identity; + } + + init_default_render_states(state->rs, d3d_info); + + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + { + state->transforms[WINED3D_TS_TEXTURE0 + i] = identity; + init_default_texture_state(i, state->texture_states[i]); + } + + init_default_sampler_states(state->sampler_states); + + state->blend_factor.r = 1.0f; + state->blend_factor.g = 1.0f; + state->blend_factor.b = 1.0f; + state->blend_factor.a = 1.0f; + + for (i = 0; i < WINED3D_MAX_STREAMS; ++i) + state->streams[i].frequency = 1; +} + +void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state, + const struct wined3d_device *device, DWORD flags) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(state->light_state.light_map); i++) + { + list_init(&state->light_state.light_map[i]); } if (flags & WINED3D_STATE_INIT_DEFAULT) - state_init_default(state, gl_info); + stateblock_state_init_default(state, &device->adapter->d3d_info); + } static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, @@ -1332,9 +1752,12 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, stateblock->ref = 1; stateblock->device = device; - state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0); + wined3d_stateblock_state_init(&stateblock->stateblock_state, device, + type == WINED3D_SBT_PRIMARY ? WINED3D_STATE_INIT_DEFAULT : 0); + + stateblock->changed.store_stream_offset = 1; - if (type == WINED3D_SBT_RECORDED) + if (type == WINED3D_SBT_RECORDED || type == WINED3D_SBT_PRIMARY) return WINED3D_OK; TRACE("Updating changed flags appropriate for type %#x.\n", type); @@ -1342,9 +1765,10 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, switch (type) { case WINED3D_SBT_ALL: - stateblock_init_lights(stateblock, device->state.light_map); + stateblock_init_lights(stateblock->stateblock_state.light_state.light_map, + device->stateblock_state.light_state.light_map); stateblock_savedstates_set_all(&stateblock->changed, - d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count); + d3d_info->limits.vs_uniform_count_swvp, d3d_info->limits.ps_uniform_count); break; case WINED3D_SBT_PIXEL_STATE: @@ -1353,9 +1777,10 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, break; case WINED3D_SBT_VERTEX_STATE: - stateblock_init_lights(stateblock, device->state.light_map); + stateblock_init_lights(stateblock->stateblock_state.light_state.light_map, + device->stateblock_state.light_state.light_map); stateblock_savedstates_set_vertex(&stateblock->changed, - d3d_info->limits.vs_uniform_count); + d3d_info->limits.vs_uniform_count_swvp); break; default: @@ -1366,6 +1791,12 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, stateblock_init_contained_states(stateblock); wined3d_stateblock_capture(stateblock); + /* According to the tests, stream offset is not updated in the captured state if + * the state was captured on state block creation. This is not the case for + * state blocks initialized with BeginStateBlock / EndStateBlock, multiple + * captures get stream offsets updated. */ + stateblock->changed.store_stream_offset = 0; + return WINED3D_OK; } @@ -1393,4 +1824,4 @@ HRESULT CDECL wined3d_stateblock_create(struct wined3d_device *device, *stateblock = object; return WINED3D_OK; -} +} \ No newline at end of file diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c index ae32235a9e6..fc372a0e882 100644 --- a/dll/directx/wine/wined3d/surface.c +++ b/dll/directx/wine/wined3d/surface.c @@ -36,208 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER; -struct blt_info -{ - GLenum binding; - GLenum bind_target; - enum wined3d_gl_resource_type tex_type; - struct wined3d_vec3 texcoords[4]; -}; - -struct float_rect -{ - float l; - float t; - float r; - float b; -}; - -static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f) -{ - f->l = ((r->left * 2.0f) / w) - 1.0f; - f->t = ((r->top * 2.0f) / h) - 1.0f; - f->r = ((r->right * 2.0f) / w) - 1.0f; - f->b = ((r->bottom * 2.0f) / h) - 1.0f; -} - -static void texture2d_get_blt_info(const struct wined3d_texture *texture, - unsigned int sub_resource_idx, const RECT *rect, struct blt_info *info) -{ - struct wined3d_vec3 *coords = info->texcoords; - struct float_rect f; - unsigned int level; - GLenum target; - GLsizei w, h; - - level = sub_resource_idx % texture->level_count; - w = wined3d_texture_get_level_pow2_width(texture, level); - h = wined3d_texture_get_level_pow2_height(texture, level); - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - - switch (target) - { - default: - FIXME("Unsupported texture target %#x.\n", target); - /* Fall back to GL_TEXTURE_2D */ - case GL_TEXTURE_2D: - info->binding = GL_TEXTURE_BINDING_2D; - info->bind_target = GL_TEXTURE_2D; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_2D; - coords[0].x = (float)rect->left / w; - coords[0].y = (float)rect->top / h; - coords[0].z = 0.0f; - - coords[1].x = (float)rect->right / w; - coords[1].y = (float)rect->top / h; - coords[1].z = 0.0f; - - coords[2].x = (float)rect->left / w; - coords[2].y = (float)rect->bottom / h; - coords[2].z = 0.0f; - - coords[3].x = (float)rect->right / w; - coords[3].y = (float)rect->bottom / h; - coords[3].z = 0.0f; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; - info->bind_target = GL_TEXTURE_RECTANGLE_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_RECT; - coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f; - coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f; - coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f; - coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - cube_coords_float(rect, w, h, &f); - - coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l; - coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r; - coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l; - coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - cube_coords_float(rect, w, h, &f); - - coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l; - coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r; - coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l; - coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - cube_coords_float(rect, w, h, &f); - - coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t; - coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t; - coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b; - coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - cube_coords_float(rect, w, h, &f); - - coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t; - coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t; - coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b; - coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - cube_coords_float(rect, w, h, &f); - - coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f; - coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f; - coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f; - coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - cube_coords_float(rect, w, h, &f); - - coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f; - coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f; - coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f; - coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f; - break; - } -} - -/* Context activation is done by the caller. */ -void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, - enum wined3d_texture_filter_type filter) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct blt_info info; - - texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info); - - gl_info->gl_ops.gl.p_glEnable(info.bind_target); - checkGLcall("glEnable(bind_target)"); - - context_bind_texture(context, info.bind_target, texture->texture_rgb.name); - - /* Filtering for StretchRect */ - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); - checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); - checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - checkGLcall("glTexEnvi"); - - /* Draw a quad */ - gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top); - - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top); - - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom); - - gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom); - gl_info->gl_ops.gl.p_glEnd(); - - /* Unbind the texture */ - context_bind_texture(context, info.bind_target, 0); - - /* We changed the filtering settings on the texture. Inform the - * container about this to get the filters reset properly next draw. */ - texture->texture_rgb.sampler_desc.mag_filter = WINED3D_TEXF_POINT; - texture->texture_rgb.sampler_desc.min_filter = WINED3D_TEXF_POINT; - texture->texture_rgb.sampler_desc.mip_filter = WINED3D_TEXF_NONE; - texture->texture_rgb.sampler_desc.srgb_decode = FALSE; -} - /* Works correctly only for <= 4 bpp formats. */ static void get_color_masks(const struct wined3d_format *format, DWORD *masks) { @@ -259,24 +57,20 @@ static BOOL texture2d_is_full_rect(const struct wined3d_texture *texture, unsign return TRUE; } -static void surface_depth_blt_fbo(const struct wined3d_device *device, - struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, - struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect) +static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, + const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + DWORD dst_location, const RECT *dst_rect) { - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_texture *src_texture = src_surface->container; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; DWORD src_mask, dst_mask; GLbitfield gl_mask; - TRACE("device %p\n", device); - TRACE("src_surface %p, src_location %s, src_rect %s,\n", - src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect)); - TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", - dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); + TRACE("device %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", device, + src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), + dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); src_mask = src_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); dst_mask = dst_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); @@ -302,14 +96,6 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, if (src_mask & WINED3DFMT_FLAG_STENCIL) gl_mask |= GL_STENCIL_BUFFER_BIT; - context = context_acquire(device, NULL, 0); - if (!context->valid) - { - context_release(context); - WARN("Invalid context, skipping blit.\n"); - return; - } - /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. */ wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location); @@ -318,14 +104,14 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, else wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); - gl_info = context->gl_info; + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, NULL, 0, + &src_texture->resource, src_sub_resource_idx, src_location); + wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER); - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, src_location); - context_check_fbo_status(context, GL_READ_FRAMEBUFFER); - - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, dst_surface, dst_location); - context_set_draw_buffer(context, GL_NONE); - context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, NULL, 0, + &dst_texture->resource, dst_sub_resource_idx, dst_location); + wined3d_context_gl_set_draw_buffer(context_gl, GL_NONE); + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); if (gl_mask & GL_DEPTH_BUFFER_BIT) @@ -335,7 +121,7 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, } if (gl_mask & GL_STENCIL_BUFFER_BIT) { - if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE]) + if (gl_info->supported[EXT_STENCIL_TWO_SIDE]) { gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE)); @@ -350,134 +136,129 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST); checkGLcall("glBlitFramebuffer()"); - - if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); -} - -static BOOL is_multisample_location(const struct wined3d_texture *texture, DWORD location) -{ - if (location == WINED3D_LOCATION_RB_MULTISAMPLE) - return TRUE; - if (location != WINED3D_LOCATION_TEXTURE_RGB && location != WINED3D_LOCATION_TEXTURE_SRGB) - return FALSE; - return texture->target == GL_TEXTURE_2D_MULTISAMPLE || texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY; } /* Blit between surface locations. Onscreen on different swapchains is not supported. * Depth / stencil is not supported. Context activation is done by the caller. */ -static void surface_blt_fbo(const struct wined3d_device *device, - struct wined3d_context *old_ctx, enum wined3d_texture_filter_type filter, - struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect_in, - struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect_in) +void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *context, + enum wined3d_texture_filter_type filter, struct wined3d_texture *src_texture, + unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, + const RECT *dst_rect) { - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *required_texture, *restore_texture; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context = old_ctx; - struct wined3d_surface *required_rt, *restore_rt = NULL; - RECT src_rect, dst_rect; + struct wined3d_context_gl *context_gl; + unsigned int restore_idx; GLenum gl_filter; GLenum buffer; int i; + RECT s, d; - TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter)); - TRACE("src_surface %p, src_location %s, src_rect %s,\n", - src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect_in)); - TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", - dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect_in)); - - src_rect = *src_rect_in; - dst_rect = *dst_rect_in; + TRACE("device %p, context %p, filter %s, src_texture %p, src_sub_resource_idx %u, src_location %s, " + "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", + device, context, debug_d3dtexturefiltertype(filter), src_texture, src_sub_resource_idx, + wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect), dst_texture, + dst_sub_resource_idx, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); switch (filter) { - case WINED3D_TEXF_LINEAR: - gl_filter = GL_LINEAR; + case WINED3D_TEXF_NONE: + case WINED3D_TEXF_POINT: + gl_filter = GL_NEAREST; break; default: FIXME("Unsupported filter mode %s (%#x).\n", debug_d3dtexturefiltertype(filter), filter); - case WINED3D_TEXF_NONE: - case WINED3D_TEXF_POINT: - gl_filter = GL_NEAREST; + /* fall through */ + case WINED3D_TEXF_LINEAR: + gl_filter = GL_LINEAR; break; } /* Resolve the source surface first if needed. */ - if (is_multisample_location(src_texture, src_location) + if (wined3d_texture_gl_is_multisample_location(wined3d_texture_gl(src_texture), src_location) && (src_texture->resource.format->id != dst_texture->resource.format->id - || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top) - || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left))) + || abs(src_rect->bottom - src_rect->top) != abs(dst_rect->bottom - dst_rect->top) + || abs(src_rect->right - src_rect->left) != abs(dst_rect->right - dst_rect->left))) src_location = WINED3D_LOCATION_RB_RESOLVED; /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. (And is * in fact harmful if we're being called by surface_load_location() with * the purpose of loading the destination surface.) */ - wined3d_texture_load_location(src_texture, src_sub_resource_idx, old_ctx, src_location); - if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_rect)) - wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location); + wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location); + if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, dst_rect)) + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location); else - wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location); - + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); - if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface; - else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface; - else required_rt = NULL; + /* Acquire a context for the front-buffer, even though we may be blitting + * to/from a back-buffer. Since context_acquire() doesn't take the + * resource location into account, it may consider the back-buffer to be + * offscreen. */ + if (src_location == WINED3D_LOCATION_DRAWABLE) + required_texture = src_texture->swapchain->front_buffer; + else if (dst_location == WINED3D_LOCATION_DRAWABLE) + required_texture = dst_texture->swapchain->front_buffer; + else + required_texture = NULL; - restore_rt = context_get_rt_surface(old_ctx); - if (restore_rt != required_rt) - context = context_acquire(device, required_rt ? required_rt->container : NULL, - required_rt ? surface_get_sub_resource_idx(required_rt) : 0); + restore_texture = context->current_rt.texture; + restore_idx = context->current_rt.sub_resource_idx; + if (restore_texture != required_texture) + context = context_acquire(device, required_texture, 0); else - restore_rt = NULL; + restore_texture = NULL; - if (!context->valid) + context_gl = wined3d_context_gl(context); + if (!context_gl->valid) { context_release(context); WARN("Invalid context, skipping blit.\n"); return; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; if (src_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Source surface %p is onscreen.\n", src_surface); + TRACE("Source texture %p is onscreen.\n", src_texture); buffer = wined3d_texture_get_gl_buffer(src_texture); - surface_translate_drawable_coords(src_surface, context->win_handle, &src_rect); + s = *src_rect; + wined3d_texture_translate_drawable_coords(src_texture, context_gl->window, &s); + src_rect = &s; } else { - TRACE("Source surface %p is offscreen.\n", src_surface); + TRACE("Source texture %p is offscreen.\n", src_texture); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL, src_location); + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, + &src_texture->resource, src_sub_resource_idx, NULL, 0, src_location); gl_info->gl_ops.gl.p_glReadBuffer(buffer); checkGLcall("glReadBuffer()"); - context_check_fbo_status(context, GL_READ_FRAMEBUFFER); + wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER); if (dst_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Destination surface %p is onscreen.\n", dst_surface); + TRACE("Destination texture %p is onscreen.\n", dst_texture); buffer = wined3d_texture_get_gl_buffer(dst_texture); - surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect); + d = *dst_rect; + wined3d_texture_translate_drawable_coords(dst_texture, context_gl->window, &d); + dst_rect = &d; } else { - TRACE("Destination surface %p is offscreen.\n", dst_surface); + TRACE("Destination texture %p is offscreen.\n", dst_texture); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); - context_set_draw_buffer(context, buffer); - context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, + &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location); + wined3d_context_gl_set_draw_buffer(context_gl, buffer); + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -487,19 +268,18 @@ static void surface_blt_fbo(const struct wined3d_device *device, gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); - gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, - dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); + gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, + dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, GL_COLOR_BUFFER_BIT, gl_filter); checkGLcall("glBlitFramebuffer()"); - if (wined3d_settings.strict_draw_ordering || (dst_location == WINED3D_LOCATION_DRAWABLE - && dst_texture->swapchain->front_buffer == dst_texture)) + if (dst_location == WINED3D_LOCATION_DRAWABLE && dst_texture->swapchain->front_buffer == dst_texture) gl_info->gl_ops.gl.p_glFlush(); - if (restore_rt) - context_restore(context, restore_rt); + if (restore_texture) + context_restore(context, restore_texture, restore_idx); } -static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_gl_info *gl_info, +BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_gl_info *gl_info, const struct wined3d_resource *src_resource, DWORD src_location, const struct wined3d_resource *dst_resource, DWORD dst_location) { @@ -513,14 +293,17 @@ static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct win if (!(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) return FALSE; + if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) + return FALSE; + switch (blit_op) { case WINED3D_BLIT_OP_COLOR_BLIT: if (!((src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (src_resource->usage & WINED3DUSAGE_RENDERTARGET))) + || (src_resource->bind_flags & WINED3D_BIND_RENDER_TARGET))) return FALSE; if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (dst_resource->usage & WINED3DUSAGE_RENDERTARGET))) + || (dst_resource->bind_flags & WINED3D_BIND_RENDER_TARGET))) return FALSE; if ((src_format->id != dst_format->id || dst_location == WINED3D_LOCATION_DRAWABLE) && (!is_identity_fixup(src_format->color_fixup) || !is_identity_fixup(dst_format->color_fixup))) @@ -547,2113 +330,720 @@ static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct win return TRUE; } -/* This call just downloads data, the caller is responsible for binding the - * correct texture. */ -/* Context activation is done by the caller. */ -static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - DWORD dst_location) +/* See also float_16_to_32() in wined3d_private.h */ +static inline unsigned short float_32_to_16(const float *in) { - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - struct wined3d_texture *texture = surface->container; - const struct wined3d_format *format = texture->resource.format; - struct wined3d_texture_sub_resource *sub_resource; - unsigned int dst_row_pitch, dst_slice_pitch; - unsigned int src_row_pitch, src_slice_pitch; - struct wined3d_bo_address data; - BYTE *temporary_mem = NULL; - unsigned int level; - GLenum target; - void *mem; + int exp = 0; + float tmp = fabsf(*in); + unsigned int mantissa; + unsigned short ret; + + /* Deal with special numbers */ + if (*in == 0.0f) + return 0x0000; + if (isnan(*in)) + return 0x7c01; + if (isinf(*in)) + return (*in < 0.0f ? 0xfc00 : 0x7c00); - /* Only support read back of converted P8 surfaces. */ - if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT && !format->download) + if (tmp < (float)(1u << 10)) { - ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id)); - return; + do + { + tmp = tmp * 2.0f; + exp--; + } while (tmp < (float)(1u << 10)); } - - sub_resource = &texture->sub_resources[sub_resource_idx]; - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - level = sub_resource_idx % texture->level_count; - - if (target == GL_TEXTURE_2D_ARRAY) + else if (tmp >= (float)(1u << 11)) { - if (format->download) + do { - FIXME("Reading back converted array texture %p is not supported.\n", texture); - return; - } + tmp /= 2.0f; + exp++; + } while (tmp >= (float)(1u << 11)); + } - /* NP2 emulation is not allowed on array textures. */ - if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) - ERR("Array texture %p uses NP2 emulation.\n", texture); + mantissa = (unsigned int)tmp; + if (tmp - mantissa >= 0.5f) + ++mantissa; /* Round to nearest, away from zero. */ - WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); + exp += 10; /* Normalize the mantissa. */ + exp += 15; /* Exponent is encoded with excess 15. */ - if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size))) - { - ERR("Out of memory.\n"); - return; - } + if (exp > 30) /* too big */ + { + ret = 0x7c00; /* INF */ } - - wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); - - if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + else if (exp <= 0) { - if (format->download) - { - FIXME("Reading back converted texture %p with NP2 emulation is not supported.\n", texture); - return; - } - - wined3d_texture_get_pitch(texture, level, &dst_row_pitch, &dst_slice_pitch); - wined3d_format_calculate_pitch(format, texture->resource.device->surface_alignment, - wined3d_texture_get_level_pow2_width(texture, level), - wined3d_texture_get_level_pow2_height(texture, level), - &src_row_pitch, &src_slice_pitch); - if (!(temporary_mem = heap_alloc(src_slice_pitch))) + /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */ + while (exp <= 0) { - ERR("Out of memory.\n"); - return; + mantissa = mantissa >> 1; + ++exp; } - - if (data.buffer_object) - ERR("NP2 emulated texture uses PBO unexpectedly.\n"); - if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) - ERR("Unexpected compressed format for NP2 emulated texture.\n"); + ret = mantissa & 0x3ff; } - - if (format->download) + else { - struct wined3d_format f; + ret = (exp << 10) | (mantissa & 0x3ff); + } - if (data.buffer_object) - ERR("Converted texture %p uses PBO unexpectedly.\n", texture); + ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */ + return ret; +} - WARN_(d3d_perf)("Downloading converted surface %p with format %s.\n", surface, debug_d3dformat(format->id)); +static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + unsigned short *dst_s; + const float *src_f; + unsigned int x, y; - f = *format; - f.byte_count = format->conv_byte_count; - wined3d_texture_get_pitch(texture, level, &dst_row_pitch, &dst_slice_pitch); - wined3d_format_calculate_pitch(&f, texture->resource.device->surface_alignment, - wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level), - &src_row_pitch, &src_slice_pitch); + TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - if (!(temporary_mem = heap_alloc(src_slice_pitch))) + for (y = 0; y < h; ++y) + { + src_f = (const float *)(src + y * pitch_in); + dst_s = (unsigned short *) (dst + y * pitch_out); + for (x = 0; x < w; ++x) { - ERR("Failed to allocate memory.\n"); - return; + dst_s[x] = float_32_to_16(src_f + x); } } +} - if (temporary_mem) - { - mem = temporary_mem; - } - else if (data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); - checkGLcall("glBindBuffer"); - mem = data.addr; - } - else - { - mem = data.addr; - } - - if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) +static void convert_r5g6b5_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + static const unsigned char convert_5to8[] = { - TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n", - surface, level, format->glFormat, format->glType, mem); - - GL_EXTCALL(glGetCompressedTexImage(target, level, mem)); - checkGLcall("glGetCompressedTexImage"); - } - else + 0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a, + 0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b, + 0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd, + 0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff, + }; + static const unsigned char convert_6to8[] = { - TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n", - surface, level, format->glFormat, format->glType, mem); + 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, + 0x20, 0x24, 0x28, 0x2d, 0x31, 0x35, 0x39, 0x3d, + 0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d, + 0x61, 0x65, 0x69, 0x6d, 0x71, 0x75, 0x79, 0x7d, + 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e, + 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe, + 0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd7, 0xdb, 0xdf, + 0xe3, 0xe7, 0xeb, 0xef, 0xf3, 0xf7, 0xfb, 0xff, + }; + unsigned int x, y; - gl_info->gl_ops.gl.p_glGetTexImage(target, level, format->glFormat, format->glType, mem); - checkGLcall("glGetTexImage"); - } + TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - if (format->download) - { - format->download(mem, data.addr, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, - wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level), 1); - } - else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + for (y = 0; y < h; ++y) { - const BYTE *src_data; - unsigned int h, y; - BYTE *dst_data; - /* - * Some games (e.g. warhammer 40k) don't work properly with the odd pitches, preventing - * the surface pitch from being used to box non-power2 textures. Instead we have to use a hack to - * repack the texture so that the bpp * width pitch can be used instead of bpp * pow2width. - * - * We're doing this... - * - * instead of boxing the texture : - * |<-texture width ->| -->pow2width| /\ - * |111111111111111111| | | - * |222 Texture 222222| boxed empty | texture height - * |3333 Data 33333333| | | - * |444444444444444444| | \/ - * ----------------------------------- | - * | boxed empty | boxed empty | pow2height - * | | | \/ - * ----------------------------------- - * - * - * we're repacking the data to the expected texture width - * - * |<-texture width ->| -->pow2width| /\ - * |111111111111111111222222222222222| | - * |222333333333333333333444444444444| texture height - * |444444 | | - * | | \/ - * | | | - * | empty | pow2height - * | | \/ - * ----------------------------------- - * - * == is the same as - * - * |<-texture width ->| /\ - * |111111111111111111| - * |222222222222222222|texture height - * |333333333333333333| - * |444444444444444444| \/ - * -------------------- - * - * This also means that any references to surface memory should work with the data as if it were a - * standard texture with a non-power2 width instead of a texture boxed up to be a power2 texture. - * - * internally the texture is still stored in a boxed format so any references to textureName will - * get a boxed texture with width pow2width and not a texture of width resource.width. */ - src_data = mem; - dst_data = data.addr; - TRACE("Repacking the surface data from pitch %u to pitch %u.\n", src_row_pitch, dst_row_pitch); - h = wined3d_texture_get_level_height(texture, level); - for (y = 0; y < h; ++y) + const WORD *src_line = (const WORD *)(src + y * pitch_in); + DWORD *dst_line = (DWORD *)(dst + y * pitch_out); + for (x = 0; x < w; ++x) { - memcpy(dst_data, src_data, dst_row_pitch); - src_data += src_row_pitch; - dst_data += dst_row_pitch; + WORD pixel = src_line[x]; + dst_line[x] = 0xff000000u + | convert_5to8[(pixel & 0xf800u) >> 11] << 16 + | convert_6to8[(pixel & 0x07e0u) >> 5] << 8 + | convert_5to8[(pixel & 0x001fu)]; } } - else if (temporary_mem) +} + +/* We use this for both B8G8R8A8 -> B8G8R8X8 and B8G8R8X8 -> B8G8R8A8, since + * in both cases we're just setting the X / Alpha channel to 0xff. */ +static void convert_a8r8g8b8_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + unsigned int x, y; + + TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); + + for (y = 0; y < h; ++y) { - unsigned int layer = sub_resource_idx / texture->level_count; - void *src_data = temporary_mem + layer * sub_resource->size; - if (data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); - checkGLcall("glBindBuffer"); - GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data)); - checkGLcall("glBufferSubData"); - } - else + const DWORD *src_line = (const DWORD *)(src + y * pitch_in); + DWORD *dst_line = (DWORD *)(dst + y * pitch_out); + + for (x = 0; x < w; ++x) { - memcpy(data.addr, src_data, sub_resource->size); + dst_line[x] = 0xff000000 | (src_line[x] & 0xffffff); } } +} - if (data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - - heap_free(temporary_mem); +static inline BYTE cliptobyte(int x) +{ + return (BYTE)((x < 0) ? 0 : ((x > 255) ? 255 : x)); } -/* This call just uploads data, the caller is responsible for binding the - * correct texture. */ -/* Context activation is done by the caller. */ -void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, - BOOL srgb, const struct wined3d_const_bo_address *data) +static void convert_yuy2_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - struct wined3d_texture *texture = surface->container; - UINT update_w = src_rect->right - src_rect->left; - UINT update_h = src_rect->bottom - src_rect->top; - unsigned int level, layer; - GLenum target; + int c2, d, e, r2 = 0, g2 = 0, b2 = 0; + unsigned int x, y; - TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_pitch %u, dst_point %s, srgb %#x, data {%#x:%p}.\n", - surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch, - wine_dbgstr_point(dst_point), srgb, data->buffer_object, data->addr); + TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - if (texture->sub_resources[sub_resource_idx].map_count) + for (y = 0; y < h; ++y) { - WARN("Uploading a surface that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n"); - texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; - } - - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) - { - update_h *= format->height_scale.numerator; - update_h /= format->height_scale.denominator; - } - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); - } - - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - level = sub_resource_idx % texture->level_count; - layer = sub_resource_idx / texture->level_count; - - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) - { - unsigned int dst_row_pitch, dst_slice_pitch; - const BYTE *addr = data->addr; - GLenum internal; - - addr += (src_rect->top / format->block_height) * src_pitch; - addr += (src_rect->left / format->block_width) * format->block_byte_count; - - if (srgb) - internal = format->glGammaInternal; - else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET - && wined3d_resource_is_offscreen(&texture->resource)) - internal = format->rtInternal; - else - internal = format->glInternal; - - wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); - - TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " - "format %#x, image_size %#x, addr %p.\n", - target, level, layer, dst_point->x, dst_point->y, - update_w, update_h, internal, dst_slice_pitch, addr); - - if (dst_row_pitch == src_pitch) - { - if (target == GL_TEXTURE_2D_ARRAY) - { - GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, dst_point->y, - layer, update_w, update_h, 1, internal, dst_slice_pitch, addr)); - } - else - { - GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, dst_point->y, - update_w, update_h, internal, dst_slice_pitch, addr)); - } - } - else + const BYTE *src_line = src + y * pitch_in; + DWORD *dst_line = (DWORD *)(dst + y * pitch_out); + for (x = 0; x < w; ++x) { - UINT row_count = (update_h + format->block_height - 1) / format->block_height; - UINT row, y; - - /* glCompressedTexSubImage2D() ignores pixel store state, so we - * can't use the unpack row length like for glTexSubImage2D. */ - for (row = 0, y = dst_point->y; row < row_count; ++row) + /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV: + * C = Y - 16; D = U - 128; E = V - 128; + * R = cliptobyte((298 * C + 409 * E + 128) >> 8); + * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8); + * B = cliptobyte((298 * C + 516 * D + 128) >> 8); + * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V . + * U and V are shared between the pixels. */ + if (!(x & 1)) /* For every even pixel, read new U and V. */ { - if (target == GL_TEXTURE_2D_ARRAY) - { - GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, y, - layer, update_w, format->block_height, 1, internal, dst_row_pitch, addr)); - } - else - { - GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, y, - update_w, format->block_height, internal, dst_row_pitch, addr)); - } - - y += format->block_height; - addr += src_pitch; + d = (int) src_line[1] - 128; + e = (int) src_line[3] - 128; + r2 = 409 * e + 128; + g2 = - 100 * d - 208 * e + 128; + b2 = 516 * d + 128; } + c2 = 298 * ((int) src_line[0] - 16); + dst_line[x] = 0xff000000 + | cliptobyte((c2 + r2) >> 8) << 16 /* red */ + | cliptobyte((c2 + g2) >> 8) << 8 /* green */ + | cliptobyte((c2 + b2) >> 8); /* blue */ + /* Scale RGB values to 0..255 range, + * then clip them if still not in range (may be negative), + * then shift them within DWORD if necessary. */ + src_line += 2; } - checkGLcall("Upload compressed surface data"); - } - else - { - const BYTE *addr = data->addr; - - addr += src_rect->top * src_pitch; - addr += src_rect->left * format->byte_count; - - TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " - "format %#x, type %#x, addr %p.\n", - target, level, layer, dst_point->x, dst_point->y, - update_w, update_h, format->glFormat, format->glType, addr); - - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count); - if (target == GL_TEXTURE_2D_ARRAY) - { - GL_EXTCALL(glTexSubImage3D(target, level, dst_point->x, dst_point->y, - layer, update_w, update_h, 1, format->glFormat, format->glType, addr)); - } - else - { - gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_point->x, dst_point->y, - update_w, update_h, format->glFormat, format->glType, addr); - } - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - checkGLcall("Upload surface data"); } +} - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } +static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + unsigned int x, y; + int c2, d, e, r2 = 0, g2 = 0, b2 = 0; - if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); + TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out); - if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) + for (y = 0; y < h; ++y) { - struct wined3d_device *device = texture->resource.device; - unsigned int i; - - for (i = 0; i < device->context_count; ++i) + const BYTE *src_line = src + y * pitch_in; + WORD *dst_line = (WORD *)(dst + y * pitch_out); + for (x = 0; x < w; ++x) { - context_surface_update(device->contexts[i], surface); + /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV: + * C = Y - 16; D = U - 128; E = V - 128; + * R = cliptobyte((298 * C + 409 * E + 128) >> 8); + * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8); + * B = cliptobyte((298 * C + 516 * D + 128) >> 8); + * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V . + * U and V are shared between the pixels. */ + if (!(x & 1)) /* For every even pixel, read new U and V. */ + { + d = (int) src_line[1] - 128; + e = (int) src_line[3] - 128; + r2 = 409 * e + 128; + g2 = - 100 * d - 208 * e + 128; + b2 = 516 * d + 128; + } + c2 = 298 * ((int) src_line[0] - 16); + dst_line[x] = (cliptobyte((c2 + r2) >> 8) >> 3) << 11 /* red */ + | (cliptobyte((c2 + g2) >> 8) >> 2) << 5 /* green */ + | (cliptobyte((c2 + b2) >> 8) >> 3); /* blue */ + /* Scale RGB values to 0..255 range, + * then clip them if still not in range (may be negative), + * then shift them within DWORD if necessary. */ + src_line += 2; } } } -static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, - struct wined3d_surface *src_surface, const RECT *src_rect) +static void convert_dxt1_a8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - struct wined3d_texture *src_texture = src_surface->container; - struct wined3d_texture *dst_texture = dst_surface->container; - unsigned int src_row_pitch, src_slice_pitch; - const struct wined3d_gl_info *gl_info; - unsigned int src_level, dst_level; - struct wined3d_context *context; - struct wined3d_bo_address data; - UINT update_w, update_h; - - TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n", - dst_surface, wine_dbgstr_point(dst_point), - src_surface, wine_dbgstr_rect(src_rect)); - - context = context_acquire(dst_texture->resource.device, NULL, 0); - gl_info = context->gl_info; - - /* Only load the surface for partial updates. For newly allocated texture - * the texture wouldn't be the current location, and we'd upload zeroes - * just to overwrite them again. */ - update_w = src_rect->right - src_rect->left; - update_h = src_rect->bottom - src_rect->top; - dst_level = dst_sub_resource_idx % dst_texture->level_count; - if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level) - && update_h == wined3d_texture_get_level_height(dst_texture, dst_level)) - wined3d_texture_prepare_texture(dst_texture, context, FALSE); - else - wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - - src_level = src_sub_resource_idx % src_texture->level_count; - wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, - src_texture->sub_resources[src_sub_resource_idx].locations); - wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); - - wined3d_surface_upload_data(dst_surface, gl_info, src_texture->resource.format, src_rect, - src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); - - context_release(context); - - wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); - - return WINED3D_OK; + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); } -/* In D3D the depth stencil dimensions have to be greater than or equal to the - * render target dimensions. With FBOs, the dimensions have to be an exact match. */ -/* TODO: We should synchronize the renderbuffer's content with the texture's content. */ -/* Context activation is done by the caller. */ -void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt) +static void convert_dxt1_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - unsigned int sub_resource_idx, width, height, level; - struct wined3d_renderbuffer_entry *entry; - const struct wined3d_texture *texture; - const struct wined3d_gl_info *gl_info; - unsigned int src_width, src_height; - GLuint renderbuffer = 0; - - texture = surface->container; - gl_info = &texture->resource.device->adapter->gl_info; - sub_resource_idx = surface_get_sub_resource_idx(surface); - level = sub_resource_idx % texture->level_count; - - if (rt && rt->resource->format->id != WINED3DFMT_NULL) - { - struct wined3d_texture *rt_texture; - unsigned int rt_level; - - if (rt->resource->type == WINED3D_RTYPE_BUFFER) - { - FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type)); - return; - } - rt_texture = wined3d_texture_from_resource(rt->resource); - rt_level = rt->sub_resource_idx % rt_texture->level_count; - - width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level); - height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level); - } - else - { - width = wined3d_texture_get_level_pow2_width(texture, level); - height = wined3d_texture_get_level_pow2_height(texture, level); - } - - src_width = wined3d_texture_get_level_pow2_width(texture, level); - src_height = wined3d_texture_get_level_pow2_height(texture, level); - - /* A depth stencil smaller than the render target is not valid */ - if (width > src_width || height > src_height) return; - - /* Remove any renderbuffer set if the sizes match */ - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] - || (width == src_width && height == src_height)) - { - surface->current_renderbuffer = NULL; - return; - } - - /* Look if we've already got a renderbuffer of the correct dimensions */ - LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - if (entry->width == width && entry->height == height) - { - renderbuffer = entry->id; - surface->current_renderbuffer = entry; - break; - } - } - - if (!renderbuffer) - { - gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, - texture->resource.format->glInternal, width, height); - - entry = heap_alloc(sizeof(*entry)); - entry->width = width; - entry->height = height; - entry->id = renderbuffer; - list_add_head(&surface->renderbuffers, &entry->entry); - - surface->current_renderbuffer = entry; - } - - checkGLcall("set_compatible_renderbuffer"); + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); } -/* See also float_16_to_32() in wined3d_private.h */ -static inline unsigned short float_32_to_16(const float *in) +static void convert_dxt1_a4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - int exp = 0; - float tmp = fabsf(*in); - unsigned int mantissa; - unsigned short ret; - - /* Deal with special numbers */ - if (*in == 0.0f) - return 0x0000; - if (isnan(*in)) - return 0x7c01; - if (isinf(*in)) - return (*in < 0.0f ? 0xfc00 : 0x7c00); - - if (tmp < (float)(1u << 10)) - { - do - { - tmp = tmp * 2.0f; - exp--; - } while (tmp < (float)(1u << 10)); - } - else if (tmp >= (float)(1u << 11)) - { - do - { - tmp /= 2.0f; - exp++; - } while (tmp >= (float)(1u << 11)); - } - - mantissa = (unsigned int)tmp; - if (tmp - mantissa >= 0.5f) - ++mantissa; /* Round to nearest, away from zero. */ - - exp += 10; /* Normalize the mantissa. */ - exp += 15; /* Exponent is encoded with excess 15. */ - - if (exp > 30) /* too big */ - { - ret = 0x7c00; /* INF */ - } - else if (exp <= 0) - { - /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */ - while (exp <= 0) - { - mantissa = mantissa >> 1; - ++exp; - } - ret = mantissa & 0x3ff; - } - else - { - ret = (exp << 10) | (mantissa & 0x3ff); - } - - ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */ - return ret; + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h); } -static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst, +static void convert_dxt1_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - unsigned short *dst_s; - const float *src_f; - unsigned int x, y; - - TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - - for (y = 0; y < h; ++y) - { - src_f = (const float *)(src + y * pitch_in); - dst_s = (unsigned short *) (dst + y * pitch_out); - for (x = 0; x < w; ++x) - { - dst_s[x] = float_32_to_16(src_f + x); - } - } + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h); } -static void convert_r5g6b5_x8r8g8b8(const BYTE *src, BYTE *dst, +static void convert_dxt1_a1r5g5b5(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - static const unsigned char convert_5to8[] = - { - 0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a, - 0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b, - 0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd, - 0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff, - }; - static const unsigned char convert_6to8[] = - { - 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, - 0x20, 0x24, 0x28, 0x2d, 0x31, 0x35, 0x39, 0x3d, - 0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d, - 0x61, 0x65, 0x69, 0x6d, 0x71, 0x75, 0x79, 0x7d, - 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e, - 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe, - 0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd7, 0xdb, 0xdf, - 0xe3, 0xe7, 0xeb, 0xef, 0xf3, 0xf7, 0xfb, 0xff, - }; - unsigned int x, y; - - TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - - for (y = 0; y < h; ++y) - { - const WORD *src_line = (const WORD *)(src + y * pitch_in); - DWORD *dst_line = (DWORD *)(dst + y * pitch_out); - for (x = 0; x < w; ++x) - { - WORD pixel = src_line[x]; - dst_line[x] = 0xff000000u - | convert_5to8[(pixel & 0xf800u) >> 11] << 16 - | convert_6to8[(pixel & 0x07e0u) >> 5] << 8 - | convert_5to8[(pixel & 0x001fu)]; - } - } -} - -/* We use this for both B8G8R8A8 -> B8G8R8X8 and B8G8R8X8 -> B8G8R8A8, since - * in both cases we're just setting the X / Alpha channel to 0xff. */ -static void convert_a8r8g8b8_x8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - unsigned int x, y; - - TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - - for (y = 0; y < h; ++y) - { - const DWORD *src_line = (const DWORD *)(src + y * pitch_in); - DWORD *dst_line = (DWORD *)(dst + y * pitch_out); - - for (x = 0; x < w; ++x) - { - dst_line[x] = 0xff000000 | (src_line[x] & 0xffffff); - } - } -} - -static inline BYTE cliptobyte(int x) -{ - return (BYTE)((x < 0) ? 0 : ((x > 255) ? 255 : x)); -} - -static void convert_yuy2_x8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - int c2, d, e, r2 = 0, g2 = 0, b2 = 0; - unsigned int x, y; - - TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - - for (y = 0; y < h; ++y) - { - const BYTE *src_line = src + y * pitch_in; - DWORD *dst_line = (DWORD *)(dst + y * pitch_out); - for (x = 0; x < w; ++x) - { - /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV: - * C = Y - 16; D = U - 128; E = V - 128; - * R = cliptobyte((298 * C + 409 * E + 128) >> 8); - * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8); - * B = cliptobyte((298 * C + 516 * D + 128) >> 8); - * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V . - * U and V are shared between the pixels. */ - if (!(x & 1)) /* For every even pixel, read new U and V. */ - { - d = (int) src_line[1] - 128; - e = (int) src_line[3] - 128; - r2 = 409 * e + 128; - g2 = - 100 * d - 208 * e + 128; - b2 = 516 * d + 128; - } - c2 = 298 * ((int) src_line[0] - 16); - dst_line[x] = 0xff000000 - | cliptobyte((c2 + r2) >> 8) << 16 /* red */ - | cliptobyte((c2 + g2) >> 8) << 8 /* green */ - | cliptobyte((c2 + b2) >> 8); /* blue */ - /* Scale RGB values to 0..255 range, - * then clip them if still not in range (may be negative), - * then shift them within DWORD if necessary. */ - src_line += 2; - } - } -} - -static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - unsigned int x, y; - int c2, d, e, r2 = 0, g2 = 0, b2 = 0; - - TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out); - - for (y = 0; y < h; ++y) - { - const BYTE *src_line = src + y * pitch_in; - WORD *dst_line = (WORD *)(dst + y * pitch_out); - for (x = 0; x < w; ++x) - { - /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV: - * C = Y - 16; D = U - 128; E = V - 128; - * R = cliptobyte((298 * C + 409 * E + 128) >> 8); - * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8); - * B = cliptobyte((298 * C + 516 * D + 128) >> 8); - * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V . - * U and V are shared between the pixels. */ - if (!(x & 1)) /* For every even pixel, read new U and V. */ - { - d = (int) src_line[1] - 128; - e = (int) src_line[3] - 128; - r2 = 409 * e + 128; - g2 = - 100 * d - 208 * e + 128; - b2 = 516 * d + 128; - } - c2 = 298 * ((int) src_line[0] - 16); - dst_line[x] = (cliptobyte((c2 + r2) >> 8) >> 3) << 11 /* red */ - | (cliptobyte((c2 + g2) >> 8) >> 2) << 5 /* green */ - | (cliptobyte((c2 + b2) >> 8) >> 3); /* blue */ - /* Scale RGB values to 0..255 range, - * then clip them if still not in range (may be negative), - * then shift them within DWORD if necessary. */ - src_line += 2; - } - } -} - -static void convert_dxt1_a8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); -} - -static void convert_dxt1_x8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); -} - -static void convert_dxt1_a4r4g4b4(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h); -} - -static void convert_dxt1_x4r4g4b4(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h); -} - -static void convert_dxt1_a1r5g5b5(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h); -} - -static void convert_dxt1_x1r5g5b5(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h); -} - -static void convert_dxt3_a8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); -} - -static void convert_dxt3_x8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); -} - -static void convert_dxt3_a4r4g4b4(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h); -} - -static void convert_dxt3_x4r4g4b4(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h); -} - -static void convert_dxt5_a8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); -} - -static void convert_dxt5_x8r8g8b8(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); -} - -static void convert_a8r8g8b8_dxt1(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); -} - -static void convert_x8r8g8b8_dxt1(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); -} - -static void convert_a1r5g5b5_dxt1(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h); -} - -static void convert_x1r5g5b5_dxt1(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h); -} - -static void convert_a8r8g8b8_dxt3(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); -} - -static void convert_x8r8g8b8_dxt3(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); -} - -static void convert_a8r8g8b8_dxt5(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); -} - -static void convert_x8r8g8b8_dxt5(const BYTE *src, BYTE *dst, - DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) -{ - wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); -} - -struct d3dfmt_converter_desc -{ - enum wined3d_format_id from, to; - void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h); -}; - -static const struct d3dfmt_converter_desc converters[] = -{ - {WINED3DFMT_R32_FLOAT, WINED3DFMT_R16_FLOAT, convert_r32_float_r16_float}, - {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_r5g6b5_x8r8g8b8}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_a8r8g8b8_x8r8g8b8}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8A8_UNORM, convert_a8r8g8b8_x8r8g8b8}, - {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8}, - {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5}, -}; - -static const struct d3dfmt_converter_desc dxtn_converters[] = -{ - /* decode DXT */ - {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt1_a8r8g8b8}, - {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt1_x8r8g8b8}, - {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt1_a4r4g4b4}, - {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt1_x4r4g4b4}, - {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5A1_UNORM, convert_dxt1_a1r5g5b5}, - {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5X1_UNORM, convert_dxt1_x1r5g5b5}, - {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt3_a8r8g8b8}, - {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt3_x8r8g8b8}, - {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt3_a4r4g4b4}, - {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt3_x4r4g4b4}, - {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt5_a8r8g8b8}, - {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt5_x8r8g8b8}, - - /* encode DXT */ - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT1, convert_a8r8g8b8_dxt1}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT1, convert_x8r8g8b8_dxt1}, - {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_DXT1, convert_a1r5g5b5_dxt1}, - {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_DXT1, convert_x1r5g5b5_dxt1}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT3, convert_a8r8g8b8_dxt3}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT3, convert_x8r8g8b8_dxt3}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT5, convert_a8r8g8b8_dxt5}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT5, convert_x8r8g8b8_dxt5} -}; - -static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from, - enum wined3d_format_id to) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(converters); ++i) - { - if (converters[i].from == from && converters[i].to == to) - return &converters[i]; - } - - for (i = 0; i < (sizeof(dxtn_converters) / sizeof(*dxtn_converters)); ++i) - { - if (dxtn_converters[i].from == from && dxtn_converters[i].to == to) - return wined3d_dxtn_supported() ? &dxtn_converters[i] : NULL; - } - - return NULL; -} - -static struct wined3d_texture *surface_convert_format(struct wined3d_texture *src_texture, - unsigned int sub_resource_idx, const struct wined3d_format *dst_format) -{ - unsigned int texture_level = sub_resource_idx % src_texture->level_count; - const struct wined3d_format *src_format = src_texture->resource.format; - struct wined3d_device *device = src_texture->resource.device; - const struct d3dfmt_converter_desc *conv = NULL; - const struct wined3d_gl_info *gl_info = NULL; - unsigned int src_row_pitch, src_slice_pitch; - struct wined3d_context *context = NULL; - struct wined3d_texture *dst_texture; - struct wined3d_bo_address src_data; - struct wined3d_resource_desc desc; - DWORD map_binding; - - if (!(conv = find_converter(src_format->id, dst_format->id)) && (!device->d3d_initialized - || !is_identity_fixup(src_format->color_fixup) || src_format->conv_byte_count - || !is_identity_fixup(dst_format->color_fixup) || dst_format->conv_byte_count - || (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED))) - { - FIXME("Cannot find a conversion function from format %s to %s.\n", - debug_d3dformat(src_format->id), debug_d3dformat(dst_format->id)); - return NULL; - } - - /* FIXME: Multisampled conversion? */ - desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = dst_format->id; - desc.multisample_type = WINED3D_MULTISAMPLE_NONE; - desc.multisample_quality = 0; - desc.usage = WINED3DUSAGE_SCRATCH | WINED3DUSAGE_PRIVATE; - desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - desc.width = wined3d_texture_get_level_width(src_texture, texture_level); - desc.height = wined3d_texture_get_level_height(src_texture, texture_level); - desc.depth = 1; - desc.size = 0; - if (FAILED(wined3d_texture_create(device, &desc, 1, 1, - WINED3D_TEXTURE_CREATE_MAPPABLE | WINED3D_TEXTURE_CREATE_DISCARD, - NULL, NULL, &wined3d_null_parent_ops, &dst_texture))) - { - ERR("Failed to create a destination texture for conversion.\n"); - return NULL; - } - - if (device->d3d_initialized) - { - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; - } - - map_binding = src_texture->resource.map_binding; - if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding)) - ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); - wined3d_texture_get_pitch(src_texture, texture_level, &src_row_pitch, &src_slice_pitch); - wined3d_texture_get_memory(src_texture, sub_resource_idx, &src_data, map_binding); - - if (conv) - { - unsigned int dst_row_pitch, dst_slice_pitch; - struct wined3d_bo_address dst_data; - const BYTE *src; - BYTE *dst; - - map_binding = dst_texture->resource.map_binding; - if (!wined3d_texture_load_location(dst_texture, 0, context, map_binding)) - ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); - wined3d_texture_get_pitch(dst_texture, 0, &dst_row_pitch, &dst_slice_pitch); - wined3d_texture_get_memory(dst_texture, 0, &dst_data, map_binding); - - src = context_map_bo_address(context, &src_data, - src_texture->sub_resources[sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); - dst = context_map_bo_address(context, - &dst_data, dst_texture->sub_resources[0].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_WRITE); - - conv->convert(src, dst, src_row_pitch, dst_row_pitch, desc.width, desc.height); - - wined3d_texture_invalidate_location(dst_texture, 0, ~map_binding); - context_unmap_bo_address(context, &dst_data, GL_PIXEL_UNPACK_BUFFER); - context_unmap_bo_address(context, &src_data, GL_PIXEL_UNPACK_BUFFER); - } - else - { - RECT src_rect = {0, 0, desc.width, desc.height}; - POINT dst_point = {0, 0}; - - TRACE("Using upload conversion.\n"); - - wined3d_texture_prepare_texture(dst_texture, context, FALSE); - wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - wined3d_surface_upload_data(dst_texture->sub_resources[0].u.surface, gl_info, src_format, - &src_rect, src_row_pitch, &dst_point, FALSE, wined3d_const_bo_address(&src_data)); - - wined3d_texture_validate_location(dst_texture, 0, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(dst_texture, 0, ~WINED3D_LOCATION_TEXTURE_RGB); - } - - if (context) - context_release(context); - - return dst_texture; -} - -static void read_from_framebuffer(struct wined3d_surface *surface, - struct wined3d_context *old_ctx, DWORD src_location, DWORD dst_location) -{ - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - struct wined3d_texture *texture = surface->container; - struct wined3d_device *device = texture->resource.device; - struct wined3d_context *context = old_ctx; - struct wined3d_surface *restore_rt = NULL; - const struct wined3d_gl_info *gl_info; - unsigned int row_pitch, slice_pitch; - unsigned int width, height, level; - struct wined3d_bo_address data; - BYTE *row, *top, *bottom; - BOOL src_is_upside_down; - unsigned int i; - BYTE *mem; - - wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); - - restore_rt = context_get_rt_surface(old_ctx); - if (restore_rt != surface) - context = context_acquire(device, texture, sub_resource_idx); - else - restore_rt = NULL; - gl_info = context->gl_info; - - if (src_location != texture->resource.draw_binding) - { - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, surface, NULL, src_location); - context_check_fbo_status(context, GL_READ_FRAMEBUFFER); - context_invalidate_state(context, STATE_FRAMEBUFFER); - } - else - { - context_apply_blit_state(context, device); - } - - /* Select the correct read buffer, and give some debug output. - * There is no need to keep track of the current read buffer or reset it, - * every part of the code that reads sets the read buffer as desired. - */ - if (src_location != WINED3D_LOCATION_DRAWABLE || wined3d_resource_is_offscreen(&texture->resource)) - { - /* Mapping the primary render target which is not on a swapchain. - * Read from the back buffer. */ - TRACE("Mapping offscreen render target.\n"); - gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); - src_is_upside_down = TRUE; - } - else - { - /* Onscreen surfaces are always part of a swapchain */ - GLenum buffer = wined3d_texture_get_gl_buffer(texture); - TRACE("Mapping %#x buffer.\n", buffer); - gl_info->gl_ops.gl.p_glReadBuffer(buffer); - src_is_upside_down = FALSE; - } - checkGLcall("glReadBuffer"); - - if (data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); - checkGLcall("glBindBuffer"); - } - - level = sub_resource_idx % texture->level_count; - wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); - - /* Setup pixel store pack state -- to glReadPixels into the correct place */ - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / texture->resource.format->byte_count); - checkGLcall("glPixelStorei"); - - width = wined3d_texture_get_level_width(texture, level); - height = wined3d_texture_get_level_height(texture, level); - gl_info->gl_ops.gl.p_glReadPixels(0, 0, width, height, - texture->resource.format->glFormat, - texture->resource.format->glType, data.addr); - checkGLcall("glReadPixels"); - - /* Reset previous pixel store pack state */ - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, 0); - checkGLcall("glPixelStorei"); - - if (!src_is_upside_down) - { - /* glReadPixels returns the image upside down, and there is no way to - * prevent this. Flip the lines in software. */ - - if (!(row = heap_alloc(row_pitch))) - goto error; - - if (data.buffer_object) - { - mem = GL_EXTCALL(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE)); - checkGLcall("glMapBuffer"); - } - else - mem = data.addr; - - top = mem; - bottom = mem + row_pitch * (height - 1); - for (i = 0; i < height / 2; i++) - { - memcpy(row, top, row_pitch); - memcpy(top, bottom, row_pitch); - memcpy(bottom, row, row_pitch); - top += row_pitch; - bottom -= row_pitch; - } - heap_free(row); - - if (data.buffer_object) - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER)); - } - -error: - if (data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - - if (restore_rt) - context_restore(context, restore_rt); -} - -/* Read the framebuffer contents into a texture. Note that this function - * doesn't do any kind of flipping. Using this on an onscreen surface will - * result in a flipped D3D texture. - * - * Context activation is done by the caller. This function may temporarily - * switch to a different context and restore the original one before return. */ -void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx) -{ - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - struct wined3d_texture *texture = surface->container; - struct wined3d_device *device = texture->resource.device; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context = old_ctx; - struct wined3d_surface *restore_rt = NULL; - unsigned int level; - GLenum target; - - restore_rt = context_get_rt_surface(old_ctx); - if (restore_rt != surface) - context = context_acquire(device, texture, sub_resource_idx); - else - restore_rt = NULL; - - gl_info = context->gl_info; - device_invalidate_state(device, STATE_FRAMEBUFFER); - - wined3d_texture_prepare_texture(texture, context, srgb); - wined3d_texture_bind_and_dirtify(texture, context, srgb); - - TRACE("Reading back offscreen render target %p.\n", surface); - - if (wined3d_resource_is_offscreen(&texture->resource)) - gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); - else - gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(texture)); - checkGLcall("glReadBuffer"); - - level = sub_resource_idx % texture->level_count; - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(target, level, 0, 0, 0, 0, - wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level)); - checkGLcall("glCopyTexSubImage2D"); - - if (restore_rt) - context_restore(context, restore_rt); -} - -/* Does a direct frame buffer -> texture copy. Stretching is done with single - * pixel copy calls. */ -static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface, - const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) -{ - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - struct wined3d_texture *src_texture = src_surface->container; - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_device *device = dst_texture->resource.device; - unsigned int src_height, src_level, dst_level; - const struct wined3d_gl_info *gl_info; - float xrel, yrel; - struct wined3d_context *context; - BOOL upsidedown = FALSE; - RECT dst_rect = *dst_rect_in; - GLenum dst_target; - - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag - * glCopyTexSubImage is a bit picky about the parameters we pass to it - */ - if(dst_rect.top > dst_rect.bottom) { - UINT tmp = dst_rect.bottom; - dst_rect.bottom = dst_rect.top; - dst_rect.top = tmp; - upsidedown = TRUE; - } - - context = context_acquire(device, src_texture, src_sub_resource_idx); - gl_info = context->gl_info; - context_apply_blit_state(context, device); - wined3d_texture_load(dst_texture, context, FALSE); - - /* Bind the target texture */ - context_bind_texture(context, dst_texture->target, dst_texture->texture_rgb.name); - if (wined3d_resource_is_offscreen(&src_texture->resource)) - { - TRACE("Reading from an offscreen target\n"); - upsidedown = !upsidedown; - gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); - } - else - { - gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(src_texture)); - } - checkGLcall("glReadBuffer"); - - xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left); - yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top); - - if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) - { - FIXME_(d3d_perf)("Doing a pixel by pixel copy from the framebuffer to a texture.\n"); - - if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT) - ERR("Texture filtering not supported in direct blit.\n"); - } - else if ((filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT) - && ((yrel - 1.0f < -eps) || (yrel - 1.0f > eps))) - { - ERR("Texture filtering not supported in direct blit\n"); - } - - src_level = src_sub_resource_idx % src_texture->level_count; - dst_level = dst_sub_resource_idx % dst_texture->level_count; - - src_height = wined3d_texture_get_level_height(src_texture, src_level); - dst_target = wined3d_texture_get_sub_resource_target(dst_texture, dst_sub_resource_idx); - if (upsidedown - && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) - && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps))) - { - /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do. */ - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level, - dst_rect.left /*xoffset */, dst_rect.top /* y offset */, - src_rect->left, src_height - src_rect->bottom, - dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); - } - else - { - LONG row; - UINT yoffset = src_height - src_rect->top + dst_rect.top - 1; - /* I have to process this row by row to swap the image, - * otherwise it would be upside down, so stretching in y direction - * doesn't cost extra time - * - * However, stretching in x direction can be avoided if not necessary - */ - for(row = dst_rect.top; row < dst_rect.bottom; row++) { - if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) - { - /* Well, that stuff works, but it's very slow. - * find a better way instead - */ - LONG col; - - for (col = dst_rect.left; col < dst_rect.right; ++col) - { - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level, - dst_rect.left + col /* x offset */, row /* y offset */, - src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1); - } - } - else - { - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level, - dst_rect.left /* x offset */, row /* y offset */, - src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1); - } - } - } - checkGLcall("glCopyTexSubImage2D"); - - context_release(context); - - /* The texture is now most up to date - If the surface is a render target - * and has a drawable, this path is never entered. */ - wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); -} - -/* Uses the hardware to stretch and flip the image */ -static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface, - const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) -{ - unsigned int src_width, src_height, src_pow2_width, src_pow2_height, src_level; - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - struct wined3d_texture *src_texture = src_surface->container; - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_device *device = dst_texture->resource.device; - GLenum src_target, dst_target, texture_target; - GLuint src, backup = 0; - float left, right, top, bottom; /* Texture coordinates */ - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - GLenum drawBuffer = GL_BACK; - GLenum offscreen_buffer; - BOOL noBackBufferBackup; - BOOL src_offscreen; - BOOL upsidedown = FALSE; - RECT dst_rect = *dst_rect_in; - - TRACE("Using hwstretch blit\n"); - - src_target = wined3d_texture_get_sub_resource_target(src_texture, src_sub_resource_idx); - dst_target = wined3d_texture_get_sub_resource_target(dst_texture, dst_sub_resource_idx); - - /* Activate the Proper context for reading from the source surface, set it up for blitting */ - context = context_acquire(device, src_texture, src_sub_resource_idx); - gl_info = context->gl_info; - context_apply_blit_state(context, device); - wined3d_texture_load(dst_texture, context, FALSE); - - offscreen_buffer = context_get_offscreen_gl_buffer(context); - src_level = src_sub_resource_idx % src_texture->level_count; - src_width = wined3d_texture_get_level_width(src_texture, src_level); - src_height = wined3d_texture_get_level_height(src_texture, src_level); - src_pow2_width = wined3d_texture_get_level_pow2_width(src_texture, src_level); - src_pow2_height = wined3d_texture_get_level_pow2_height(src_texture, src_level); - - src_offscreen = wined3d_resource_is_offscreen(&src_texture->resource); - noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO; - if (!noBackBufferBackup && !src_texture->texture_rgb.name) - { - /* Get it a description */ - wined3d_texture_load(src_texture, context, FALSE); - } - - /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring. - * This way we don't have to wait for the 2nd readback to finish to leave this function. - */ - if (context->aux_buffers >= 2) - { - /* Got more than one aux buffer? Use the 2nd aux buffer */ - drawBuffer = GL_AUX1; - } - else if ((!src_offscreen || offscreen_buffer == GL_BACK) && context->aux_buffers >= 1) - { - /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */ - drawBuffer = GL_AUX0; - } - - if (noBackBufferBackup) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &backup); - checkGLcall("glGenTextures"); - context_bind_texture(context, GL_TEXTURE_2D, backup); - texture_target = GL_TEXTURE_2D; - } - else - { - /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If - * we are reading from the back buffer, the backup can be used as source texture - */ - texture_target = src_target; - context_bind_texture(context, texture_target, src_texture->texture_rgb.name); - gl_info->gl_ops.gl.p_glEnable(texture_target); - checkGLcall("glEnable(texture_target)"); - - /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ - surface_get_sub_resource(src_surface)->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; - } - - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag - * glCopyTexSubImage is a bit picky about the parameters we pass to it - */ - if(dst_rect.top > dst_rect.bottom) { - UINT tmp = dst_rect.bottom; - dst_rect.bottom = dst_rect.top; - dst_rect.top = tmp; - upsidedown = TRUE; - } - - if (src_offscreen) - { - TRACE("Reading from an offscreen target\n"); - upsidedown = !upsidedown; - gl_info->gl_ops.gl.p_glReadBuffer(offscreen_buffer); - } - else - { - gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(src_texture)); - } - - /* TODO: Only back up the part that will be overwritten */ - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, 0, 0, 0, 0, src_width, src_height); - - checkGLcall("glCopyTexSubImage2D"); - - /* No issue with overriding these - the sampler is dirty due to blit usage */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); - checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); - checkGLcall("glTexParameteri"); - - if (!src_texture->swapchain || src_texture == src_texture->swapchain->back_buffers[0]) - { - src = backup ? backup : src_texture->texture_rgb.name; - } - else - { - gl_info->gl_ops.gl.p_glReadBuffer(GL_FRONT); - checkGLcall("glReadBuffer(GL_FRONT)"); - - gl_info->gl_ops.gl.p_glGenTextures(1, &src); - checkGLcall("glGenTextures(1, &src)"); - context_bind_texture(context, GL_TEXTURE_2D, src); - - /* TODO: Only copy the part that will be read. Use src_rect->left, - * src_rect->bottom as origin, but with the width watch out for power - * of 2 sizes. */ - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_pow2_width, - src_pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - checkGLcall("glTexImage2D"); - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, src_width, src_height); - - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - - gl_info->gl_ops.gl.p_glReadBuffer(GL_BACK); - checkGLcall("glReadBuffer(GL_BACK)"); - - if (texture_target != GL_TEXTURE_2D) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); - texture_target = GL_TEXTURE_2D; - } - } - checkGLcall("glEnd and previous"); - - left = src_rect->left; - right = src_rect->right; - - if (!upsidedown) - { - top = src_height - src_rect->top; - bottom = src_height - src_rect->bottom; - } - else - { - top = src_height - src_rect->bottom; - bottom = src_height - src_rect->top; - } - - if (src_texture->flags & WINED3D_TEXTURE_NORMALIZED_COORDS) - { - left /= src_pow2_width; - right /= src_pow2_width; - top /= src_pow2_height; - bottom /= src_pow2_height; - } - - /* draw the source texture stretched and upside down. The correct surface is bound already */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - context_set_draw_buffer(context, drawBuffer); - gl_info->gl_ops.gl.p_glReadBuffer(drawBuffer); - - gl_info->gl_ops.gl.p_glBegin(GL_QUADS); - /* bottom left */ - gl_info->gl_ops.gl.p_glTexCoord2f(left, bottom); - gl_info->gl_ops.gl.p_glVertex2i(0, 0); - - /* top left */ - gl_info->gl_ops.gl.p_glTexCoord2f(left, top); - gl_info->gl_ops.gl.p_glVertex2i(0, dst_rect.bottom - dst_rect.top); - - /* top right */ - gl_info->gl_ops.gl.p_glTexCoord2f(right, top); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); - - /* bottom right */ - gl_info->gl_ops.gl.p_glTexCoord2f(right, bottom); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect.right - dst_rect.left, 0); - gl_info->gl_ops.gl.p_glEnd(); - checkGLcall("glEnd and previous"); - - if (texture_target != dst_target) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(dst_target); - texture_target = dst_target; - } - - /* Now read the stretched and upside down image into the destination texture */ - context_bind_texture(context, texture_target, dst_texture->texture_rgb.name); - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, - 0, - dst_rect.left, dst_rect.top, /* xoffset, yoffset */ - 0, 0, /* We blitted the image to the origin */ - dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); - checkGLcall("glCopyTexSubImage2D"); - - if (drawBuffer == GL_BACK) - { - /* Write the back buffer backup back. */ - if (backup) - { - if (texture_target != GL_TEXTURE_2D) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); - texture_target = GL_TEXTURE_2D; - } - context_bind_texture(context, GL_TEXTURE_2D, backup); - } - else - { - if (texture_target != src_target) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(src_target); - texture_target = src_target; - } - context_bind_texture(context, src_target, src_texture->texture_rgb.name); - } - - gl_info->gl_ops.gl.p_glBegin(GL_QUADS); - /* top left */ - gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, 0.0f); - gl_info->gl_ops.gl.p_glVertex2i(0, src_height); + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h); +} - /* bottom left */ - gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, (float)src_height / (float)src_pow2_height); - gl_info->gl_ops.gl.p_glVertex2i(0, 0); +static void convert_dxt1_x1r5g5b5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h); +} - /* bottom right */ - gl_info->gl_ops.gl.p_glTexCoord2f((float)src_width / (float)src_pow2_width, - (float)src_height / (float)src_pow2_height); - gl_info->gl_ops.gl.p_glVertex2i(src_width, 0); +static void convert_dxt3_a8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} - /* top right */ - gl_info->gl_ops.gl.p_glTexCoord2f((float)src_width / (float)src_pow2_width, 0.0f); - gl_info->gl_ops.gl.p_glVertex2i(src_width, src_height); - gl_info->gl_ops.gl.p_glEnd(); - } - gl_info->gl_ops.gl.p_glDisable(texture_target); - checkGLcall("glDisable(texture_target)"); +static void convert_dxt3_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} - /* Cleanup */ - if (src != src_texture->texture_rgb.name && src != backup) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &src); - checkGLcall("glDeleteTextures(1, &src)"); - } - if (backup) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &backup); - checkGLcall("glDeleteTextures(1, &backup)"); - } +static void convert_dxt3_a4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h); +} - if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ +static void convert_dxt3_x4r4g4b4(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h); +} - context_release(context); +static void convert_dxt5_a8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} - /* The texture is now most up to date - If the surface is a render target - * and has a drawable, this path is never entered. */ - wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); +static void convert_dxt5_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); } -/* Front buffer coordinates are always full screen coordinates, but our GL - * drawable is limited to the window's client area. The sysmem and texture - * copies do have the full screen size. Note that GL has a bottom-left - * origin, while D3D has a top-left origin. */ -void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) +static void convert_a8r8g8b8_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - struct wined3d_texture *texture = surface->container; - POINT offset = {0, 0}; - UINT drawable_height; - RECT windowsize; + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} - if (!texture->swapchain) - return; +static void convert_x8r8g8b8_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} - if (texture == texture->swapchain->front_buffer) - { - ScreenToClient(window, &offset); - OffsetRect(rect, offset.x, offset.y); - } +static void convert_a1r5g5b5_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h); +} - GetClientRect(window, &windowsize); - drawable_height = windowsize.bottom - windowsize.top; +static void convert_x1r5g5b5_dxt1(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt1_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h); +} - rect->top = drawable_height - rect->top; - rect->bottom = drawable_height - rect->bottom; +static void convert_a8r8g8b8_dxt3(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); } -static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +static void convert_x8r8g8b8_dxt3(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_device *device = dst_texture->resource.device; - const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - struct wined3d_texture *src_texture; + wined3d_dxt3_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), - flags, fx, debug_d3dtexturefiltertype(filter)); +static void convert_a8r8g8b8_dxt5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8A8_UNORM, w, h); +} - /* Get the swapchain. One of the surfaces has to be a primary surface. */ - if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - WARN("Destination resource is not GPU accessible, rejecting GL blit.\n"); - return WINED3DERR_INVALIDCALL; - } +static void convert_x8r8g8b8_dxt5(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); +} +#ifdef __REACTOS__ +#else +static void convert_x8r8g8b8_l8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + unsigned int x, y; - dst_swapchain = dst_texture->swapchain; + TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); - if (src_surface) + for (y = 0; y < h; ++y) { - src_texture = src_surface->container; - if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) + const DWORD *src_line = (const DWORD *)(src + y * pitch_in); + BYTE *dst_line = (BYTE *)(dst + y * pitch_out); + + for (x = 0; x < w; ++x) { - WARN("Source resource is not GPU accessible, rejecting GL blit.\n"); - return WINED3DERR_INVALIDCALL; + dst_line[x] = src_line[x] & 0x000000ff; } - - src_swapchain = src_texture->swapchain; - } - else - { - src_texture = NULL; - src_swapchain = NULL; } +} +#endif - /* Early sort out of cases where no render target is used */ - if (!dst_swapchain && !src_swapchain && src_surface != rt && dst_surface != rt) - { - TRACE("No surface is render target, not using hardware blit.\n"); - return WINED3DERR_INVALIDCALL; - } +struct d3dfmt_converter_desc +{ + enum wined3d_format_id from, to; + void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h); +}; - /* No destination color keying supported */ - if (flags & (WINED3D_BLT_DST_CKEY | WINED3D_BLT_DST_CKEY_OVERRIDE)) - { - /* Can we support that with glBlendFunc if blitting to the frame buffer? */ - TRACE("Destination color key not supported in accelerated Blit, falling back to software\n"); - return WINED3DERR_INVALIDCALL; - } +static const struct d3dfmt_converter_desc converters[] = +{ + {WINED3DFMT_R32_FLOAT, WINED3DFMT_R16_FLOAT, convert_r32_float_r16_float}, + {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_r5g6b5_x8r8g8b8}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_a8r8g8b8_x8r8g8b8}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8A8_UNORM, convert_a8r8g8b8_x8r8g8b8}, + {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8}, + {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5}, +}; - if (dst_swapchain && dst_swapchain == src_swapchain) - { - FIXME("Implement hardware blit between two surfaces on the same swapchain\n"); - return WINED3DERR_INVALIDCALL; - } +static const struct d3dfmt_converter_desc dxtn_converters[] = +{ + /* decode DXT */ + {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt1_a8r8g8b8}, + {WINED3DFMT_DXT1, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt1_x8r8g8b8}, + {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt1_a4r4g4b4}, + {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt1_x4r4g4b4}, + {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5A1_UNORM, convert_dxt1_a1r5g5b5}, + {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5X1_UNORM, convert_dxt1_x1r5g5b5}, + {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt3_a8r8g8b8}, + {WINED3DFMT_DXT3, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt3_x8r8g8b8}, + {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt3_a4r4g4b4}, + {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt3_x4r4g4b4}, + {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt5_a8r8g8b8}, + {WINED3DFMT_DXT5, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt5_x8r8g8b8}, - if (dst_swapchain && src_swapchain) - { - FIXME("Implement hardware blit between two different swapchains\n"); - return WINED3DERR_INVALIDCALL; - } + /* encode DXT */ + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT1, convert_a8r8g8b8_dxt1}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT1, convert_x8r8g8b8_dxt1}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_DXT1, convert_a1r5g5b5_dxt1}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_DXT1, convert_x1r5g5b5_dxt1}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT3, convert_a8r8g8b8_dxt3}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT3, convert_x8r8g8b8_dxt3}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_DXT5, convert_a8r8g8b8_dxt5}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_DXT5, convert_x8r8g8b8_dxt5} +}; - if (dst_swapchain) - { - /* Handled with regular texture -> swapchain blit */ - if (src_surface == rt) - TRACE("Blit from active render target to a swapchain\n"); - } - else if (src_swapchain && dst_surface == rt) +static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from, + enum wined3d_format_id to) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(converters); ++i) { - FIXME("Implement blit from a swapchain to the active render target\n"); - return WINED3DERR_INVALIDCALL; + if (converters[i].from == from && converters[i].to == to) + return &converters[i]; } - if ((src_swapchain || src_surface == rt) && !dst_swapchain) + for (i = 0; i < (sizeof(dxtn_converters) / sizeof(*dxtn_converters)); ++i) { - unsigned int src_level, src_width, src_height; - /* Blit from render target to texture */ - BOOL stretchx; - - /* P8 read back is not implemented */ - if (src_texture->resource.format->id == WINED3DFMT_P8_UINT - || dst_texture->resource.format->id == WINED3DFMT_P8_UINT) - { - TRACE("P8 read back not supported by frame buffer to texture blit\n"); - return WINED3DERR_INVALIDCALL; - } - - if (flags & (WINED3D_BLT_SRC_CKEY | WINED3D_BLT_SRC_CKEY_OVERRIDE)) - { - TRACE("Color keying not supported by frame buffer to texture blit\n"); - return WINED3DERR_INVALIDCALL; - /* Destination color key is checked above */ - } - - if (dst_rect->right - dst_rect->left != src_rect->right - src_rect->left) - stretchx = TRUE; - else - stretchx = FALSE; - - /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot - * flip the image nor scale it. - * - * -> If the app asks for an unscaled, upside down copy, just perform one glCopyTexSubImage2D call - * -> If the app wants an image width an unscaled width, copy it line per line - * -> If the app wants an image that is scaled on the x axis, and the destination rectangle is smaller - * than the frame buffer, draw an upside down scaled image onto the fb, read it back and restore the - * back buffer. This is slower than reading line per line, thus not used for flipping - * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied - * pixel by pixel. */ - src_level = surface_get_sub_resource_idx(src_surface) % src_texture->level_count; - src_width = wined3d_texture_get_level_width(src_texture, src_level); - src_height = wined3d_texture_get_level_height(src_texture, src_level); - if (!stretchx || dst_rect->right - dst_rect->left > src_width - || dst_rect->bottom - dst_rect->top > src_height) - { - TRACE("No stretching in x direction, using direct framebuffer -> texture copy.\n"); - fb_copy_to_texture_direct(dst_surface, src_surface, src_rect, dst_rect, filter); - } - else - { - TRACE("Using hardware stretching to flip / stretch the texture.\n"); - fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter); - } - - return WINED3D_OK; + if (dxtn_converters[i].from == from && dxtn_converters[i].to == to) + return wined3d_dxtn_supported() ? &dxtn_converters[i] : NULL; } - /* Default: Fall back to the generic blt. Not an error, a TRACE is enough */ - TRACE("Didn't find any usable render target setup for hw blit, falling back to software\n"); - return WINED3DERR_INVALIDCALL; + return NULL; } -/* Context activation is done by the caller. */ -static BOOL surface_load_sysmem(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD dst_location) +static struct wined3d_texture *surface_convert_format(struct wined3d_texture *src_texture, + unsigned int sub_resource_idx, const struct wined3d_format *dst_format) { - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_texture *texture = surface->container; - struct wined3d_texture_sub_resource *sub_resource; - - sub_resource = &texture->sub_resources[sub_resource_idx]; - wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location); + unsigned int texture_level = sub_resource_idx % src_texture->level_count; + const struct wined3d_format *src_format = src_texture->resource.format; + struct wined3d_device *device = src_texture->resource.device; + const struct d3dfmt_converter_desc *conv = NULL; + unsigned int src_row_pitch, src_slice_pitch; + struct wined3d_texture *dst_texture; + struct wined3d_bo_address src_data; + struct wined3d_resource_desc desc; + struct wined3d_context *context; + DWORD map_binding; - /* We cannot download data from multisample textures directly. */ - if (is_multisample_location(texture, WINED3D_LOCATION_TEXTURE_RGB)) - { - wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_RB_RESOLVED); - read_from_framebuffer(surface, context, WINED3D_LOCATION_RB_RESOLVED, dst_location); - return TRUE; - } - else + if (!(conv = find_converter(src_format->id, dst_format->id)) && (!device->d3d_initialized + || !is_identity_fixup(src_format->color_fixup) || src_format->conv_byte_count + || !is_identity_fixup(dst_format->color_fixup) || dst_format->conv_byte_count + || (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED))) { - if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) - wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); - - /* Download the surface to system memory. */ - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - wined3d_texture_bind_and_dirtify(texture, context, - !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)); - surface_download_data(surface, gl_info, dst_location); - ++texture->download_count; - - return TRUE; - } + FIXME("Cannot find a conversion function from format %s to %s.\n", + debug_d3dformat(src_format->id), debug_d3dformat(dst_format->id)); + return NULL; } - if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) - && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) + /* FIXME: Multisampled conversion? */ + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + desc.format = dst_format->id; + desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + desc.multisample_quality = 0; + desc.usage = WINED3DUSAGE_SCRATCH | WINED3DUSAGE_PRIVATE; + desc.bind_flags = 0; + desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + desc.width = wined3d_texture_get_level_width(src_texture, texture_level); + desc.height = wined3d_texture_get_level_height(src_texture, texture_level); + desc.depth = 1; + desc.size = 0; + if (FAILED(wined3d_texture_create(device, &desc, 1, 1, WINED3D_TEXTURE_CREATE_DISCARD, + NULL, NULL, &wined3d_null_parent_ops, &dst_texture))) { - read_from_framebuffer(surface, context, texture->resource.draw_binding, dst_location); - return TRUE; + ERR("Failed to create a destination texture for conversion.\n"); + return NULL; } - FIXME("Can't load surface %p with location flags %s into sysmem.\n", - surface, wined3d_debug_location(sub_resource->locations)); - return FALSE; -} + context = context_acquire(device, NULL, 0); -/* Context activation is done by the caller. */ -static BOOL surface_load_drawable(struct wined3d_surface *surface, - struct wined3d_context *context) -{ - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - struct wined3d_texture *texture = surface->container; - struct wined3d_surface *restore_rt = NULL; - struct wined3d_device *device; - unsigned int level; - RECT r; + map_binding = src_texture->resource.map_binding; + if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding)) + ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_get_pitch(src_texture, texture_level, &src_row_pitch, &src_slice_pitch); + wined3d_texture_get_memory(src_texture, sub_resource_idx, &src_data, map_binding); - if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + if (conv) { - DWORD current = texture->sub_resources[sub_resource_idx].locations; - FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", - wined3d_debug_location(current)); - return FALSE; - } + unsigned int dst_row_pitch, dst_slice_pitch; + struct wined3d_bo_address dst_data; + struct wined3d_map_range range; + const BYTE *src; + BYTE *dst; - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && wined3d_resource_is_offscreen(&texture->resource)) - { - ERR("Trying to load offscreen surface into WINED3D_LOCATION_DRAWABLE.\n"); - return FALSE; - } + map_binding = dst_texture->resource.map_binding; + if (!wined3d_texture_load_location(dst_texture, 0, context, map_binding)) + ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_get_pitch(dst_texture, 0, &dst_row_pitch, &dst_slice_pitch); + wined3d_texture_get_memory(dst_texture, 0, &dst_data, map_binding); - device = texture->resource.device; - restore_rt = context_get_rt_surface(context); - if (restore_rt != surface) - context = context_acquire(device, texture, sub_resource_idx); + src = wined3d_context_map_bo_address(context, &src_data, + src_texture->sub_resources[sub_resource_idx].size, 0, WINED3D_MAP_READ); + dst = wined3d_context_map_bo_address(context, &dst_data, + dst_texture->sub_resources[0].size, 0, WINED3D_MAP_WRITE); + + conv->convert(src, dst, src_row_pitch, dst_row_pitch, desc.width, desc.height); + + range.offset = 0; + range.size = dst_texture->sub_resources[0].size; + wined3d_texture_invalidate_location(dst_texture, 0, ~map_binding); + wined3d_context_unmap_bo_address(context, &dst_data, 0, 1, &range); + wined3d_context_unmap_bo_address(context, &src_data, 0, 0, NULL); + } else - restore_rt = NULL; + { + struct wined3d_box src_box = {0, 0, desc.width, desc.height, 0, 1}; - level = sub_resource_idx % texture->level_count; - SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level)); - wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); - device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, - surface, WINED3D_LOCATION_TEXTURE_RGB, &r, - surface, WINED3D_LOCATION_DRAWABLE, &r, - NULL, WINED3D_TEXF_POINT); + TRACE("Using upload conversion.\n"); - if (restore_rt) - context_restore(context, restore_rt); + wined3d_texture_prepare_location(dst_texture, 0, context, WINED3D_LOCATION_TEXTURE_RGB); + dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&src_data), + src_format, &src_box, src_row_pitch, src_slice_pitch, + dst_texture, 0, WINED3D_LOCATION_TEXTURE_RGB, 0, 0, 0); - return TRUE; + wined3d_texture_validate_location(dst_texture, 0, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, 0, ~WINED3D_LOCATION_TEXTURE_RGB); + } + + context_release(context); + + return dst_texture; } -static BOOL surface_load_texture(struct wined3d_surface *surface, - struct wined3d_context *context, BOOL srgb) +void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD src_location, DWORD dst_location) { - unsigned int width, height, level, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; - unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_texture *texture = surface->container; - struct wined3d_device *device = texture->resource.device; - const struct wined3d_color_key_conversion *conversion; - struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_resource *resource = &texture->resource; + struct wined3d_device *device = resource->device; + const struct wined3d_format_gl *format_gl; + struct wined3d_texture *restore_texture; + const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; + unsigned int row_pitch, slice_pitch; + unsigned int width, height, level; struct wined3d_bo_address data; - BYTE *src_mem, *dst_mem = NULL; - struct wined3d_format format; - POINT dst_point = {0, 0}; - RECT src_rect; - BOOL depth; - - depth = texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL; - sub_resource = surface_get_sub_resource(surface); - - if (!depth && wined3d_settings.offscreen_rendering_mode != ORM_FBO - && wined3d_resource_is_offscreen(&texture->resource) - && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) - { - surface_load_fb_texture(surface, srgb, context); + unsigned int restore_idx; + BYTE *row, *top, *bottom; + BOOL src_is_upside_down; + unsigned int i; + BYTE *mem; - return TRUE; - } + wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); - level = sub_resource_idx % texture->level_count; - width = wined3d_texture_get_level_width(texture, level); - height = wined3d_texture_get_level_height(texture, level); - SetRect(&src_rect, 0, 0, width, height); + restore_texture = context->current_rt.texture; + restore_idx = context->current_rt.sub_resource_idx; + if (restore_texture != texture || restore_idx != sub_resource_idx) + context = context_acquire(device, texture, sub_resource_idx); + else + restore_texture = NULL; + context_gl = wined3d_context_gl(context); + gl_info = context_gl->gl_info; - if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) - && (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) - && fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info, - &texture->resource, WINED3D_LOCATION_TEXTURE_RGB, - &texture->resource, WINED3D_LOCATION_TEXTURE_SRGB)) + if (src_location != resource->draw_binding) { - if (srgb) - surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB, - &src_rect, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect); - else - surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB, - &src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); - - return TRUE; + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, + resource, sub_resource_idx, NULL, 0, src_location); + wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER); + context_invalidate_state(context, STATE_FRAMEBUFFER); } - - if (!depth && sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) - && (!srgb || (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))) + else { - DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ? - WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; - DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; - - if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info, - &texture->resource, src_location, &texture->resource, dst_location)) - surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location, - &src_rect, surface, dst_location, &src_rect); - - return TRUE; + wined3d_context_gl_apply_blit_state(context_gl, device); } - /* Upload from system memory */ - - if (srgb) + /* Select the correct read buffer, and give some debug output. + * There is no need to keep track of the current read buffer or reset it, + * every part of the code that reads sets the read buffer as desired. + */ + if (src_location != WINED3D_LOCATION_DRAWABLE || wined3d_resource_is_offscreen(resource)) { - if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture->resource.map_binding)) - == WINED3D_LOCATION_TEXTURE_RGB) - { - FIXME_(d3d_perf)("Downloading RGB surface %p to reload it as sRGB.\n", surface); - wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); - } + /* Mapping the primary render target which is not on a swapchain. + * Read from the back buffer. */ + TRACE("Mapping offscreen render target.\n"); + gl_info->gl_ops.gl.p_glReadBuffer(wined3d_context_gl_get_offscreen_gl_buffer(context_gl)); + src_is_upside_down = TRUE; } else { - if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture->resource.map_binding)) - == WINED3D_LOCATION_TEXTURE_SRGB) - { - FIXME_(d3d_perf)("Downloading sRGB surface %p to reload it as RGB.\n", surface); - wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); - } + /* Onscreen surfaces are always part of a swapchain */ + GLenum buffer = wined3d_texture_get_gl_buffer(texture); + TRACE("Mapping %#x buffer.\n", buffer); + gl_info->gl_ops.gl.p_glReadBuffer(buffer); + src_is_upside_down = FALSE; } + checkGLcall("glReadBuffer"); - if (!(sub_resource->locations & surface_simple_locations)) + if (data.buffer_object) { - WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); - /* Lets hope we get it from somewhere... */ - wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); + checkGLcall("glBindBuffer"); } - wined3d_texture_prepare_texture(texture, context, srgb); - wined3d_texture_bind_and_dirtify(texture, context, srgb); - wined3d_texture_get_pitch(texture, level, &src_row_pitch, &src_slice_pitch); - - format = *texture->resource.format; - if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) - format = *wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage); - - /* Don't use PBOs for converted surfaces. During PBO conversion we look at - * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is - * getting called. */ -#if !defined(STAGING_CSMT) - if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer_object) -#else /* STAGING_CSMT */ - if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer) -#endif /* STAGING_CSMT */ - { - TRACE("Removing the pbo attached to surface %p.\n", surface); + level = sub_resource_idx % texture->level_count; + wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); + format_gl = wined3d_format_gl(resource->format); - wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); - wined3d_texture_set_map_binding(texture, WINED3D_LOCATION_SYSMEM); - } + /* Setup pixel store pack state -- to glReadPixels into the correct place */ + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / format_gl->f.byte_count); + checkGLcall("glPixelStorei"); - wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations); - if (format.conv_byte_count) - { - /* This code is entered for texture formats which need a fixup. */ - format.byte_count = format.conv_byte_count; - wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch); + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); + gl_info->gl_ops.gl.p_glReadPixels(0, 0, width, height, + format_gl->format, format_gl->type, data.addr); + checkGLcall("glReadPixels"); - src_mem = context_map_bo_address(context, &data, src_slice_pitch, - GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); - if (!(dst_mem = heap_alloc(dst_slice_pitch))) - { - ERR("Out of memory (%u).\n", dst_slice_pitch); - context_release(context); - return FALSE; - } - format.upload(src_mem, dst_mem, src_row_pitch, src_slice_pitch, - dst_row_pitch, dst_slice_pitch, width, height, 1); - src_row_pitch = dst_row_pitch; - context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + /* Reset previous pixel store pack state */ + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, 0); + checkGLcall("glPixelStorei"); - data.buffer_object = 0; - data.addr = dst_mem; - } - else if (conversion) + if (!src_is_upside_down) { - /* This code is only entered for color keying fixups */ - struct wined3d_palette *palette = NULL; + /* glReadPixels returns the image upside down, and there is no way to + * prevent this. Flip the lines in software. */ - wined3d_format_calculate_pitch(&format, device->surface_alignment, - width, height, &dst_row_pitch, &dst_slice_pitch); + if (!(row = heap_alloc(row_pitch))) + goto error; - src_mem = context_map_bo_address(context, &data, src_slice_pitch, - GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); - if (!(dst_mem = heap_alloc(dst_slice_pitch))) + if (data.buffer_object) { - ERR("Out of memory (%u).\n", dst_slice_pitch); - context_release(context); - return FALSE; + mem = GL_EXTCALL(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE)); + checkGLcall("glMapBuffer"); } - if (texture->swapchain && texture->swapchain->palette) - palette = texture->swapchain->palette; - conversion->convert(src_mem, src_row_pitch, dst_mem, dst_row_pitch, - width, height, palette, &texture->async.gl_color_key); - src_row_pitch = dst_row_pitch; - context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); - - data.buffer_object = 0; - data.addr = dst_mem; - } - - wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, - src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); + else + mem = data.addr; - heap_free(dst_mem); + top = mem; + bottom = mem + row_pitch * (height - 1); + for (i = 0; i < height / 2; i++) + { + memcpy(row, top, row_pitch); + memcpy(top, bottom, row_pitch); + memcpy(bottom, row, row_pitch); + top += row_pitch; + bottom -= row_pitch; + } + heap_free(row); - return TRUE; -} + if (data.buffer_object) + GL_EXTCALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER)); + } -/* Context activation is done by the caller. */ -static BOOL surface_load_renderbuffer(struct wined3d_surface *surface, struct wined3d_context *context, - DWORD dst_location) -{ - struct wined3d_texture *texture = surface->container; - unsigned int level = surface_get_sub_resource_idx(surface) % texture->level_count; - const RECT rect = {0, 0, - wined3d_texture_get_level_width(texture, level), - wined3d_texture_get_level_height(texture, level)}; - DWORD locations = surface_get_sub_resource(surface)->locations; - DWORD src_location; - - if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) +error: + if (data.buffer_object) { - FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", - wined3d_debug_location(locations)); - return FALSE; + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); } - if (locations & WINED3D_LOCATION_RB_MULTISAMPLE) - src_location = WINED3D_LOCATION_RB_MULTISAMPLE; - else if (locations & WINED3D_LOCATION_RB_RESOLVED) - src_location = WINED3D_LOCATION_RB_RESOLVED; - else if (locations & WINED3D_LOCATION_TEXTURE_SRGB) - src_location = WINED3D_LOCATION_TEXTURE_SRGB; - else /* surface_blt_fbo will load the source location if necessary. */ - src_location = WINED3D_LOCATION_TEXTURE_RGB; - - surface_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, - surface, src_location, &rect, surface, dst_location, &rect); - - return TRUE; + if (restore_texture) + context_restore(context, restore_texture, restore_idx); } -/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ -BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) +/* Read the framebuffer contents into a texture. Note that this function + * doesn't do any kind of flipping. Using this on an onscreen surface will + * result in a flipped D3D texture. + * + * Context activation is done by the caller. This function may temporarily + * switch to a different context and restore the original one before return. */ +void texture2d_load_fb_texture(struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, BOOL srgb, struct wined3d_context *context) { - TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); + struct wined3d_texture *restore_texture; + const struct wined3d_gl_info *gl_info; + struct wined3d_context_gl *context_gl; + struct wined3d_resource *resource; + unsigned int restore_idx, level; + struct wined3d_device *device; + GLenum target; - switch (location) - { - case WINED3D_LOCATION_USER_MEMORY: - case WINED3D_LOCATION_SYSMEM: - case WINED3D_LOCATION_BUFFER: - return surface_load_sysmem(surface, context, location); + resource = &texture_gl->t.resource; + device = resource->device; + restore_texture = context->current_rt.texture; + restore_idx = context->current_rt.sub_resource_idx; + if (restore_texture != &texture_gl->t || restore_idx != sub_resource_idx) + context = context_acquire(device, &texture_gl->t, sub_resource_idx); + else + restore_texture = NULL; + context_gl = wined3d_context_gl(context); - case WINED3D_LOCATION_DRAWABLE: - return surface_load_drawable(surface, context); + gl_info = context_gl->gl_info; + device_invalidate_state(device, STATE_FRAMEBUFFER); - case WINED3D_LOCATION_RB_RESOLVED: - case WINED3D_LOCATION_RB_MULTISAMPLE: - return surface_load_renderbuffer(surface, context, location); + wined3d_texture_gl_prepare_texture(texture_gl, context_gl, srgb); + wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, srgb); - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - return surface_load_texture(surface, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); + TRACE("Reading back offscreen render target %p, %u.\n", texture_gl, sub_resource_idx); - default: - ERR("Don't know how to handle location %#x.\n", location); - return FALSE; - } + if (wined3d_resource_is_offscreen(resource)) + gl_info->gl_ops.gl.p_glReadBuffer(wined3d_context_gl_get_offscreen_gl_buffer(context_gl)); + else + gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(&texture_gl->t)); + checkGLcall("glReadBuffer"); + + level = sub_resource_idx % texture_gl->t.level_count; + target = wined3d_texture_gl_get_sub_resource_target(texture_gl, sub_resource_idx); + gl_info->gl_ops.gl.p_glCopyTexSubImage2D(target, level, 0, 0, 0, 0, + wined3d_texture_get_level_width(&texture_gl->t, level), + wined3d_texture_get_level_height(&texture_gl->t, level)); + checkGLcall("glCopyTexSubImage2D"); + + if (restore_texture) + context_restore(context, restore_texture, restore_idx); } /* Context activation is done by the caller. */ @@ -2679,16 +1069,28 @@ static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de } static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, - const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, + unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) { - struct wined3d_resource *src_resource = &src_surface->container->resource; - struct wined3d_resource *dst_resource = &dst_surface->container->resource; - struct wined3d_device *device = dst_resource->device; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct wined3d_resource *src_resource, *dst_resource; enum wined3d_blit_op blit_op = op; + struct wined3d_device *device; struct wined3d_blitter *next; + TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, " + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n", + blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), + wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location), + wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter)); + + src_resource = &src_texture->resource; + dst_resource = &dst_texture->resource; + + device = dst_resource->device; + if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_resource->format->id == src_resource->format->id) { if (dst_resource->format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) @@ -2697,26 +1099,33 @@ static DWORD fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit blit_op = WINED3D_BLIT_OP_COLOR_BLIT; } - if (!fbo_blitter_supported(blit_op, context->gl_info, + if (!fbo_blitter_supported(blit_op, context_gl->gl_info, src_resource, src_location, dst_resource, dst_location)) { - if ((next = blitter->next)) - return next->ops->blitter_blit(next, op, context, src_surface, src_location, - src_rect, dst_surface, dst_location, dst_rect, colour_key, filter); + if (!(next = blitter->next)) + { + ERR("No blitter to handle blit op %#x.\n", op); + return dst_location; + } + + TRACE("Forwarding to blitter %p.\n", next); + return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); } if (blit_op == WINED3D_BLIT_OP_COLOR_BLIT) { TRACE("Colour blit.\n"); - surface_blt_fbo(device, context, filter, src_surface, src_location, - src_rect, dst_surface, dst_location, dst_rect); + texture2d_blt_fbo(device, context, filter, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect); return dst_location; } if (blit_op == WINED3D_BLIT_OP_DEPTH_BLIT) { TRACE("Depth/stencil blit.\n"); - surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect); + texture2d_depth_blt_fbo(device, context, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect); return dst_location; } @@ -2779,21 +1188,20 @@ static void raw_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de /* Context activation is done by the caller. */ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, - const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, + unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) { - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int src_sub_resource_idx, dst_sub_resource_idx; + struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); + struct wined3d_texture_gl *dst_texture_gl = wined3d_texture_gl(dst_texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int src_level, src_layer, dst_level, dst_layer; - struct wined3d_texture *src_texture, *dst_texture; struct wined3d_blitter *next; GLuint src_name, dst_name; DWORD location; - src_texture = src_surface->container; - dst_texture = dst_surface->container; - /* If we would need to copy from a renderbuffer or drawable, we'd probably * be better of using the FBO blitter directly, since we'd need to use it * to copy the resource contents to the texture anyway. */ @@ -2809,17 +1217,15 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit } TRACE("Forwarding to blitter %p.\n", next); - return next->ops->blitter_blit(next, op, context, src_surface, src_location, - src_rect, dst_surface, dst_location, dst_rect, colour_key, filter); + return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter); } TRACE("Blit using ARB_copy_image.\n"); - src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); src_level = src_sub_resource_idx % src_texture->level_count; src_layer = src_sub_resource_idx / src_texture->level_count; - dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); dst_level = dst_sub_resource_idx % dst_texture->level_count; dst_layer = dst_sub_resource_idx / dst_texture->level_count; @@ -2829,7 +1235,8 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; if (!wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, location)) ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(location)); - src_name = wined3d_texture_get_texture_name(src_texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); + src_name = wined3d_texture_gl_get_texture_name(src_texture_gl, + context, location == WINED3D_LOCATION_TEXTURE_SRGB); location = dst_location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB); if (!location) @@ -2845,10 +1252,11 @@ static DWORD raw_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit if (!wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, location)) ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(location)); } - dst_name = wined3d_texture_get_texture_name(dst_texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); + dst_name = wined3d_texture_gl_get_texture_name(dst_texture_gl, + context, location == WINED3D_LOCATION_TEXTURE_SRGB); - GL_EXTCALL(glCopyImageSubData(src_name, src_texture->target, src_level, - src_rect->left, src_rect->top, src_layer, dst_name, dst_texture->target, dst_level, + GL_EXTCALL(glCopyImageSubData(src_name, src_texture_gl->target, src_level, + src_rect->left, src_rect->top, src_layer, dst_name, dst_texture_gl->target, dst_level, dst_rect->left, dst_rect->top, dst_layer, src_rect->right - src_rect->left, src_rect->bottom - src_rect->top, 1)); checkGLcall("copy image data"); @@ -2904,7 +1312,10 @@ static BOOL ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3 const struct wined3d_format *dst_format = dst_resource->format; BOOL decompress; - decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) + return FALSE; + + decompress = (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU)) { @@ -2930,7 +1341,7 @@ static BOOL ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3 } case WINED3D_BLIT_OP_COLOR_BLIT: case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST: - if (!context->gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + if (!wined3d_context_gl_const(context)->gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) return FALSE; if (TRACE_ON(d3d)) @@ -2955,7 +1366,7 @@ static BOOL ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3 } } - if (!(dst_resource->usage & WINED3DUSAGE_RENDERTARGET)) + if (!(dst_resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) { TRACE("Can only blit to render targets.\n"); return FALSE; @@ -2992,7 +1403,10 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil) { - struct wined3d_rendertarget_view *view; + struct wined3d_rendertarget_view *view, *previous = NULL; + BOOL have_identical_size = TRUE; + struct wined3d_fb_state tmp_fb; + unsigned int next_rt_count = 0; struct wined3d_blitter *next; DWORD next_flags = 0; unsigned int i; @@ -3005,12 +1419,14 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de continue; if (ffp_blitter_use_cpu_clear(view) - || (!(view->resource->usage & WINED3DUSAGE_RENDERTARGET) + || (!(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET) && (wined3d_settings.offscreen_rendering_mode != ORM_FBO || !(view->format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)))) { next_flags |= WINED3DCLEAR_TARGET; flags &= ~WINED3DCLEAR_TARGET; + next_rt_count = rt_count; + rt_count = 0; break; } @@ -3029,24 +1445,67 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de } if (flags) - device_clear_render_targets(device, rt_count, fb, rect_count, - clear_rects, draw_rect, flags, colour, depth, stencil); + { + for (i = 0; i < rt_count; ++i) + { + if (!(view = fb->render_targets[i])) + continue; + + if (previous && (previous->width != view->width || previous->height != view->height)) + have_identical_size = FALSE; + previous = view; + } + if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + { + view = fb->depth_stencil; + + if (previous && (previous->width != view->width || previous->height != view->height)) + have_identical_size = FALSE; + } + + if (have_identical_size) + { + device_clear_render_targets(device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, colour, depth, stencil); + } + else + { + for (i = 0; i < rt_count; ++i) + { + if (!(view = fb->render_targets[i])) + continue; + + tmp_fb.render_targets[0] = view; + tmp_fb.depth_stencil = NULL; + device_clear_render_targets(device, 1, &tmp_fb, rect_count, + clear_rects, draw_rect, WINED3DCLEAR_TARGET, colour, depth, stencil); + } + if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + { + tmp_fb.render_targets[0] = NULL; + tmp_fb.depth_stencil = fb->depth_stencil; + device_clear_render_targets(device, 0, &tmp_fb, rect_count, + clear_rects, draw_rect, flags & ~WINED3DCLEAR_TARGET, colour, depth, stencil); + } + } + } if (next_flags && (next = blitter->next)) - next->ops->blitter_clear(next, device, rt_count, fb, rect_count, + next->ops->blitter_clear(next, device, next_rt_count, fb, rect_count, clear_rects, draw_rect, next_flags, colour, depth, stencil); } static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, - const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, + unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - struct wined3d_texture *src_texture = src_surface->container; - struct wined3d_texture *dst_texture = dst_surface->container; - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_resource *src_resource, *dst_resource; + struct wined3d_texture *staging_texture = NULL; struct wined3d_color_key old_blt_key; struct wined3d_device *device; struct wined3d_blitter *next; @@ -3060,28 +1519,68 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit if (!ffp_blit_supported(op, context, src_resource, src_location, dst_resource, dst_location)) { if ((next = blitter->next)) - return next->ops->blitter_blit(next, op, context, src_surface, src_location, - src_rect, dst_surface, dst_location, dst_rect, color_key, filter); + return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location, + src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter); } - TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface); + TRACE("Blt from texture %p, %u to rendertarget %p, %u.\n", + src_texture, src_sub_resource_idx, dst_texture, dst_sub_resource_idx); old_blt_key = src_texture->async.src_blt_color_key; old_color_key_flags = src_texture->async.color_key_flags; wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, color_key); - /* Make sure the surface is up-to-date. This should probably use - * surface_load_location() and worry about the destination surface too, - * unless we're overwriting it completely. */ - wined3d_texture_load(src_texture, context, FALSE); + if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + struct wined3d_resource_desc desc; + struct wined3d_box upload_box; + unsigned int src_level; + HRESULT hr; + + TRACE("Source texture is not GPU accessible, creating a staging texture.\n"); + + src_level = src_sub_resource_idx % src_texture->level_count; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + desc.format = src_texture->resource.format->id; + desc.multisample_type = src_texture->resource.multisample_type; + desc.multisample_quality = src_texture->resource.multisample_quality; + desc.usage = WINED3DUSAGE_PRIVATE; + desc.bind_flags = 0; + desc.access = WINED3D_RESOURCE_ACCESS_GPU; + desc.width = wined3d_texture_get_level_width(src_texture, src_level); + desc.height = wined3d_texture_get_level_height(src_texture, src_level); + desc.depth = 1; + desc.size = 0; + + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0, + NULL, NULL, &wined3d_null_parent_ops, &staging_texture))) + { + ERR("Failed to create staging texture, hr %#x.\n", hr); + return dst_location; + } + + wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth); + wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0, + src_texture, src_sub_resource_idx, &upload_box); - /* Activate the destination context, set it up for blitting. */ - context_apply_blit_state(context, device); + src_texture = staging_texture; + src_texture_gl = wined3d_texture_gl(src_texture); + src_sub_resource_idx = 0; + } + else + { + /* Make sure the surface is up-to-date. This should probably use + * surface_load_location() and worry about the destination surface + * too, unless we're overwriting it completely. */ + wined3d_texture_load(src_texture, context, FALSE); + } + + wined3d_context_gl_apply_ffp_blit_state(context_gl, device); if (dst_location == WINED3D_LOCATION_DRAWABLE) { r = *dst_rect; - surface_translate_drawable_coords(dst_surface, context->win_handle, &r); + wined3d_texture_translate_drawable_coords(dst_texture, context_gl->window, &r); dst_rect = &r; } @@ -3091,21 +1590,22 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit if (dst_location == WINED3D_LOCATION_DRAWABLE) { - TRACE("Destination surface %p is onscreen.\n", dst_surface); + TRACE("Destination texture %p is onscreen.\n", dst_texture); buffer = wined3d_texture_get_gl_buffer(dst_texture); } else { - TRACE("Destination surface %p is offscreen.\n", dst_surface); + TRACE("Destination texture %p is offscreen.\n", dst_texture); buffer = GL_COLOR_ATTACHMENT0; } - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); - context_set_draw_buffer(context, buffer); - context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, + dst_resource, dst_sub_resource_idx, NULL, 0, dst_location); + wined3d_context_gl_set_draw_buffer(context_gl, buffer); + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER); } - gl_info->gl_ops.gl.p_glEnable(src_texture->target); + gl_info->gl_ops.gl.p_glEnable(src_texture_gl->target); checkGLcall("glEnable(target)"); if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key) @@ -3127,7 +1627,8 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit checkGLcall("glAlphaFunc"); } - draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter); + wined3d_context_gl_draw_textured_quad(context_gl, src_texture_gl, + src_sub_resource_idx, src_rect, dst_rect, filter); if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key) { @@ -3135,7 +1636,6 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit checkGLcall("glDisable(GL_ALPHA_TEST)"); } - /* Leave the OpenGL state valid for blitting. */ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) @@ -3149,14 +1649,16 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); } - if (wined3d_settings.strict_draw_ordering - || (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + if (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture) + gl_info->gl_ops.gl.p_glFlush(); /* Restore the color key parameters */ wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); + if (staging_texture) + wined3d_texture_decref(staging_texture); + return dst_location; } @@ -3307,8 +1809,9 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int struct wined3d_bo_address src_data, dst_data; unsigned int src_fmt_flags, dst_fmt_flags; struct wined3d_map_desc dst_map, src_map; - struct wined3d_context *context = NULL; unsigned int x, sx, xinc, y, sy, yinc; + struct wined3d_map_range dst_range; + struct wined3d_context *context; unsigned int texture_level; HRESULT hr = WINED3D_OK; BOOL same_sub_resource; @@ -3322,9 +1825,18 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, src_sub_resource_idx, debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter)); - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); + context = context_acquire(device, NULL, 0); + + src_format = src_texture->resource.format; + dst_format = dst_texture->resource.format; + + if (wined3d_format_is_typeless(src_format) && src_format->id == dst_format->typeless_id) + src_format = dst_format; + if (wined3d_format_is_typeless(dst_format) && dst_format->id == src_format->typeless_id) + dst_format = src_format; + dst_range.offset = 0; + dst_range.size = dst_texture->sub_resources[dst_sub_resource_idx].size; if (src_texture == dst_texture && src_sub_resource_idx == dst_sub_resource_idx) { same_sub_resource = TRUE; @@ -3336,36 +1848,27 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~map_binding); wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch); wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); - dst_map.data = context_map_bo_address(context, &dst_data, - dst_texture->sub_resources[dst_sub_resource_idx].size, - GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE); + dst_map.data = wined3d_context_map_bo_address(context, &dst_data, + dst_texture->sub_resources[dst_sub_resource_idx].size, 0, WINED3D_MAP_READ | WINED3D_MAP_WRITE); src_map = dst_map; - src_format = dst_texture->resource.format; - dst_format = src_format; - dst_fmt_flags = dst_texture->resource.format_flags; - src_fmt_flags = dst_fmt_flags; } else { same_sub_resource = FALSE; - dst_format = dst_texture->resource.format; - dst_fmt_flags = dst_texture->resource.format_flags; - if (!(flags & WINED3D_BLT_RAW) && dst_texture->resource.format->id != src_texture->resource.format->id) + if (!(flags & WINED3D_BLT_RAW) && dst_format->id != src_format->id) { if (!(converted_texture = surface_convert_format(src_texture, src_sub_resource_idx, dst_format))) { - FIXME("Cannot convert %s to %s.\n", debug_d3dformat(src_texture->resource.format->id), - debug_d3dformat(dst_texture->resource.format->id)); - if (context) - context_release(context); + FIXME("Cannot convert %s to %s.\n", debug_d3dformat(src_format->id), + debug_d3dformat(dst_format->id)); + context_release(context); return WINED3DERR_NOTAVAILABLE; } src_texture = converted_texture; src_sub_resource_idx = 0; + src_format = src_texture->resource.format; } - src_format = src_texture->resource.format; - src_fmt_flags = src_texture->resource.format_flags; map_binding = src_texture->resource.map_binding; texture_level = src_sub_resource_idx % src_texture->level_count; @@ -3373,8 +1876,8 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_get_pitch(src_texture, texture_level, &src_map.row_pitch, &src_map.slice_pitch); wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &src_data, map_binding); - src_map.data = context_map_bo_address(context, &src_data, - src_texture->sub_resources[src_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); + src_map.data = wined3d_context_map_bo_address(context, &src_data, + src_texture->sub_resources[src_sub_resource_idx].size, 0, WINED3D_MAP_READ); map_binding = dst_texture->resource.map_binding; texture_level = dst_sub_resource_idx % dst_texture->level_count; @@ -3383,9 +1886,11 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~map_binding); wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch); wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); - dst_map.data = context_map_bo_address(context, &dst_data, - dst_texture->sub_resources[dst_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_WRITE); + dst_map.data = wined3d_context_map_bo_address(context, &dst_data, + dst_texture->sub_resources[dst_sub_resource_idx].size, 0, WINED3D_MAP_WRITE); } + src_fmt_flags = src_format->flags[src_texture->resource.gl_type]; + dst_fmt_flags = dst_format->flags[dst_texture->resource.gl_type]; flags &= ~WINED3D_BLT_RAW; bpp = dst_format->byte_count; @@ -3761,9 +2266,9 @@ do { \ FIXME(" Unsupported flags %#x.\n", flags); release: - context_unmap_bo_address(context, &dst_data, GL_PIXEL_UNPACK_BUFFER); + wined3d_context_unmap_bo_address(context, &dst_data, 0, 1, &dst_range); if (!same_sub_resource) - context_unmap_bo_address(context, &src_data, GL_PIXEL_UNPACK_BUFFER); + wined3d_context_unmap_bo_address(context, &src_data, 0, 0, NULL); if (SUCCEEDED(hr) && dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture) { SetRect(&dst_texture->swapchain->front_buffer_update, @@ -3772,8 +2277,7 @@ do { \ } if (converted_texture) wined3d_texture_decref(converted_texture); - if (context) - context_release(context); + context_release(context); return hr; } @@ -3782,13 +2286,14 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, const struct wined3d_box *box, const struct wined3d_color *colour) { struct wined3d_device *device = view->resource->device; - struct wined3d_context *context = NULL; + unsigned int x, y, z, w, h, d, bpp, level; + struct wined3d_context *context; struct wined3d_texture *texture; struct wined3d_bo_address data; - unsigned int x, y, w, h, bpp; + struct wined3d_map_range range; struct wined3d_map_desc map; DWORD map_binding; - BYTE *row; + uint8_t *dst; DWORD c; TRACE("view %p, box %s, colour %s.\n", view, debug_box(box), debug_color(colour)); @@ -3809,28 +2314,39 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, return; } - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); + context = context_acquire(device, NULL, 0); + + texture = texture_from_resource(view->resource); + level = view->sub_resource_idx % texture->level_count; c = wined3d_format_convert_from_float(view->format, colour); bpp = view->format->byte_count; - w = box->right - box->left; - h = box->bottom - box->top; + w = min(box->right, view->width) - min(box->left, view->width); + h = min(box->bottom, view->height) - min(box->top, view->height); + if (view->resource->type != WINED3D_RTYPE_TEXTURE_3D) + { + d = 1; + } + else + { + d = wined3d_texture_get_level_depth(texture, level); + d = min(box->back, d) - min(box->front, d); + } - texture = texture_from_resource(view->resource); map_binding = texture->resource.map_binding; if (!wined3d_texture_load_location(texture, view->sub_resource_idx, context, map_binding)) ERR("Failed to load the sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_invalidate_location(texture, view->sub_resource_idx, ~map_binding); - wined3d_texture_get_pitch(texture, view->sub_resource_idx % texture->level_count, - &map.row_pitch, &map.slice_pitch); + wined3d_texture_get_pitch(texture, level, &map.row_pitch, &map.slice_pitch); wined3d_texture_get_memory(texture, view->sub_resource_idx, &data, map_binding); - map.data = context_map_bo_address(context, &data, - texture->sub_resources[view->sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_WRITE); + map.data = wined3d_context_map_bo_address(context, &data, + texture->sub_resources[view->sub_resource_idx].size, 0, WINED3D_MAP_WRITE); map.data = (BYTE *)map.data + (box->front * map.slice_pitch) + ((box->top / view->format->block_height) * map.row_pitch) + ((box->left / view->format->block_width) * view->format->block_byte_count); + range.offset = 0; + range.size = texture->sub_resources[view->sub_resource_idx].size; switch (bpp) { @@ -3850,12 +2366,12 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, case 3: { - row = map.data; - for (x = 0; x < w; ++x, row += 3) + dst = map.data; + for (x = 0; x < w; ++x, dst += 3) { - row[0] = (c ) & 0xff; - row[1] = (c >> 8) & 0xff; - row[2] = (c >> 16) & 0xff; + dst[0] = (c ) & 0xff; + dst[1] = (c >> 8) & 0xff; + dst[2] = (c >> 16) & 0xff; } break; } @@ -3872,16 +2388,22 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, return; } - row = map.data; + dst = map.data; for (y = 1; y < h; ++y) { - row += map.row_pitch; - memcpy(row, map.data, w * bpp); + dst += map.row_pitch; + memcpy(dst, map.data, w * bpp); } - context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); - if (context) - context_release(context); + dst = map.data; + for (z = 1; z < d; ++z) + { + dst += map.slice_pitch; + memcpy(dst, map.data, w * h * bpp); + } + + wined3d_context_unmap_bo_address(context, &data, 0, 1, &range); + context_release(context); } static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, @@ -3906,7 +2428,7 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de box.right = min(clear_rects[i].right, draw_rect->right); box.bottom = min(clear_rects[i].bottom, draw_rect->bottom); box.front = 0; - box.back = 1; + box.back = ~0u; if (box.left >= box.right || box.top >= box.bottom) continue; @@ -3932,16 +2454,13 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de } static DWORD cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, - struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, - const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, + unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_texture *src_texture = src_surface->container; struct wined3d_blt_fx fx; DWORD flags = 0; @@ -3950,7 +2469,9 @@ static DWORD cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit { case WINED3D_BLIT_OP_COLOR_BLIT: case WINED3D_BLIT_OP_DEPTH_BLIT: + break; case WINED3D_BLIT_OP_RAW_BLIT: + flags |= WINED3D_BLT_RAW; break; case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST: flags |= WINED3D_BLT_ALPHA_TEST; @@ -3995,17 +2516,12 @@ struct wined3d_blitter *wined3d_cpu_blitter_create(void) return blitter; } -HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx, + enum wined3d_texture_filter_type filter) { - struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; - struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; - unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); - unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource; - struct wined3d_texture *dst_texture = dst_surface->container; - struct wined3d_texture *src_texture = src_surface->container; struct wined3d_device *device = dst_texture->resource.device; struct wined3d_swapchain *src_swapchain, *dst_swapchain; const struct wined3d_color_key *colour_key = NULL; @@ -4014,15 +2530,17 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst struct wined3d_context *context; enum wined3d_blit_op blit_op; BOOL scale, convert, resolve; + RECT src_rect, dst_rect; static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY | WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_ALPHA_TEST | WINED3D_BLT_RAW; - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), - flags, fx, debug_d3dtexturefiltertype(filter)); + TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, " + "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n", + dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, src_sub_resource_idx, + debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter)); TRACE("Usage is %s.\n", debug_d3dusage(dst_texture->resource.usage)); if (fx) @@ -4036,6 +2554,18 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst fx->src_color_key.color_space_high_value); } + dst_sub_resource = &dst_texture->sub_resources[dst_sub_resource_idx]; + src_sub_resource = &src_texture->sub_resources[src_sub_resource_idx]; + + if (src_sub_resource->locations & WINED3D_LOCATION_DISCARDED) + { + WARN("Source sub-resource is discarded, nothing to do.\n"); + return WINED3D_OK; + } + + SetRect(&src_rect, src_box->left, src_box->top, src_box->right, src_box->bottom); + SetRect(&dst_rect, dst_box->left, dst_box->top, dst_box->right, dst_box->bottom); + if (!fx || !(fx->fx)) flags &= ~WINED3D_BLT_FX; @@ -4052,7 +2582,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst if (!device->d3d_initialized) { - WARN("D3D not initialized, using fallback.\n"); + WARN("D3D not initialized, using CPU blit fallback.\n"); goto cpu; } @@ -4068,26 +2598,25 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst if (flags & ~simple_blit) { - WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags); - goto fallback; + WARN_(d3d_perf)("Using CPU fallback for complex blit (%#x).\n", flags); + goto cpu; } src_swapchain = src_texture->swapchain; dst_swapchain = dst_texture->swapchain; - /* This isn't strictly needed. FBO blits for example could deal with - * cross-swapchain blits by first downloading the source to a texture - * before switching to the destination context. We just have this here to - * not have to deal with the issue, since cross-swapchain blits should be - * rare. */ - if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain) + if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain + && (wined3d_settings.offscreen_rendering_mode != ORM_FBO + || src_texture == src_swapchain->front_buffer)) { - FIXME("Using fallback for cross-swapchain blit.\n"); - goto fallback; + /* TODO: We could support cross-swapchain blits by first downloading + * the source to a texture. */ + FIXME("Cross-swapchain blit not supported.\n"); + return WINED3DERR_INVALIDCALL; } - scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left - || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top; + scale = src_box->right - src_box->left != dst_box->right - dst_box->left + || src_box->bottom - src_box->top != dst_box->bottom - dst_box->top; convert = src_texture->resource.format->id != dst_texture->resource.format->id; resolve = src_texture->resource.multisample_type != dst_texture->resource.multisample_type; @@ -4105,11 +2634,15 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst else dst_location = dst_texture->resource.map_binding; + if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve)) + blit_op = WINED3D_BLIT_OP_RAW_BLIT; + else + blit_op = WINED3D_BLIT_OP_DEPTH_BLIT; + context = context_acquire(device, dst_texture, dst_sub_resource_idx); - valid_locations = device->blitter->ops->blitter_blit(device->blitter, - WINED3D_BLIT_OP_DEPTH_BLIT, context, - src_surface, src_texture->resource.draw_binding, src_rect, - dst_surface, dst_location, dst_rect, NULL, filter); + valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context, + src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect, + dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter); context_release(context); wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations); @@ -4120,9 +2653,6 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst TRACE("Colour blit.\n"); - dst_sub_resource = &dst_texture->sub_resources[dst_sub_resource_idx]; - src_sub_resource = &src_texture->sub_resources[src_sub_resource_idx]; - /* In principle this would apply to depth blits as well, but we don't * implement those in the CPU blitter at the moment. */ if ((dst_sub_resource->locations & dst_texture->resource.map_binding) @@ -4163,19 +2693,40 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst TRACE("Not doing upload because the destination format needs conversion.\n"); else { - POINT dst_point = {dst_rect->left, dst_rect->top}; - - if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) + wined3d_texture_upload_from_texture(dst_texture, dst_sub_resource_idx, dst_box->left, + dst_box->top, dst_box->front, src_texture, src_sub_resource_idx, src_box); + if (!wined3d_resource_is_offscreen(&dst_texture->resource)) { - if (!wined3d_resource_is_offscreen(&dst_texture->resource)) - { - context = context_acquire(device, dst_texture, dst_sub_resource_idx); - wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, - context, dst_texture->resource.draw_binding); - context_release(context); - } - return WINED3D_OK; + context = context_acquire(device, dst_texture, dst_sub_resource_idx); + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, + context, dst_texture->resource.draw_binding); + context_release(context); } + return WINED3D_OK; + } + } + else if (!(src_sub_resource->locations & surface_simple_locations) + && (dst_sub_resource->locations & dst_texture->resource.map_binding) + && !(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) + { + /* Download */ + if (scale) + TRACE("Not doing download because of scaling.\n"); + else if (convert) + TRACE("Not doing download because of format conversion.\n"); + else if (src_texture->resource.format->conv_byte_count) + TRACE("Not doing download because the source format needs conversion.\n"); + else if (!(src_texture->flags & WINED3D_TEXTURE_DOWNLOADABLE)) + TRACE("Not doing download because texture is not downloadable.\n"); + else if (!texture2d_is_full_rect(src_texture, src_sub_resource_idx % src_texture->level_count, &src_rect)) + TRACE("Not doing download because of partial download (src).\n"); + else if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_rect)) + TRACE("Not doing download because of partial download (dst).\n"); + else + { + wined3d_texture_download_from_texture(dst_texture, dst_sub_resource_idx, src_texture, + src_sub_resource_idx); + return WINED3D_OK; } } else if (dst_swapchain && dst_swapchain->back_buffers @@ -4188,22 +2739,22 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst * Prince of Persia 3D use Blt() from the backbuffer to the * frontbuffer instead of doing a Flip(). D3d8 and d3d9 applications * can't blit directly to the frontbuffer. */ - enum wined3d_swap_effect swap_effect = dst_swapchain->desc.swap_effect; + enum wined3d_swap_effect swap_effect = dst_swapchain->state.desc.swap_effect; TRACE("Using present for backbuffer -> frontbuffer blit.\n"); /* Set the swap effect to COPY, we don't want the backbuffer to become * undefined. */ - dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; - wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0, 0); - dst_swapchain->desc.swap_effect = swap_effect; + dst_swapchain->state.desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; + wined3d_swapchain_present(dst_swapchain, NULL, NULL, + dst_swapchain->win_handle, dst_swapchain->swap_interval, 0); + dst_swapchain->state.desc.swap_effect = swap_effect; return WINED3D_OK; } - else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve)) - { + + if ((flags & WINED3D_BLT_RAW) || (blit_op == WINED3D_BLIT_OP_COLOR_BLIT && !scale && !convert && !resolve)) blit_op = WINED3D_BLIT_OP_RAW_BLIT; - } if (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU) dst_location = dst_texture->resource.draw_binding; @@ -4212,8 +2763,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst context = context_acquire(device, dst_texture, dst_sub_resource_idx); valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context, - src_surface, src_texture->resource.draw_binding, src_rect, - dst_surface, dst_location, dst_rect, colour_key, filter); + src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect, + dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter); context_release(context); wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations); @@ -4221,12 +2772,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst return WINED3D_OK; -fallback: - /* Special cases for render targets. */ - if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) - return WINED3D_OK; - cpu: - return surface_cpu_blt(dst_texture, dst_sub_resource_idx, &dst_box, - src_texture, src_sub_resource_idx, &src_box, flags, fx, filter); + return surface_cpu_blt(dst_texture, dst_sub_resource_idx, dst_box, + src_texture, src_sub_resource_idx, src_box, flags, fx, filter); } diff --git a/dll/directx/wine/wined3d/swapchain.c b/dll/directx/wine/wined3d/swapchain.c index 8c67a0d42be..4d598780fe9 100644 --- a/dll/directx/wine/wined3d/swapchain.c +++ b/dll/directx/wine/wined3d/swapchain.c @@ -31,18 +31,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps); -static void wined3d_swapchain_destroy_object(void *object) -{ - swapchain_destroy_contexts(object); -} - -static void swapchain_cleanup(struct wined3d_swapchain *swapchain) +void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; UINT i; TRACE("Destroying swapchain %p.\n", swapchain); + wined3d_unhook_swapchain(swapchain); wined3d_swapchain_set_gamma_ramp(swapchain, 0, &swapchain->orig_gamma); /* Release the swapchain's draw buffers. Make sure swapchain->back_buffers[0] @@ -57,7 +53,7 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) if (swapchain->back_buffers) { - i = swapchain->desc.backbuffer_count; + i = swapchain->state.desc.backbuffer_count; while (i--) { @@ -69,35 +65,54 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) swapchain->back_buffers = NULL; } - wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain); - swapchain->device->cs->ops->finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); - /* Restore the screen resolution if we rendered in fullscreen. * This will restore the screen resolution to what it was before creating * the swapchain. In case of d3d8 and d3d9 this will be the original * desktop resolution. In case of d3d7 this will be a NOP because ddraw * sets the resolution before starting up Direct3D, thus orig_width and * orig_height will be equal to the modes in the presentation params. */ - if (!swapchain->desc.windowed && swapchain->desc.auto_restore_display_mode) + if (!swapchain->state.desc.windowed) { - if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d, - swapchain->device->adapter->ordinal, &swapchain->original_mode))) - ERR("Failed to restore display mode, hr %#x.\n", hr); + if (swapchain->state.desc.auto_restore_display_mode) + { + if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d, + swapchain->device->adapter->ordinal, &swapchain->state.original_mode))) + ERR("Failed to restore display mode, hr %#x.\n", hr); - if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) + if (swapchain->state.desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) + { + wined3d_swapchain_state_restore_from_fullscreen(&swapchain->state, + swapchain->state.device_window, &swapchain->state.original_window_rect); + wined3d_device_release_focus_window(swapchain->device); + } + } + else { - wined3d_device_restore_fullscreen_window(swapchain->device, swapchain->device_window, - &swapchain->original_window_rect); - wined3d_device_release_focus_window(swapchain->device); + wined3d_swapchain_state_restore_from_fullscreen(&swapchain->state, swapchain->state.device_window, NULL); } } +} + +static void wined3d_swapchain_gl_destroy_object(void *object) +{ + wined3d_swapchain_gl_destroy_contexts(object); +} + +void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) +{ + struct wined3d_cs *cs = swapchain_gl->s.device->cs; + + wined3d_swapchain_cleanup(&swapchain_gl->s); - if (swapchain->backup_dc) + wined3d_cs_destroy_object(cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); + + if (swapchain_gl->backup_dc) { - TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain->backup_wnd, swapchain->backup_dc); + TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain_gl->backup_wnd, swapchain_gl->backup_dc); - wined3d_release_dc(swapchain->backup_wnd, swapchain->backup_dc); - DestroyWindow(swapchain->backup_wnd); + wined3d_release_dc(swapchain_gl->backup_wnd, swapchain_gl->backup_dc); + DestroyWindow(swapchain_gl->backup_wnd); } } @@ -118,13 +133,19 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain) if (!refcount) { - struct wined3d_device *device = swapchain->device; + struct wined3d_device *device; + + wined3d_mutex_lock(); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + device = swapchain->device; + if (device->swapchain_count && device->swapchains[0] == swapchain) + wined3d_device_uninit_3d(device); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - swapchain_cleanup(swapchain); swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent); - heap_free(swapchain); + swapchain->device->adapter->adapter_ops->adapter_destroy_swapchain(swapchain); + + wined3d_mutex_unlock(); } return refcount; @@ -140,42 +161,48 @@ void * CDECL wined3d_swapchain_get_parent(const struct wined3d_swapchain *swapch void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window) { if (!window) - window = swapchain->device_window; + window = swapchain->state.device_window; if (window == swapchain->win_handle) return; TRACE("Setting swapchain %p window from %p to %p.\n", swapchain, swapchain->win_handle, window); + + wined3d_cs_finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); + swapchain->win_handle = window; } HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - DWORD swap_interval, DWORD flags) + unsigned int swap_interval, DWORD flags) { +#ifdef __REACTOS__ +#else static DWORD notified_flags = 0; +#endif RECT s, d; - TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, flags %#x.\n", + TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, swap_interval %u, flags %#x.\n", swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), - dst_window_override, flags); + dst_window_override, swap_interval, flags); - if (flags & ~notified_flags) - { - FIXME("Ignoring flags %#x.\n", flags & ~notified_flags); - notified_flags |= flags; - } + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + wined3d_mutex_lock(); if (!swapchain->back_buffers) { - WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); + WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL.\n"); + wined3d_mutex_unlock(); return WINED3DERR_INVALIDCALL; } if (!src_rect) { - SetRect(&s, 0, 0, swapchain->desc.backbuffer_width, - swapchain->desc.backbuffer_height); + SetRect(&s, 0, 0, swapchain->state.desc.backbuffer_width, + swapchain->state.desc.backbuffer_height); src_rect = &s; } @@ -188,6 +215,8 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, wined3d_cs_emit_present(swapchain->device->cs, swapchain, src_rect, dst_rect, dst_window_override, swap_interval, flags); + wined3d_mutex_unlock(); + return WINED3D_OK; } @@ -201,7 +230,7 @@ HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapc SetRect(&src_rect, 0, 0, swapchain->front_buffer->resource.width, swapchain->front_buffer->resource.height); dst_rect = src_rect; - if (swapchain->desc.windowed) + if (swapchain->state.desc.windowed) { MapWindowPoints(swapchain->win_handle, NULL, (POINT *)&dst_rect, 2); FIXME("Using destination rect %s in windowed mode, this is likely wrong.\n", @@ -223,7 +252,7 @@ struct wined3d_texture * CDECL wined3d_swapchain_get_back_buffer(const struct wi * NULL). We need this because this function is called from * stateblock_init_default_state() to get the default scissorrect * dimensions. */ - if (!swapchain->back_buffers || back_buffer_idx >= swapchain->desc.backbuffer_count) + if (!swapchain->back_buffers || back_buffer_idx >= swapchain->state.desc.backbuffer_count) { WARN("Invalid back buffer index.\n"); /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it @@ -245,6 +274,11 @@ HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain swapchain->device->adapter->ordinal, raster_status); } +struct wined3d_swapchain_state * CDECL wined3d_swapchain_get_state(struct wined3d_swapchain *swapchain) +{ + return &swapchain->state; +} + HRESULT CDECL wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation) { @@ -273,7 +307,7 @@ void CDECL wined3d_swapchain_get_desc(const struct wined3d_swapchain *swapchain, { TRACE("swapchain %p, desc %p.\n", swapchain, desc); - *desc = swapchain->desc; + *desc = swapchain->state.desc; } HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain, @@ -286,9 +320,9 @@ HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *s if (flags) FIXME("Ignoring flags %#x.\n", flags); - dc = GetDCEx(swapchain->device_window, 0, DCX_USESTYLE | DCX_CACHE); + dc = GetDCEx(swapchain->state.device_window, 0, DCX_USESTYLE | DCX_CACHE); SetDeviceGammaRamp(dc, (void *)ramp); - ReleaseDC(swapchain->device_window, dc); + ReleaseDC(swapchain->state.device_window, dc); return WINED3D_OK; } @@ -296,6 +330,9 @@ HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *s void CDECL wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette) { TRACE("swapchain %p, palette %p.\n", swapchain, palette); + + wined3d_cs_finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); + swapchain->palette = palette; } @@ -306,9 +343,9 @@ HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *s TRACE("swapchain %p, ramp %p.\n", swapchain, ramp); - dc = GetDCEx(swapchain->device_window, 0, DCX_USESTYLE | DCX_CACHE); + dc = GetDCEx(swapchain->state.device_window, 0, DCX_USESTYLE | DCX_CACHE); GetDeviceGammaRamp(dc, ramp); - ReleaseDC(swapchain->device_window, dc); + ReleaseDC(swapchain->state.device_window, dc); return WINED3D_OK; } @@ -318,7 +355,6 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect) { struct wined3d_texture *texture = swapchain->back_buffers[0]; - struct wined3d_surface *back_buffer = texture->sub_resources[0].u.surface; struct wined3d_device *device = swapchain->device; enum wined3d_texture_filter_type filter; DWORD location; @@ -338,45 +374,66 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, location = WINED3D_LOCATION_RB_RESOLVED; wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); - device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, back_buffer, - location, src_rect, back_buffer, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter); + device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, texture, 0, + location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter); wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); } +static void swapchain_gl_set_swap_interval(struct wined3d_swapchain *swapchain, + struct wined3d_context_gl *context_gl, unsigned int swap_interval) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + + swap_interval = swap_interval <= 4 ? swap_interval : 1; + if (swapchain->swap_interval == swap_interval) + return; + + swapchain->swap_interval = swap_interval; + + if (!gl_info->supported[WGL_EXT_SWAP_CONTROL]) + return; + + if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval))) + { + ERR("Failed to set swap interval %u for context %p, last error %#x.\n", + swap_interval, context_gl, GetLastError()); + } +} + /* Context activation is done by the caller. */ -static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context *context) +static void wined3d_swapchain_gl_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context *context) { struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_texture *texture, *texture_prev; + struct wined3d_texture_gl *texture, *texture_prev; struct gl_texture tex0; GLuint rb0; DWORD locations0; unsigned int i; static const DWORD supported_locations = WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_RB_MULTISAMPLE; - if (swapchain->desc.backbuffer_count < 2 || !swapchain->render_to_fbo) + if (swapchain->state.desc.backbuffer_count < 2 || !swapchain->render_to_fbo) return; - texture_prev = swapchain->back_buffers[0]; + texture_prev = wined3d_texture_gl(swapchain->back_buffers[0]); /* Back buffer 0 is already in the draw binding. */ tex0 = texture_prev->texture_rgb; rb0 = texture_prev->rb_multisample; - locations0 = texture_prev->sub_resources[0].locations; + locations0 = texture_prev->t.sub_resources[0].locations; - for (i = 1; i < swapchain->desc.backbuffer_count; ++i) + for (i = 1; i < swapchain->state.desc.backbuffer_count; ++i) { - texture = swapchain->back_buffers[i]; - sub_resource = &texture->sub_resources[0]; + texture = wined3d_texture_gl(swapchain->back_buffers[i]); + sub_resource = &texture->t.sub_resources[0]; if (!(sub_resource->locations & supported_locations)) - wined3d_texture_load_location(texture, 0, context, texture->resource.draw_binding); + wined3d_texture_load_location(&texture->t, 0, context, texture->t.resource.draw_binding); texture_prev->texture_rgb = texture->texture_rgb; texture_prev->rb_multisample = texture->rb_multisample; - wined3d_texture_validate_location(texture_prev, 0, sub_resource->locations & supported_locations); - wined3d_texture_invalidate_location(texture_prev, 0, ~(sub_resource->locations & supported_locations)); + wined3d_texture_validate_location(&texture_prev->t, 0, sub_resource->locations & supported_locations); + wined3d_texture_invalidate_location(&texture_prev->t, 0, ~(sub_resource->locations & supported_locations)); texture_prev = texture; } @@ -384,31 +441,38 @@ static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct texture_prev->texture_rgb = tex0; texture_prev->rb_multisample = rb0; - wined3d_texture_validate_location(texture_prev, 0, locations0 & supported_locations); - wined3d_texture_invalidate_location(texture_prev, 0, ~(locations0 & supported_locations)); + wined3d_texture_validate_location(&texture_prev->t, 0, locations0 & supported_locations); + wined3d_texture_invalidate_location(&texture_prev->t, 0, ~(locations0 & supported_locations)); device_invalidate_state(swapchain->device, STATE_FRAMEBUFFER); } static void swapchain_gl_present(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, DWORD flags) + const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, DWORD flags) { + struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(swapchain); + const struct wined3d_swapchain_desc *desc = &swapchain->state.desc; struct wined3d_texture *back_buffer = swapchain->back_buffers[0]; const struct wined3d_fb_state *fb = &swapchain->device->cs->fb; + struct wined3d_rendertarget_view *dsv = fb->depth_stencil; + struct wined3d_texture *logo_texture, *cursor_texture; const struct wined3d_gl_info *gl_info; - struct wined3d_texture *logo_texture; + struct wined3d_context_gl *context_gl; struct wined3d_context *context; BOOL render_to_fbo; - context = context_acquire(swapchain->device, back_buffer, 0); - if (!context->valid) + context = context_acquire(swapchain->device, swapchain->front_buffer, 0); + context_gl = wined3d_context_gl(context); + if (!context_gl->valid) { context_release(context); WARN("Invalid context, skipping present.\n"); return; } - gl_info = context->gl_info; + gl_info = context_gl->gl_info; + + swapchain_gl_set_swap_interval(swapchain, context_gl, swap_interval); if ((logo_texture = swapchain->device->logo_texture)) { @@ -419,8 +483,8 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT); } - if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture - && !swapchain->device->hardwareCursor) + if ((cursor_texture = swapchain->device->cursor_texture) + && swapchain->device->bCursorVisible && !swapchain->device->hardwareCursor) { RECT dst_rect = { @@ -431,31 +495,28 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, }; RECT src_rect = { - 0, 0, - swapchain->device->cursor_texture->resource.width, - swapchain->device->cursor_texture->resource.height + 0, 0, cursor_texture->resource.width, cursor_texture->resource.height }; const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height}; TRACE("Rendering the software cursor.\n"); - if (swapchain->desc.windowed) + if (desc->windowed) MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&dst_rect, 2); if (wined3d_clip_blit(&clip_rect, &dst_rect, &src_rect)) - wined3d_texture_blt(back_buffer, 0, &dst_rect, - swapchain->device->cursor_texture, 0, &src_rect, - WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT); + wined3d_texture_blt(back_buffer, 0, &dst_rect, cursor_texture, 0, + &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT); } - TRACE("Presenting HDC %p.\n", context->hdc); + TRACE("Presenting DC %p.\n", context_gl->dc); if (!(render_to_fbo = swapchain->render_to_fbo) && (src_rect->left || src_rect->top - || src_rect->right != swapchain->desc.backbuffer_width - || src_rect->bottom != swapchain->desc.backbuffer_height + || src_rect->right != desc->backbuffer_width + || src_rect->bottom != desc->backbuffer_height || dst_rect->left || dst_rect->top - || dst_rect->right != swapchain->desc.backbuffer_width - || dst_rect->bottom != swapchain->desc.backbuffer_height)) + || dst_rect->right != desc->backbuffer_width + || dst_rect->bottom != desc->backbuffer_height)) render_to_fbo = TRUE; /* Rendering to a window of different size, presenting partial rectangles, @@ -480,17 +541,13 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, if (swapchain->render_to_fbo) swapchain_blit(swapchain, context, src_rect, dst_rect); -#if !defined(STAGING_CSMT) - if (swapchain->num_contexts > 1) -#else /* STAGING_CSMT */ - if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) -#endif /* STAGING_CSMT */ + if (swapchain_gl->context_count > 1) gl_info->gl_ops.gl.p_glFinish(); /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ - gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); + gl_info->gl_ops.wgl.p_wglSwapBuffers(context_gl->dc); - wined3d_swapchain_rotate(swapchain, context); + wined3d_swapchain_gl_rotate(swapchain, context); TRACE("SwapBuffers called, Starting new frame\n"); /* FPS support */ @@ -518,25 +575,24 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE * up to date and hope WGL flipped front and back buffers and read this data into * the FBO. Don't bother about this for now. */ - if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD - || swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP_DISCARD) - wined3d_texture_validate_location(swapchain->back_buffers[swapchain->desc.backbuffer_count - 1], + if (desc->swap_effect == WINED3D_SWAP_EFFECT_DISCARD + || desc->swap_effect == WINED3D_SWAP_EFFECT_FLIP_DISCARD) + wined3d_texture_validate_location(swapchain->back_buffers[desc->backbuffer_count - 1], 0, WINED3D_LOCATION_DISCARDED); - if (fb->depth_stencil) + if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER) { - struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); + struct wined3d_texture *ds = texture_from_resource(dsv->resource); - if (ds && (swapchain->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL - || ds->container->flags & WINED3D_TEXTURE_DISCARD)) - wined3d_texture_validate_location(ds->container, - fb->depth_stencil->sub_resource_idx, WINED3D_LOCATION_DISCARDED); + if ((desc->flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL + || ds->flags & WINED3D_TEXTURE_DISCARD)) + wined3d_texture_validate_location(ds, dsv->sub_resource_idx, WINED3D_LOCATION_DISCARDED); } context_release(context); } -static void swapchain_gl_frontbuffer_updated(struct wined3d_swapchain *swapchain) +static void swapchain_frontbuffer_updated(struct wined3d_swapchain *swapchain) { struct wined3d_texture *front_buffer = swapchain->front_buffer; struct wined3d_context *context; @@ -550,12 +606,24 @@ static void swapchain_gl_frontbuffer_updated(struct wined3d_swapchain *swapchain static const struct wined3d_swapchain_ops swapchain_gl_ops = { swapchain_gl_present, - swapchain_gl_frontbuffer_updated, + swapchain_frontbuffer_updated, +}; + +static void swapchain_vk_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, + const RECT *dst_rect, unsigned int swap_interval, uint32_t flags) +{ + FIXME("Not implemented.\n"); +} + +static const struct wined3d_swapchain_ops swapchain_vk_ops = +{ + swapchain_vk_present, + swapchain_frontbuffer_updated, }; static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain) { - struct wined3d_surface *front; + struct wined3d_dc_info *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; @@ -563,11 +631,11 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai TRACE("swapchain %p.\n", swapchain); - front = swapchain->front_buffer->sub_resources[0].u.surface; + front = &swapchain->front_buffer->dc_info[0]; if (swapchain->palette) wined3d_palette_apply_to_dc(swapchain->palette, front->dc); - if (front->container->resource.map_count) + if (swapchain->front_buffer->resource.map_count) ERR("Trying to blit a mapped surface.\n"); TRACE("Copying surface %p to screen.\n", front); @@ -578,7 +646,7 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai /* Front buffer coordinates are screen coordinates. Map them to the * destination window if not fullscreened. */ - if (swapchain->desc.windowed) + if (swapchain->state.desc.windowed) ClientToScreen(window, &offset); TRACE("offset %s.\n", wine_dbgstr_point(&offset)); @@ -596,28 +664,28 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai } static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, DWORD flags) + const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, DWORD flags) { - struct wined3d_surface *front, *back; + struct wined3d_dc_info *front, *back; HBITMAP bitmap; void *data; HDC dc; - front = swapchain->front_buffer->sub_resources[0].u.surface; - back = swapchain->back_buffers[0]->sub_resources[0].u.surface; + front = &swapchain->front_buffer->dc_info[0]; + back = &swapchain->back_buffers[0]->dc_info[0]; /* Flip the surface data. */ dc = front->dc; bitmap = front->bitmap; - data = front->container->resource.heap_memory; + data = swapchain->front_buffer->resource.heap_memory; front->dc = back->dc; front->bitmap = back->bitmap; - front->container->resource.heap_memory = back->container->resource.heap_memory; + swapchain->front_buffer->resource.heap_memory = swapchain->back_buffers[0]->resource.heap_memory; back->dc = dc; back->bitmap = bitmap; - back->container->resource.heap_memory = data; + swapchain->back_buffers[0]->resource.heap_memory = data; /* FPS support */ if (TRACE_ON(fps)) @@ -642,7 +710,7 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, swapchain_gdi_frontbuffer_updated(swapchain); } -static const struct wined3d_swapchain_ops swapchain_gdi_ops = +static const struct wined3d_swapchain_ops swapchain_no3d_ops = { swapchain_gdi_present, swapchain_gdi_frontbuffer_updated, @@ -653,7 +721,7 @@ static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; - if (!swapchain->desc.backbuffer_count) + if (!swapchain->state.desc.backbuffer_count) { TRACE("Single buffered rendering.\n"); swapchain->render_to_fbo = FALSE; @@ -667,6 +735,7 @@ static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) static void wined3d_swapchain_apply_sample_count_override(const struct wined3d_swapchain *swapchain, enum wined3d_format_id format_id, enum wined3d_multisample_type *type, DWORD *quality) { + const struct wined3d_adapter *adapter; const struct wined3d_gl_info *gl_info; const struct wined3d_format *format; enum wined3d_multisample_type t; @@ -674,8 +743,9 @@ static void wined3d_swapchain_apply_sample_count_override(const struct wined3d_s if (wined3d_settings.sample_count == ~0u) return; - gl_info = &swapchain->device->adapter->gl_info; - if (!(format = wined3d_get_format(gl_info, format_id, WINED3DUSAGE_RENDERTARGET))) + adapter = swapchain->device->adapter; + gl_info = &adapter->gl_info; + if (!(format = wined3d_get_format(adapter, format_id, WINED3D_BIND_RENDER_TARGET))) return; if ((t = min(wined3d_settings.sample_count, gl_info->limits.samples))) @@ -686,104 +756,73 @@ static void wined3d_swapchain_apply_sample_count_override(const struct wined3d_s *quality = 0; } -static void wined3d_swapchain_update_swap_interval_cs(void *object) +void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const struct wined3d_device *device) { - struct wined3d_swapchain *swapchain = object; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - int swap_interval; + /* Subtract 1 for the implicit OpenGL latency. */ + swapchain->max_frame_latency = device->max_frame_latency >= 2 ? device->max_frame_latency - 1 : 1; +} - context = context_acquire(swapchain->device, swapchain->front_buffer, 0); - gl_info = context->gl_info; - - switch (swapchain->desc.swap_interval) - { - case WINED3DPRESENT_INTERVAL_IMMEDIATE: - swap_interval = 0; - break; - case WINED3DPRESENT_INTERVAL_DEFAULT: - case WINED3DPRESENT_INTERVAL_ONE: - swap_interval = 1; - break; - case WINED3DPRESENT_INTERVAL_TWO: - swap_interval = 2; - break; - case WINED3DPRESENT_INTERVAL_THREE: - swap_interval = 3; - break; - case WINED3DPRESENT_INTERVAL_FOUR: - swap_interval = 4; - break; - default: - FIXME("Unhandled present interval %#x.\n", swapchain->desc.swap_interval); - swap_interval = 1; - } - - if (gl_info->supported[WGL_EXT_SWAP_CONTROL]) - { - if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval))) - ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x\n", - swap_interval, context, GetLastError()); - } +static enum wined3d_format_id adapter_format_from_backbuffer_format(const struct wined3d_adapter *adapter, + enum wined3d_format_id format_id) +{ + const struct wined3d_format *backbuffer_format; - context_release(context); + backbuffer_format = wined3d_get_format(adapter, format_id, WINED3D_BIND_RENDER_TARGET); + return pixelformat_for_depth(backbuffer_format->byte_count * CHAR_BIT); } -static void wined3d_swapchain_cs_init(void *object) +static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *state, + const struct wined3d_swapchain_desc *desc, HWND window, + struct wined3d *wined3d, unsigned int adapter_idx) { - struct wined3d_swapchain *swapchain = object; - const struct wined3d_gl_info *gl_info; - unsigned int i; - - static const enum wined3d_format_id formats[] = - { - WINED3DFMT_D24_UNORM_S8_UINT, - WINED3DFMT_D32_UNORM, - WINED3DFMT_R24_UNORM_X8_TYPELESS, - WINED3DFMT_D16_UNORM, - WINED3DFMT_S1_UINT_D15_UNORM, - }; + HRESULT hr; - gl_info = &swapchain->device->adapter->gl_info; + state->desc = *desc; - /* Without ORM_FBO, switching the depth/stencil format is hard. Always - * request a depth/stencil buffer in the likely case it's needed later. */ - for (i = 0; i < ARRAY_SIZE(formats); ++i) + if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &state->original_mode, NULL))) { - swapchain->ds_format = wined3d_get_format(gl_info, formats[i], WINED3DUSAGE_DEPTHSTENCIL); - if ((swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format))) - break; - TRACE("Depth stencil format %s is not supported, trying next format.\n", debug_d3dformat(formats[i])); + ERR("Failed to get current display mode, hr %#x.\n", hr); + return hr; } - if (!swapchain->context[0]) + if (!desc->windowed) { - WARN("Failed to create context.\n"); - return; - } - swapchain->num_contexts = 1; + if (desc->flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) + { + struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx]; - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && (!swapchain->desc.enable_auto_depth_stencil - || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) - FIXME("Add OpenGL context recreation support.\n"); + state->d3d_mode.width = desc->backbuffer_width; + state->d3d_mode.height = desc->backbuffer_height; + state->d3d_mode.format_id = adapter_format_from_backbuffer_format(adapter, desc->backbuffer_format); + state->d3d_mode.refresh_rate = desc->refresh_rate; + state->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; + } + else + { + state->d3d_mode = state->original_mode; + } + } - context_release(swapchain->context[0]); + GetWindowRect(window, &state->original_window_rect); + state->device_window = window; - wined3d_swapchain_update_swap_interval_cs(swapchain); + return hr; } -static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, - struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, + const struct wined3d_swapchain_ops *swapchain_ops) { const struct wined3d_adapter *adapter = device->adapter; struct wined3d_resource_desc texture_desc; BOOL displaymode_set = FALSE; DWORD texture_flags = 0; RECT client_rect; + unsigned int i; HWND window; HRESULT hr; - UINT i; + + wined3d_mutex_lock(); if (desc->backbuffer_count > 1) { @@ -796,68 +835,70 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 && desc->swap_effect != WINED3D_SWAP_EFFECT_COPY) FIXME("Unimplemented swap effect %#x.\n", desc->swap_effect); - if (device->wined3d->flags & WINED3D_NO3D) - swapchain->swapchain_ops = &swapchain_gdi_ops; - else - swapchain->swapchain_ops = &swapchain_gl_ops; - window = desc->device_window ? desc->device_window : device->create_parms.focus_window; + if (FAILED(hr = wined3d_swapchain_state_init(&swapchain->state, desc, window, device->wined3d, adapter->ordinal))) + return hr; + swapchain->swapchain_ops = swapchain_ops; swapchain->device = device; swapchain->parent = parent; swapchain->parent_ops = parent_ops; swapchain->ref = 1; swapchain->win_handle = window; - swapchain->device_window = window; - - if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, - adapter->ordinal, &swapchain->original_mode, NULL))) - { - ERR("Failed to get current display mode, hr %#x.\n", hr); - goto err; - } - GetWindowRect(window, &swapchain->original_window_rect); + swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT; + swapchain_set_max_frame_latency(swapchain, device); GetClientRect(window, &client_rect); if (desc->windowed) { + TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect)); + if (!desc->backbuffer_width) { - desc->backbuffer_width = client_rect.right; + desc->backbuffer_width = client_rect.right ? client_rect.right : 8; TRACE("Updating width to %u.\n", desc->backbuffer_width); } - if (!desc->backbuffer_height) { - desc->backbuffer_height = client_rect.bottom; + desc->backbuffer_height = client_rect.bottom ? client_rect.bottom : 8; TRACE("Updating height to %u.\n", desc->backbuffer_height); } if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) { - desc->backbuffer_format = swapchain->original_mode.format_id; - TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->original_mode.format_id)); + desc->backbuffer_format = swapchain->state.original_mode.format_id; + TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->state.original_mode.format_id)); } } - swapchain->desc = *desc; - wined3d_swapchain_apply_sample_count_override(swapchain, swapchain->desc.backbuffer_format, - &swapchain->desc.multisample_type, &swapchain->desc.multisample_quality); + else + { + wined3d_swapchain_state_setup_fullscreen(&swapchain->state, + window, desc->backbuffer_width, desc->backbuffer_height); + } + swapchain->state.desc = *desc; + wined3d_swapchain_apply_sample_count_override(swapchain, swapchain->state.desc.backbuffer_format, + &swapchain->state.desc.multisample_type, &swapchain->state.desc.multisample_quality); swapchain_update_render_to_fbo(swapchain); TRACE("Creating front buffer.\n"); texture_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - texture_desc.format = swapchain->desc.backbuffer_format; - texture_desc.multisample_type = swapchain->desc.multisample_type; - texture_desc.multisample_quality = swapchain->desc.multisample_quality; + texture_desc.format = swapchain->state.desc.backbuffer_format; + texture_desc.multisample_type = swapchain->state.desc.multisample_type; + texture_desc.multisample_quality = swapchain->state.desc.multisample_quality; texture_desc.usage = 0; + if (device->wined3d->flags & WINED3D_NO3D) + texture_desc.usage |= WINED3DUSAGE_OWNDC; + texture_desc.bind_flags = 0; texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU; - texture_desc.width = swapchain->desc.backbuffer_width; - texture_desc.height = swapchain->desc.backbuffer_height; + if (swapchain->state.desc.flags & WINED3D_SWAPCHAIN_LOCKABLE_BACKBUFFER) + texture_desc.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + texture_desc.width = swapchain->state.desc.backbuffer_width; + texture_desc.height = swapchain->state.desc.backbuffer_height; texture_desc.depth = 1; texture_desc.size = 0; - if (swapchain->desc.flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + if (swapchain->state.desc.flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC; if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, @@ -877,53 +918,21 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 /* MSDN says we're only allowed a single fullscreen swapchain per device, * so we should really check to see if there is a fullscreen swapchain * already. Does a single head count as full screen? */ - if (!desc->windowed) - { - if (desc->flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) - { - /* Change the display settings */ - swapchain->d3d_mode.width = desc->backbuffer_width; - swapchain->d3d_mode.height = desc->backbuffer_height; - swapchain->d3d_mode.format_id = desc->backbuffer_format; - swapchain->d3d_mode.refresh_rate = desc->refresh_rate; - swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; - - if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, - adapter->ordinal, &swapchain->d3d_mode))) - { - WARN("Failed to set display mode, hr %#x.\n", hr); - goto err; - } - displaymode_set = TRUE; - } - else - { - swapchain->d3d_mode = swapchain->original_mode; - } - } - - if (!(device->wined3d->flags & WINED3D_NO3D)) + if (!desc->windowed && desc->flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) { - if (!(swapchain->context = heap_alloc(sizeof(*swapchain->context)))) - { - ERR("Failed to create the context array.\n"); - hr = E_OUTOFMEMORY; - goto err; - } - - wined3d_cs_init_object(device->cs, wined3d_swapchain_cs_init, swapchain); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - - if (!swapchain->context[0]) + /* Change the display settings */ + if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, + adapter->ordinal, &swapchain->state.d3d_mode))) { - hr = WINED3DERR_NOTAVAILABLE; + WARN("Failed to set display mode, hr %#x.\n", hr); goto err; } + displaymode_set = TRUE; } - if (swapchain->desc.backbuffer_count > 0) + if (swapchain->state.desc.backbuffer_count > 0) { - if (!(swapchain->back_buffers = heap_calloc(swapchain->desc.backbuffer_count, + if (!(swapchain->back_buffers = heap_calloc(swapchain->state.desc.backbuffer_count, sizeof(*swapchain->back_buffers)))) { ERR("Failed to allocate backbuffer array memory.\n"); @@ -931,15 +940,18 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 goto err; } - texture_desc.usage = swapchain->desc.backbuffer_usage; - for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + texture_desc.bind_flags = swapchain->state.desc.backbuffer_bind_flags; + texture_desc.usage = 0; + if (device->wined3d->flags & WINED3D_NO3D) + texture_desc.usage |= WINED3DUSAGE_OWNDC; + for (i = 0; i < swapchain->state.desc.backbuffer_count; ++i) { TRACE("Creating back buffer %u.\n", i); if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, parent, &texture_desc, texture_flags, &swapchain->back_buffers[i]))) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); - swapchain->desc.backbuffer_count = i; + swapchain->state.desc.backbuffer_count = i; goto err; } wined3d_texture_set_swapchain(swapchain->back_buffers[i], swapchain); @@ -947,7 +959,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 } /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */ - if (desc->enable_auto_depth_stencil && !(device->wined3d->flags & WINED3D_NO3D)) + if (desc->enable_auto_depth_stencil) { TRACE("Creating depth/stencil buffer.\n"); if (!device->auto_depth_stencil_view) @@ -955,11 +967,13 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 struct wined3d_view_desc desc; struct wined3d_texture *ds; - texture_desc.format = swapchain->desc.auto_depth_stencil_format; - texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL; + texture_desc.format = swapchain->state.desc.auto_depth_stencil_format; + texture_desc.usage = 0; + texture_desc.bind_flags = WINED3D_BIND_DEPTH_STENCIL; + texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU; if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, - device->device_parent, &texture_desc, texture_flags, &ds))) + device->device_parent, &texture_desc, 0, &ds))) { WARN("Failed to create the auto depth/stencil surface, hr %#x.\n", hr); goto err; @@ -984,20 +998,22 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 wined3d_swapchain_get_gamma_ramp(swapchain, &swapchain->orig_gamma); + wined3d_mutex_unlock(); + return WINED3D_OK; err: if (displaymode_set) { if (FAILED(wined3d_set_adapter_display_mode(device->wined3d, - adapter->ordinal, &swapchain->original_mode))) + adapter->ordinal, &swapchain->state.original_mode))) ERR("Failed to restore display mode.\n"); ClipCursor(NULL); } if (swapchain->back_buffers) { - for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + for (i = 0; i < swapchain->state.desc.backbuffer_count; ++i) { if (swapchain->back_buffers[i]) { @@ -1008,125 +1024,181 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 heap_free(swapchain->back_buffers); } - wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain); - swapchain->device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (swapchain->front_buffer) { wined3d_texture_set_swapchain(swapchain->front_buffer, NULL); wined3d_texture_decref(swapchain->front_buffer); } + wined3d_mutex_unlock(); + + return hr; +} + +HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("swapchain_no3d %p, device %p, desc %p, parent %p, parent_ops %p.\n", + swapchain_no3d, device, desc, parent, parent_ops); + + return wined3d_swapchain_init(swapchain_no3d, device, desc, parent, parent_ops, &swapchain_no3d_ops); +} + +HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + HRESULT hr; + + TRACE("swapchain_gl %p, device %p, desc %p, parent %p, parent_ops %p.\n", + swapchain_gl, device, desc, parent, parent_ops); + + if (FAILED(hr = wined3d_swapchain_init(&swapchain_gl->s, device, desc, parent, parent_ops, &swapchain_gl_ops))) + { + /* Cleanup any context that may have been created for the swapchain. */ + wined3d_cs_destroy_object(device->cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + } + return hr; } +HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain *swapchain_vk, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("swapchain_vk %p, device %p, desc %p, parent %p, parent_ops %p.\n", + swapchain_vk, device, desc, parent, parent_ops); + + return wined3d_swapchain_init(swapchain_vk, device, desc, parent, parent_ops, &swapchain_vk_ops); +} + HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) { struct wined3d_swapchain *object; HRESULT hr; - TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", - device, desc, parent, parent_ops, swapchain); + if (FAILED(hr = device->adapter->adapter_ops->adapter_create_swapchain(device, + desc, parent, parent_ops, &object))) + return hr; - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; + if (desc->flags & WINED3D_SWAPCHAIN_HOOK) + wined3d_hook_swapchain(object); - hr = swapchain_init(object, device, desc, parent, parent_ops); - if (FAILED(hr)) + if (desc->flags & WINED3D_SWAPCHAIN_IMPLICIT) { - WARN("Failed to initialize swapchain, hr %#x.\n", hr); - heap_free(object); - return hr; + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_device_set_implicit_swapchain(device, object))) + { + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + device->adapter->adapter_ops->adapter_destroy_swapchain(object); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_unlock(); } - TRACE("Created swapchain %p.\n", object); *swapchain = object; - return WINED3D_OK; + return hr; } -static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain) +static struct wined3d_context_gl *wined3d_swapchain_gl_create_context(struct wined3d_swapchain_gl *swapchain_gl) { - struct wined3d_context **ctx_array; - struct wined3d_context *ctx; + struct wined3d_device *device = swapchain_gl->s.device; + struct wined3d_context_gl *context_gl; + + TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain_gl, GetCurrentThreadId()); + + wined3d_from_cs(device->cs); + + if (!(context_gl = heap_alloc_zero(sizeof(*context_gl)))) + { + ERR("Failed to allocate context memory.\n"); + return NULL; + } - TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain, GetCurrentThreadId()); + if (FAILED(wined3d_context_gl_init(context_gl, swapchain_gl))) + { + WARN("Failed to initialise context.\n"); + heap_free(context_gl); + return NULL; + } - if (!(ctx = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format))) + if (!device_context_add(device, &context_gl->c)) { - ERR("Failed to create a new context for the swapchain\n"); + ERR("Failed to add the newly created context to the context list.\n"); + wined3d_context_gl_destroy(context_gl); return NULL; } - context_release(ctx); - if (!(ctx_array = heap_calloc(swapchain->num_contexts + 1, sizeof(*ctx_array)))) + TRACE("Created context %p.\n", context_gl); + + context_release(&context_gl->c); + + if (!wined3d_array_reserve((void **)&swapchain_gl->contexts, &swapchain_gl->contexts_size, + swapchain_gl->context_count + 1, sizeof(*swapchain_gl->contexts))) { - ERR("Out of memory when trying to allocate a new context array\n"); - context_destroy(swapchain->device, ctx); + ERR("Failed to allocate new context array memory.\n"); + wined3d_context_gl_destroy(context_gl); return NULL; } - memcpy(ctx_array, swapchain->context, sizeof(*ctx_array) * swapchain->num_contexts); - heap_free(swapchain->context); - ctx_array[swapchain->num_contexts] = ctx; - swapchain->context = ctx_array; - swapchain->num_contexts++; + swapchain_gl->contexts[swapchain_gl->context_count++] = context_gl; - TRACE("Returning context %p\n", ctx); - return ctx; + return context_gl; } -void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) +void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) { unsigned int i; - for (i = 0; i < swapchain->num_contexts; ++i) + for (i = 0; i < swapchain_gl->context_count; ++i) { - context_destroy(swapchain->device, swapchain->context[i]); + wined3d_context_gl_destroy(swapchain_gl->contexts[i]); } - heap_free(swapchain->context); - swapchain->num_contexts = 0; - swapchain->context = NULL; + heap_free(swapchain_gl->contexts); + swapchain_gl->contexts_size = 0; + swapchain_gl->context_count = 0; + swapchain_gl->contexts = NULL; } -struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) +struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) { DWORD tid = GetCurrentThreadId(); unsigned int i; - for (i = 0; i < swapchain->num_contexts; ++i) + for (i = 0; i < swapchain_gl->context_count; ++i) { - if (swapchain->context[i]->tid == tid) - return swapchain->context[i]; + if (swapchain_gl->contexts[i]->tid == tid) + return swapchain_gl->contexts[i]; } - /* Create a new context for the thread */ - return swapchain_create_context(swapchain); + /* Create a new context for the thread. */ + return wined3d_swapchain_gl_create_context(swapchain_gl); } -HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) +HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) { - if (!swapchain->backup_dc) + if (!swapchain_gl->backup_dc) { - TRACE("Creating the backup window for swapchain %p.\n", swapchain); + TRACE("Creating the backup window for swapchain %p.\n", swapchain_gl); - if (!(swapchain->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", + if (!(swapchain_gl->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL))) { ERR("Failed to create a window.\n"); return NULL; } - if (!(swapchain->backup_dc = GetDC(swapchain->backup_wnd))) + if (!(swapchain_gl->backup_dc = GetDC(swapchain_gl->backup_wnd))) { ERR("Failed to get a DC.\n"); - DestroyWindow(swapchain->backup_wnd); - swapchain->backup_wnd = NULL; + DestroyWindow(swapchain_gl->backup_wnd); + swapchain_gl->backup_wnd = NULL; return NULL; } } - return swapchain->backup_dc; + return swapchain_gl->backup_dc; } void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) @@ -1135,31 +1207,33 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) wined3d_resource_update_draw_binding(&swapchain->front_buffer->resource); - for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + for (i = 0; i < swapchain->state.desc.backbuffer_count; ++i) { wined3d_resource_update_draw_binding(&swapchain->back_buffers[i]->resource); } } -void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) -{ - wined3d_cs_init_object(swapchain->device->cs, wined3d_swapchain_update_swap_interval_cs, swapchain); -} - void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) { struct wined3d_device *device = swapchain->device; - BOOL filter_messages = device->filter_messages; + HWND window = swapchain->state.device_window; + unsigned int screensaver_active; + BOOL focus_messages, filter; /* This code is not protected by the wined3d mutex, so it may run while * wined3d_device_reset is active. Testing on Windows shows that changing * focus during resets and resetting during focus change events causes * the application to crash with an invalid memory access. */ - device->filter_messages = !(device->wined3d->flags & WINED3D_FOCUS_MESSAGES); + if (!(focus_messages = device->wined3d->flags & WINED3D_FOCUS_MESSAGES)) + filter = wined3d_filter_messages(window, TRUE); if (activate) { + SystemParametersInfoW(SPI_GETSCREENSAVEACTIVE, 0, &screensaver_active, 0); + if ((device->restore_screensaver = !!screensaver_active)) + SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0); + if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)) { /* The d3d versions do not agree on the exact messages here. D3d8 restores @@ -1169,39 +1243,58 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa * * Guild Wars 1 wants a WINDOWPOSCHANGED message on the device window to * resume drawing after a focus loss. */ - SetWindowPos(swapchain->device_window, NULL, 0, 0, - swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height, - SWP_NOACTIVATE | SWP_NOZORDER); + SetWindowPos(window, NULL, 0, 0, swapchain->state.desc.backbuffer_width, + swapchain->state.desc.backbuffer_height, SWP_NOACTIVATE | SWP_NOZORDER); } if (device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE) { if (FAILED(wined3d_set_adapter_display_mode(device->wined3d, - device->adapter->ordinal, &swapchain->d3d_mode))) + device->adapter->ordinal, &swapchain->state.d3d_mode))) ERR("Failed to set display mode.\n"); } + + if (swapchain == device->swapchains[0]) + device->device_parent->ops->activate(device->device_parent, TRUE); } else { + if (device->restore_screensaver) + { + SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, TRUE, NULL, 0); + device->restore_screensaver = FALSE; + } + if (FAILED(wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, NULL))) ERR("Failed to set display mode.\n"); swapchain->reapply_mode = TRUE; - if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES) - && IsWindowVisible(swapchain->device_window)) - ShowWindow(swapchain->device_window, SW_MINIMIZE); + /* Some DDraw apps (Deus Ex: GOTY, and presumably all UT 1 based games) destroy the device + * during window minimization. Do our housekeeping now, as the device may not exist after + * the ShowWindow call. + * + * In d3d9, the device is marked lost after the window is minimized. If we find an app + * that needs this behavior (e.g. because it calls TestCooperativeLevel in the window proc) + * we'll have to control this via a create flag. Note that the device and swapchain are not + * safe to access after the ShowWindow call. */ + if (swapchain == device->swapchains[0]) + device->device_parent->ops->activate(device->device_parent, FALSE); + + if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES) && IsWindowVisible(window)) + ShowWindow(window, SW_MINIMIZE); } - device->filter_messages = filter_messages; + if (!focus_messages) + wined3d_filter_messages(window, filter); } HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality) { - struct wined3d_device *device = swapchain->device; + struct wined3d_swapchain_desc *desc = &swapchain->state.desc; BOOL update_desc = FALSE; TRACE("swapchain %p, buffer_count %u, width %u, height %u, format %s, " @@ -1211,10 +1304,10 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha wined3d_swapchain_apply_sample_count_override(swapchain, format_id, &multisample_type, &multisample_quality); - if (buffer_count && buffer_count != swapchain->desc.backbuffer_count) + if (buffer_count && buffer_count != desc->backbuffer_count) FIXME("Cannot change the back buffer count yet.\n"); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + wined3d_cs_finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); if (!width || !height) { @@ -1224,10 +1317,10 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha RECT client_rect; - if (!swapchain->desc.windowed) + if (!desc->windowed) return WINED3DERR_INVALIDCALL; - if (!GetClientRect(swapchain->device_window, &client_rect)) + if (!GetClientRect(swapchain->state.device_window, &client_rect)) { ERR("Failed to get client rect, last error %#x.\n", GetLastError()); return WINED3DERR_INVALIDCALL; @@ -1240,32 +1333,31 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha height = client_rect.bottom; } - if (width != swapchain->desc.backbuffer_width - || height != swapchain->desc.backbuffer_height) + if (width != desc->backbuffer_width || height != desc->backbuffer_height) { - swapchain->desc.backbuffer_width = width; - swapchain->desc.backbuffer_height = height; + desc->backbuffer_width = width; + desc->backbuffer_height = height; update_desc = TRUE; } if (format_id == WINED3DFMT_UNKNOWN) { - if (!swapchain->desc.windowed) + if (!desc->windowed) return WINED3DERR_INVALIDCALL; - format_id = swapchain->original_mode.format_id; + format_id = swapchain->state.original_mode.format_id; } - if (format_id != swapchain->desc.backbuffer_format) + if (format_id != desc->backbuffer_format) { - swapchain->desc.backbuffer_format = format_id; + desc->backbuffer_format = format_id; update_desc = TRUE; } - if (multisample_type != swapchain->desc.multisample_type - || multisample_quality != swapchain->desc.multisample_quality) + if (multisample_type != desc->multisample_type + || multisample_quality != desc->multisample_quality) { - swapchain->desc.multisample_type = multisample_type; - swapchain->desc.multisample_quality = multisample_quality; + desc->multisample_type = multisample_type; + desc->multisample_quality = multisample_quality; update_desc = TRUE; } @@ -1274,16 +1366,16 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha HRESULT hr; UINT i; - if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width, - swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format, - swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0))) + if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, desc->backbuffer_width, + desc->backbuffer_height, desc->backbuffer_format, + desc->multisample_type, desc->multisample_quality, NULL, 0))) return hr; - for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + for (i = 0; i < desc->backbuffer_count; ++i) { - if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width, - swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format, - swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0))) + if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], desc->backbuffer_width, + desc->backbuffer_height, desc->backbuffer_format, + desc->multisample_type, desc->multisample_quality, NULL, 0))) return hr; } } @@ -1294,23 +1386,20 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha return WINED3D_OK; } -static HRESULT wined3d_swapchain_set_display_mode(struct wined3d_swapchain *swapchain, - struct wined3d_display_mode *mode) +static HRESULT wined3d_swapchain_state_set_display_mode(struct wined3d_swapchain_state *state, + struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_display_mode *mode) { - struct wined3d_device *device = swapchain->device; HRESULT hr; - if (swapchain->desc.flags & WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE) + if (state->desc.flags & WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE) { - if (FAILED(hr = wined3d_find_closest_matching_adapter_mode(device->wined3d, - device->adapter->ordinal, mode))) + if (FAILED(hr = wined3d_find_closest_matching_adapter_mode(wined3d, adapter_idx, mode))) { WARN("Failed to find closest matching mode, hr %#x.\n", hr); } } - if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, - device->adapter->ordinal, mode))) + if (FAILED(hr = wined3d_set_adapter_display_mode(wined3d, adapter_idx, mode))) { WARN("Failed to set display mode, hr %#x.\n", hr); return WINED3DERR_INVALIDCALL; @@ -1319,63 +1408,181 @@ static HRESULT wined3d_swapchain_set_display_mode(struct wined3d_swapchain *swap return WINED3D_OK; } -HRESULT CDECL wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchain, - const struct wined3d_display_mode *mode) +HRESULT CDECL wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state, + struct wined3d *wined3d, unsigned int adapter_idx, const struct wined3d_display_mode *mode) { - struct wined3d_device *device = swapchain->device; struct wined3d_display_mode actual_mode; RECT original_window_rect, window_rect; + HWND window; HRESULT hr; - TRACE("swapchain %p, mode %p.\n", swapchain, mode); + TRACE("state %p, wined3d %p, adapter_idx %u, mode %p.\n", state, wined3d, adapter_idx, mode); + + wined3d_mutex_lock(); - if (swapchain->desc.windowed) + window = state->device_window; + + if (state->desc.windowed) { SetRect(&window_rect, 0, 0, mode->width, mode->height); AdjustWindowRectEx(&window_rect, - GetWindowLongW(swapchain->device_window, GWL_STYLE), FALSE, - GetWindowLongW(swapchain->device_window, GWL_EXSTYLE)); + GetWindowLongW(window, GWL_STYLE), FALSE, + GetWindowLongW(window, GWL_EXSTYLE)); SetRect(&window_rect, 0, 0, window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); - GetWindowRect(swapchain->device_window, &original_window_rect); + GetWindowRect(window, &original_window_rect); OffsetRect(&window_rect, original_window_rect.left, original_window_rect.top); } - else if (swapchain->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) + else if (state->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) { actual_mode = *mode; - if (FAILED(hr = wined3d_swapchain_set_display_mode(swapchain, &actual_mode))) + if (FAILED(hr = wined3d_swapchain_state_set_display_mode(state, wined3d, adapter_idx, &actual_mode))) + { + wined3d_mutex_unlock(); return hr; + } SetRect(&window_rect, 0, 0, actual_mode.width, actual_mode.height); } else { - if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, - &actual_mode, NULL))) + if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &actual_mode, NULL))) { ERR("Failed to get display mode, hr %#x.\n", hr); - return WINED3DERR_INVALIDCALL; + wined3d_mutex_unlock(); + return hr; } SetRect(&window_rect, 0, 0, actual_mode.width, actual_mode.height); } - MoveWindow(swapchain->device_window, window_rect.left, window_rect.top, - window_rect.right - window_rect.left, - window_rect.bottom - window_rect.top, TRUE); + wined3d_mutex_unlock(); + + MoveWindow(window, window_rect.left, window_rect.top, + window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, TRUE); return WINED3D_OK; } -HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain, - const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode) +static LONG fullscreen_style(LONG style) +{ + /* Make sure the window is managed, otherwise we won't get keyboard input. */ + style |= WS_POPUP | WS_SYSMENU; + style &= ~(WS_CAPTION | WS_THICKFRAME); + + return style; +} + +static LONG fullscreen_exstyle(LONG exstyle) +{ + /* Filter out window decorations. */ + exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); + + return exstyle; +} + +HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state, + HWND window, unsigned int w, unsigned int h) +{ + LONG style, exstyle; + BOOL filter; + + TRACE("Setting up window %p for fullscreen mode.\n", window); + + if (!IsWindow(window)) + { + WARN("%p is not a valid window.\n", window); + return WINED3DERR_NOTAVAILABLE; + } + + if (state->style || state->exstyle) + { + ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", + window, state->style, state->exstyle); + } + + state->style = GetWindowLongW(window, GWL_STYLE); + state->exstyle = GetWindowLongW(window, GWL_EXSTYLE); + + style = fullscreen_style(state->style); + exstyle = fullscreen_exstyle(state->exstyle); + + TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", + state->style, state->exstyle, style, exstyle); + + filter = wined3d_filter_messages(window, TRUE); + + SetWindowLongW(window, GWL_STYLE, style); + SetWindowLongW(window, GWL_EXSTYLE, exstyle); + SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + wined3d_filter_messages(window, filter); + + return WINED3D_OK; +} + +void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_state *state, + HWND window, const RECT *window_rect) +{ + unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE; + LONG style, exstyle; + RECT rect = {0}; + BOOL filter; + + if (!state->style && !state->exstyle) + return; + + style = GetWindowLongW(window, GWL_STYLE); + exstyle = GetWindowLongW(window, GWL_EXSTYLE); + + /* These flags are set by wined3d_device_setup_fullscreen_window, not the + * application, and we want to ignore them in the test below, since it's + * not the application's fault that they changed. Additionally, we want to + * preserve the current status of these flags (i.e. don't restore them) to + * more closely emulate the behavior of Direct3D, which leaves these flags + * alone when returning to windowed mode. */ + state->style ^= (state->style ^ style) & WS_VISIBLE; + state->exstyle ^= (state->exstyle ^ exstyle) & WS_EX_TOPMOST; + + TRACE("Restoring window style of window %p to %08x, %08x.\n", + window, state->style, state->exstyle); + + filter = wined3d_filter_messages(window, TRUE); + + /* Only restore the style if the application didn't modify it during the + * fullscreen phase. Some applications change it before calling Reset() + * when switching between windowed and fullscreen modes (HL2), some + * depend on the original style (Eve Online). */ + if (style == fullscreen_style(state->style) && exstyle == fullscreen_exstyle(state->exstyle)) + { + SetWindowLongW(window, GWL_STYLE, state->style); + SetWindowLongW(window, GWL_EXSTYLE, state->exstyle); + } + + if (window_rect) + rect = *window_rect; + else + window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(window, 0, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); + + wined3d_filter_messages(window, filter); + + /* Delete the old values. */ + state->style = 0; + state->exstyle = 0; +} + +HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state, + const struct wined3d_swapchain_desc *swapchain_desc, struct wined3d *wined3d, + unsigned int adapter_idx, const struct wined3d_display_mode *mode) { - struct wined3d_device *device = swapchain->device; struct wined3d_display_mode actual_mode; HRESULT hr; - TRACE("swapchain %p, desc %p, mode %p.\n", swapchain, swapchain_desc, mode); + TRACE("state %p, swapchain_desc %p, wined3d %p, adapter_idx %u, mode %p.\n", + state, swapchain_desc, wined3d, adapter_idx, mode); - if (swapchain->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) + if (state->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) { if (mode) { @@ -1385,19 +1592,22 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha { if (!swapchain_desc->windowed) { + const struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx]; + actual_mode.width = swapchain_desc->backbuffer_width; actual_mode.height = swapchain_desc->backbuffer_height; actual_mode.refresh_rate = swapchain_desc->refresh_rate; - actual_mode.format_id = swapchain_desc->backbuffer_format; + actual_mode.format_id = adapter_format_from_backbuffer_format(adapter, + swapchain_desc->backbuffer_format); actual_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; } else { - actual_mode = swapchain->original_mode; + actual_mode = state->original_mode; } } - if (FAILED(hr = wined3d_swapchain_set_display_mode(swapchain, &actual_mode))) + if (FAILED(hr = wined3d_swapchain_state_set_display_mode(state, wined3d, adapter_idx, &actual_mode))) return hr; } else @@ -1405,8 +1615,7 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha if (mode) WARN("WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH is not set, ignoring mode.\n"); - if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, - &actual_mode, NULL))) + if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &actual_mode, NULL))) { ERR("Failed to get display mode, hr %#x.\n", hr); return WINED3DERR_INVALIDCALL; @@ -1418,44 +1627,65 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha unsigned int width = actual_mode.width; unsigned int height = actual_mode.height; - if (swapchain->desc.windowed) + if (state->desc.windowed) { /* Switch from windowed to fullscreen */ - HWND focus_window = device->create_parms.focus_window; - if (!focus_window) - focus_window = swapchain->device_window; - if (FAILED(hr = wined3d_device_acquire_focus_window(device, focus_window))) - { - ERR("Failed to acquire focus window, hr %#x.\n", hr); + if (FAILED(hr = wined3d_swapchain_state_setup_fullscreen(state, state->device_window, width, height))) return hr; - } - - wined3d_device_setup_fullscreen_window(device, swapchain->device_window, width, height); } else { - /* Fullscreen -> fullscreen mode change */ - BOOL filter_messages = device->filter_messages; - device->filter_messages = TRUE; + HWND window = state->device_window; + BOOL filter; - MoveWindow(swapchain->device_window, 0, 0, width, height, TRUE); - ShowWindow(swapchain->device_window, SW_SHOW); - - device->filter_messages = filter_messages; + /* Fullscreen -> fullscreen mode change */ + filter = wined3d_filter_messages(window, TRUE); + MoveWindow(window, 0, 0, width, height, TRUE); + ShowWindow(window, SW_SHOW); + wined3d_filter_messages(window, filter); } - swapchain->d3d_mode = actual_mode; + state->d3d_mode = actual_mode; } - else if (!swapchain->desc.windowed) + else if (!state->desc.windowed) { /* Fullscreen -> windowed switch */ RECT *window_rect = NULL; - if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) - window_rect = &swapchain->original_window_rect; - wined3d_device_restore_fullscreen_window(device, swapchain->device_window, window_rect); - wined3d_device_release_focus_window(device); + if (state->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) + window_rect = &state->original_window_rect; + wined3d_swapchain_state_restore_from_fullscreen(state, state->device_window, window_rect); } - swapchain->desc.windowed = swapchain_desc->windowed; + state->desc.windowed = swapchain_desc->windowed; return WINED3D_OK; } + +void CDECL wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state) +{ + heap_free(state); +} + +HRESULT CDECL wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc, + HWND window, struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_swapchain_state **state) +{ + struct wined3d_swapchain_state *s; + HRESULT hr; + + TRACE("desc %p, window %p, wined3d %p, adapter_idx %u, state %p.\n", + desc, window, wined3d, adapter_idx, state); + + TRACE("desc %p, window %p, state %p.\n", desc, window, state); + + if (!(s = heap_alloc_zero(sizeof(*s)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_state_init(s, desc, window, wined3d, adapter_idx))) + { + heap_free(s); + return hr; + } + + *state = s; + + return hr; +} diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c index e6af0c75088..abdd7625101 100644 --- a/dll/directx/wine/wined3d/texture.c +++ b/dll/directx/wine/wined3d/texture.c @@ -30,13 +30,35 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); #define WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD 50 +static const uint32_t wined3d_texture_sysmem_locations = WINED3D_LOCATION_SYSMEM + | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER; +static const struct wined3d_texture_ops texture_gl_ops; + +struct wined3d_texture_idx +{ + struct wined3d_texture *texture; + unsigned int sub_resource_idx; +}; + +struct wined3d_rect_f +{ + float l; + float t; + float r; + float b; +}; + static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) { - return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) - && texture->resource.usage & WINED3DUSAGE_DYNAMIC - && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] - && !texture->resource.format->conv_byte_count - && !(texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED)); + if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] + || texture->resource.format->conv_byte_count + || (texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED))) + return FALSE; + + /* Use a PBO for dynamic textures and read-only staging textures. */ + return (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) + && texture->resource.usage & WINED3DUSAGE_DYNAMIC) + || texture->resource.access == (WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R); } static BOOL wined3d_texture_use_immutable_storage(const struct wined3d_texture *texture, @@ -48,6 +70,32 @@ static BOOL wined3d_texture_use_immutable_storage(const struct wined3d_texture * && !(texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE); } +/* Front buffer coordinates are always full screen coordinates, but our GL + * drawable is limited to the window's client area. The sysmem and texture + * copies do have the full screen size. Note that GL has a bottom-left + * origin, while D3D has a top-left origin. */ +void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, HWND window, RECT *rect) +{ + unsigned int drawable_height; + POINT offset = {0, 0}; + RECT windowsize; + + if (!texture->swapchain) + return; + + if (texture == texture->swapchain->front_buffer) + { + ScreenToClient(window, &offset); + OffsetRect(rect, offset.x, offset.y); + } + + GetClientRect(window, &windowsize); + drawable_height = windowsize.bottom - windowsize.top; + + rect->top = drawable_height - rect->top; + rect->bottom = drawable_height - rect->bottom; +} + GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) { const struct wined3d_swapchain *swapchain = texture->swapchain; @@ -101,9 +149,120 @@ static DWORD wined3d_resource_access_from_location(DWORD location) } } -static BOOL is_power_of_two(UINT x) +static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct wined3d_rect_f *f) +{ + f->l = ((r->left * 2.0f) / w) - 1.0f; + f->t = ((r->top * 2.0f) / h) - 1.0f; + f->r = ((r->right * 2.0f) / w) - 1.0f; + f->b = ((r->bottom * 2.0f) / h) - 1.0f; +} + +void texture2d_get_blt_info(const struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info) { - return (x != 0) && !(x & (x - 1)); + struct wined3d_vec3 *coords = info->texcoords; + struct wined3d_rect_f f; + unsigned int level; + GLenum target; + GLsizei w, h; + + level = sub_resource_idx % texture_gl->t.level_count; + w = wined3d_texture_get_level_pow2_width(&texture_gl->t, level); + h = wined3d_texture_get_level_pow2_height(&texture_gl->t, level); + target = wined3d_texture_gl_get_sub_resource_target(texture_gl, sub_resource_idx); + + switch (target) + { + default: + FIXME("Unsupported texture target %#x.\n", target); + /* Fall back to GL_TEXTURE_2D */ + case GL_TEXTURE_2D: + info->bind_target = GL_TEXTURE_2D; + coords[0].x = (float)rect->left / w; + coords[0].y = (float)rect->top / h; + coords[0].z = 0.0f; + + coords[1].x = (float)rect->right / w; + coords[1].y = (float)rect->top / h; + coords[1].z = 0.0f; + + coords[2].x = (float)rect->left / w; + coords[2].y = (float)rect->bottom / h; + coords[2].z = 0.0f; + + coords[3].x = (float)rect->right / w; + coords[3].y = (float)rect->bottom / h; + coords[3].z = 0.0f; + break; + + case GL_TEXTURE_RECTANGLE_ARB: + info->bind_target = GL_TEXTURE_RECTANGLE_ARB; + coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f; + coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f; + coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f; + coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + cube_coords_float(rect, w, h, &f); + + coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l; + coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r; + coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l; + coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + cube_coords_float(rect, w, h, &f); + + coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l; + coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r; + coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l; + coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + cube_coords_float(rect, w, h, &f); + + coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t; + coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t; + coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b; + coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + cube_coords_float(rect, w, h, &f); + + coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t; + coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t; + coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b; + coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + cube_coords_float(rect, w, h, &f); + + coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f; + coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f; + coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f; + coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + cube_coords_float(rect, w, h, &f); + + coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f; + coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f; + coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f; + coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f; + break; + } } static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture) @@ -199,7 +358,7 @@ static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture if (dst.buffer_object) { context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + gl_info = wined3d_context_gl(context)->gl_info; GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); @@ -211,7 +370,7 @@ static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture if (src.buffer_object) { context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + gl_info = wined3d_context_gl(context)->gl_info; GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); @@ -229,8 +388,6 @@ static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture BOOL wined3d_texture_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) { - static const DWORD sysmem_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY - | WINED3D_LOCATION_BUFFER; DWORD current = texture->sub_resources[sub_resource_idx].locations; BOOL ret; @@ -271,7 +428,7 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, return wined3d_texture_load_location(texture, sub_resource_idx, context, location); } - if ((location & sysmem_locations) && (current & sysmem_locations)) + if ((location & wined3d_texture_sysmem_locations) && (current & wined3d_texture_sysmem_locations)) ret = wined3d_texture_copy_sysmem_location(texture, sub_resource_idx, context, location); else ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location); @@ -294,11 +451,7 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su if (locations & WINED3D_LOCATION_BUFFER) { data->addr = NULL; -#if !defined(STAGING_CSMT) data->buffer_object = sub_resource->buffer_object; -#else /* STAGING_CSMT */ - data->buffer_object = sub_resource->buffer->name; -#endif /* STAGING_CSMT */ return; } if (locations & WINED3D_LOCATION_USER_MEMORY) @@ -320,93 +473,8 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su data->buffer_object = 0; } -static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops, - UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD flags, - struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops, - const struct wined3d_resource_ops *resource_ops) -{ - unsigned int i, j, size, offset = 0; - const struct wined3d_format *format; - HRESULT hr; - - TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, " - "multisample_type %#x, multisample_quality %#x, usage %s, access %s, width %u, height %u, depth %u, " - "flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n", - texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type), - debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality, - debug_d3dusage(desc->usage), wined3d_debug_resource_access(desc->access), - desc->width, desc->height, desc->depth, flags, device, parent, parent_ops, resource_ops); - - if (!desc->width || !desc->height || !desc->depth) - return WINED3DERR_INVALIDCALL; - - format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage); - - for (i = 0; i < layer_count; ++i) - { - for (j = 0; j < level_count; ++j) - { - unsigned int idx = i * level_count + j; - - size = wined3d_format_calculate_size(format, device->surface_alignment, - max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j)); - texture->sub_resources[idx].offset = offset; - texture->sub_resources[idx].size = size; - offset += size; - } - offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1); - } - - if (!offset) - return WINED3DERR_INVALIDCALL; - - if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, - desc->multisample_type, desc->multisample_quality, desc->usage, desc->access, - desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops))) - { - static unsigned int once; - - /* DXTn 3D textures are not supported. Do not write the ERR for them. */ - if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3 - || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5) - && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) - && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++) - ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n"); - - WARN("Failed to initialize resource, returning %#x\n", hr); - return hr; - } - wined3d_resource_update_draw_binding(&texture->resource); - if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE) - texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; - - texture->texture_ops = texture_ops; - - texture->layer_count = layer_count; - texture->level_count = level_count; - texture->lod = 0; - texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; - if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) - texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT; - if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)) - texture->flags |= WINED3D_TEXTURE_GET_DC; - if (flags & WINED3D_TEXTURE_CREATE_DISCARD) - texture->flags |= WINED3D_TEXTURE_DISCARD; - if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS) - { - if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP)) - WARN("Format doesn't support mipmaps generation, " - "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); - else - texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS; - } - - return WINED3D_OK; -} - /* Context activation is done by the caller. */ static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, -#if !defined(STAGING_CSMT) unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) { GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object; @@ -419,25 +487,12 @@ static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); *buffer_object = 0; -#else /* STAGING_CSMT */ - unsigned int sub_resource_idx, struct wined3d_context *context) -{ - struct wined3d_gl_bo *buffer = texture->sub_resources[sub_resource_idx].buffer; - GLuint name = buffer->name; - - wined3d_device_release_bo(texture->resource.device, buffer, context); - texture->sub_resources[sub_resource_idx].buffer = NULL; - wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); - - TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n", - name, texture, sub_resource_idx); -#endif /* STAGING_CSMT */ } static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) { unsigned int sub_count = texture->level_count * texture->layer_count; - const struct wined3d_device *device = texture->resource.device; + struct wined3d_device *device = texture->resource.device; DWORD map_binding = texture->update_map_binding; struct wined3d_context *context = NULL; unsigned int i; @@ -451,11 +506,7 @@ static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) && !wined3d_texture_load_location(texture, i, context, map_binding)) ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding)); if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER) -#if !defined(STAGING_CSMT) - wined3d_texture_remove_buffer_object(texture, i, context->gl_info); -#else /* STAGING_CSMT */ - wined3d_texture_remove_buffer_object(texture, i, context); -#endif /* STAGING_CSMT */ + wined3d_texture_remove_buffer_object(texture, i, wined3d_context_gl(context)->gl_info); } if (context) @@ -481,78 +532,57 @@ static void gltexture_delete(struct wined3d_device *device, const struct wined3d tex->name = 0; } -static unsigned int wined3d_texture_get_gl_sample_count(const struct wined3d_texture *texture) -{ - const struct wined3d_format *format = texture->resource.format; - - /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA) - * feature through type == MULTISAMPLE_XX and quality != 0. This could - * be mapped to GL_NV_framebuffer_multisample_coverage. - * - * AMD have a similar feature called Enhanced Quality Anti-Aliasing - * (EQAA), but it does not have an equivalent OpenGL extension. */ - - /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality - * levels as the count of advertised multisample types for the texture - * format. */ - if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) - { - unsigned int i, count = 0; - - for (i = 0; i < sizeof(format->multisample_types) * CHAR_BIT; ++i) - { - if (format->multisample_types & 1u << i) - { - if (texture->resource.multisample_quality == count++) - break; - } - } - return i + 1; - } - - return texture->resource.multisample_type; -} - /* Context activation is done by the caller. */ /* The caller is responsible for binding the correct texture. */ -static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *texture, - GLenum gl_internal_format, const struct wined3d_format *format, +static void wined3d_texture_gl_allocate_mutable_storage(struct wined3d_texture_gl *texture_gl, + GLenum gl_internal_format, const struct wined3d_format_gl *format, const struct wined3d_gl_info *gl_info) { unsigned int level, level_count, layer, layer_count; - GLsizei width, height; + GLsizei width, height, depth; GLenum target; - level_count = texture->level_count; - layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count; + level_count = texture_gl->t.level_count; + if (texture_gl->target == GL_TEXTURE_1D_ARRAY || texture_gl->target == GL_TEXTURE_2D_ARRAY) + layer_count = 1; + else + layer_count = texture_gl->t.layer_count; for (layer = 0; layer < layer_count; ++layer) { - target = wined3d_texture_get_sub_resource_target(texture, layer * level_count); + target = wined3d_texture_gl_get_sub_resource_target(texture_gl, layer * level_count); for (level = 0; level < level_count; ++level) { - width = wined3d_texture_get_level_pow2_width(texture, level); - height = wined3d_texture_get_level_pow2_height(texture, level); - if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE) + width = wined3d_texture_get_level_pow2_width(&texture_gl->t, level); + height = wined3d_texture_get_level_pow2_height(&texture_gl->t, level); + if (texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE) { - height *= format->height_scale.numerator; - height /= format->height_scale.denominator; + height *= format->f.height_scale.numerator; + height /= format->f.height_scale.denominator; } - TRACE("texture %p, layer %u, level %u, target %#x, width %u, height %u.\n", - texture, layer, level, target, width, height); + TRACE("texture_gl %p, layer %u, level %u, target %#x, width %u, height %u.\n", + texture_gl, layer, level, target, width, height); - if (texture->target == GL_TEXTURE_2D_ARRAY) + if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) { + depth = wined3d_texture_get_level_depth(&texture_gl->t, level); GL_EXTCALL(glTexImage3D(target, level, gl_internal_format, width, height, - texture->layer_count, 0, format->glFormat, format->glType, NULL)); + target == GL_TEXTURE_2D_ARRAY ? texture_gl->t.layer_count : depth, 0, + format->format, format->type, NULL)); checkGLcall("glTexImage3D"); } + else if (target == GL_TEXTURE_1D) + { + gl_info->gl_ops.gl.p_glTexImage1D(target, level, gl_internal_format, + width, 0, format->format, format->type, NULL); + } else { - gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, - width, height, 0, format->glFormat, format->glType, NULL); + gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, width, + target == GL_TEXTURE_1D_ARRAY ? texture_gl->t.layer_count : height, 0, + format->format, format->type, NULL); checkGLcall("glTexImage2D"); } } @@ -561,29 +591,42 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture * /* Context activation is done by the caller. */ /* The caller is responsible for binding the correct texture. */ -static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture *texture, +static void wined3d_texture_gl_allocate_immutable_storage(struct wined3d_texture_gl *texture_gl, GLenum gl_internal_format, const struct wined3d_gl_info *gl_info) { - unsigned int samples = wined3d_texture_get_gl_sample_count(texture); - GLsizei height = wined3d_texture_get_level_pow2_height(texture, 0); - GLsizei width = wined3d_texture_get_level_pow2_width(texture, 0); + unsigned int samples = wined3d_resource_get_sample_count(&texture_gl->t.resource); + GLsizei height = wined3d_texture_get_level_pow2_height(&texture_gl->t, 0); + GLsizei width = wined3d_texture_get_level_pow2_width(&texture_gl->t, 0); + GLboolean standard_pattern = texture_gl->t.resource.multisample_type != WINED3D_MULTISAMPLE_NON_MASKABLE + && texture_gl->t.resource.multisample_quality == WINED3D_STANDARD_MULTISAMPLE_PATTERN; - switch (texture->target) + switch (texture_gl->target) { + case GL_TEXTURE_3D: + GL_EXTCALL(glTexStorage3D(texture_gl->target, texture_gl->t.level_count, + gl_internal_format, width, height, wined3d_texture_get_level_depth(&texture_gl->t, 0))); + break; case GL_TEXTURE_2D_ARRAY: - GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count, - gl_internal_format, width, height, texture->layer_count)); + GL_EXTCALL(glTexStorage3D(texture_gl->target, texture_gl->t.level_count, + gl_internal_format, width, height, texture_gl->t.layer_count)); break; case GL_TEXTURE_2D_MULTISAMPLE: - GL_EXTCALL(glTexStorage2DMultisample(texture->target, samples, - gl_internal_format, width, height, GL_FALSE)); + GL_EXTCALL(glTexStorage2DMultisample(texture_gl->target, samples, + gl_internal_format, width, height, standard_pattern)); break; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples, - gl_internal_format, width, height, texture->layer_count, GL_FALSE)); + GL_EXTCALL(glTexStorage3DMultisample(texture_gl->target, samples, + gl_internal_format, width, height, texture_gl->t.layer_count, standard_pattern)); + break; + case GL_TEXTURE_1D_ARRAY: + GL_EXTCALL(glTexStorage2D(texture_gl->target, texture_gl->t.level_count, + gl_internal_format, width, texture_gl->t.layer_count)); + break; + case GL_TEXTURE_1D: + GL_EXTCALL(glTexStorage1D(texture_gl->target, texture_gl->t.level_count, gl_internal_format, width)); break; default: - GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, + GL_EXTCALL(glTexStorage2D(texture_gl->target, texture_gl->t.level_count, gl_internal_format, width, height)); break; } @@ -591,49 +634,52 @@ static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture checkGLcall("allocate immutable storage"); } -static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture) +void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) { - struct wined3d_device *device = texture->resource.device; + struct wined3d_device *device = texture_gl->t.resource.device; const struct wined3d_gl_info *gl_info = NULL; struct wined3d_context *context = NULL; - if (texture->texture_rgb.name || texture->texture_srgb.name - || texture->rb_multisample || texture->rb_resolved) + if (texture_gl->t.resource.bind_count) + device_invalidate_state(device, STATE_SAMPLER(texture_gl->t.sampler)); + + if (texture_gl->texture_rgb.name || texture_gl->texture_srgb.name + || texture_gl->rb_multisample || texture_gl->rb_resolved) { context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + gl_info = wined3d_context_gl(context)->gl_info; } - if (texture->texture_rgb.name) - gltexture_delete(device, context->gl_info, &texture->texture_rgb); + if (texture_gl->texture_rgb.name) + gltexture_delete(device, gl_info, &texture_gl->texture_rgb); - if (texture->texture_srgb.name) - gltexture_delete(device, context->gl_info, &texture->texture_srgb); + if (texture_gl->texture_srgb.name) + gltexture_delete(device, gl_info, &texture_gl->texture_srgb); - if (texture->rb_multisample) + if (texture_gl->rb_multisample) { - TRACE("Deleting multisample renderbuffer %u.\n", texture->rb_multisample); - context_gl_resource_released(device, texture->rb_multisample, TRUE); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_multisample); - texture->rb_multisample = 0; + TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample); + context_gl_resource_released(device, texture_gl->rb_multisample, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample); + texture_gl->rb_multisample = 0; } - if (texture->rb_resolved) + if (texture_gl->rb_resolved) { - TRACE("Deleting resolved renderbuffer %u.\n", texture->rb_resolved); - context_gl_resource_released(device, texture->rb_resolved, TRUE); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_resolved); - texture->rb_resolved = 0; + TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved); + context_gl_resource_released(device, texture_gl->rb_resolved, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved); + texture_gl->rb_resolved = 0; } if (context) context_release(context); - wined3d_texture_set_dirty(texture); + wined3d_texture_set_dirty(&texture_gl->t); - resource_unload(&texture->resource); + resource_unload(&texture_gl->t.resource); } -static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) +void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) { unsigned int sub_count = texture->level_count * texture->layer_count; struct wined3d_texture_sub_resource *sub_resource; @@ -651,72 +697,132 @@ static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *text } } -static void wined3d_texture_cleanup(struct wined3d_texture *texture) +static void wined3d_texture_create_dc(void *object) { - unsigned int sub_count = texture->level_count * texture->layer_count; - struct wined3d_device *device = texture->resource.device; + const struct wined3d_texture_idx *idx = object; struct wined3d_context *context = NULL; -#if !defined(STAGING_CSMT) - const struct wined3d_gl_info *gl_info; - GLuint buffer_object; -#else /* STAGING_CSMT */ - struct wined3d_gl_bo *buffer; -#endif /* STAGING_CSMT */ - unsigned int i; + unsigned int sub_resource_idx, level; + const struct wined3d_format *format; + unsigned int row_pitch, slice_pitch; + struct wined3d_texture *texture; + struct wined3d_dc_info *dc_info; + struct wined3d_bo_address data; + D3DKMT_CREATEDCFROMMEMORY desc; + struct wined3d_device *device; + NTSTATUS status; - TRACE("texture %p.\n", texture); + TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx); - for (i = 0; i < sub_count; ++i) - { -#if !defined(STAGING_CSMT) - if (!(buffer_object = texture->sub_resources[i].buffer_object)) - continue; + texture = idx->texture; + sub_resource_idx = idx->sub_resource_idx; + level = sub_resource_idx % texture->level_count; + device = texture->resource.device; - TRACE("Deleting buffer object %u.\n", buffer_object); -#else /* STAGING_CSMT */ - if (!(buffer = texture->sub_resources[i].buffer)) - continue; + format = texture->resource.format; + if (!format->ddi_format) + { + WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id)); + return; + } - TRACE("Deleting buffer object %u.\n", buffer->name); -#endif /* STAGING_CSMT */ + if (!texture->dc_info) + { + unsigned int sub_count = texture->level_count * texture->layer_count; - /* We may not be able to get a context in wined3d_texture_cleanup() in - * general, but if a buffer object was previously created we can. */ - if (!context) -#if !defined(STAGING_CSMT) + if (!(texture->dc_info = heap_calloc(sub_count, sizeof(*texture->dc_info)))) { - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + ERR("Failed to allocate DC info.\n"); + return; } + } - GL_EXTCALL(glDeleteBuffers(1, &buffer_object)); -#else /* STAGING_CSMT */ + if (!(texture->sub_resources[sub_resource_idx].locations & texture->resource.map_binding)) + { + context = context_acquire(device, NULL, 0); + wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); + } + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); + wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + if (data.buffer_object) + { + if (!context) context = context_acquire(device, NULL, 0); - - wined3d_device_release_bo(device, buffer, context); - texture->sub_resources[i].buffer = NULL; -#endif /* STAGING_CSMT */ + desc.pMemory = wined3d_context_map_bo_address(context, &data, + texture->sub_resources[sub_resource_idx].size, 0, WINED3D_MAP_READ | WINED3D_MAP_WRITE); } + else + { + desc.pMemory = data.addr; + } + if (context) context_release(context); - texture->texture_ops->texture_cleanup_sub_resources(texture); - if (texture->overlay_info) + desc.Format = format->ddi_format; + desc.Width = wined3d_texture_get_level_width(texture, level); + desc.Height = wined3d_texture_get_level_height(texture, level); + desc.Pitch = row_pitch; + desc.hDeviceDc = CreateCompatibleDC(NULL); + desc.pColorTable = NULL; + + status = D3DKMTCreateDCFromMemory(&desc); + DeleteDC(desc.hDeviceDc); + if (status) { - for (i = 0; i < sub_count; ++i) - { - struct wined3d_overlay_info *info = &texture->overlay_info[i]; - struct wined3d_overlay_info *overlay, *cur; + WARN("Failed to create DC, status %#x.\n", status); + return; + } - list_remove(&info->entry); - LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry) - { - list_remove(&overlay->entry); - } - } - heap_free(texture->overlay_info); + dc_info = &texture->dc_info[sub_resource_idx]; + dc_info->dc = desc.hDc; + dc_info->bitmap = desc.hBitmap; + + TRACE("Created DC %p, bitmap %p for texture %p, %u.\n", dc_info->dc, dc_info->bitmap, texture, sub_resource_idx); +} + +static void wined3d_texture_destroy_dc(void *object) +{ + const struct wined3d_texture_idx *idx = object; + D3DKMT_DESTROYDCFROMMEMORY destroy_desc; + struct wined3d_context *context; + struct wined3d_texture *texture; + struct wined3d_dc_info *dc_info; + struct wined3d_bo_address data; + struct wined3d_map_range range; + unsigned int sub_resource_idx; + struct wined3d_device *device; + NTSTATUS status; + + texture = idx->texture; + sub_resource_idx = idx->sub_resource_idx; + device = texture->resource.device; + dc_info = &texture->dc_info[sub_resource_idx]; + + if (!dc_info->dc) + { + ERR("Sub-resource {%p, %u} has no DC.\n", texture, sub_resource_idx); + return; + } + + TRACE("dc %p, bitmap %p.\n", dc_info->dc, dc_info->bitmap); + + destroy_desc.hDc = dc_info->dc; + destroy_desc.hBitmap = dc_info->bitmap; + if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) + ERR("Failed to destroy dc, status %#x.\n", status); + dc_info->dc = NULL; + dc_info->bitmap = NULL; + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + if (data.buffer_object) + { + context = context_acquire(device, NULL, 0); + range.offset = 0; + range.size = texture->sub_resources[sub_resource_idx].size; + wined3d_context_unmap_bo_address(context, &data, 0, 1, &range); + context_release(context); } - wined3d_texture_unload_gl_texture(texture); } void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) @@ -725,33 +831,51 @@ void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined wined3d_resource_update_draw_binding(&texture->resource); } +void wined3d_gl_texture_swizzle_from_color_fixup(GLint swizzle[4], struct color_fixup_desc fixup) +{ + static const GLenum swizzle_source[] = + { + GL_ZERO, /* CHANNEL_SOURCE_ZERO */ + GL_ONE, /* CHANNEL_SOURCE_ONE */ + GL_RED, /* CHANNEL_SOURCE_X */ + GL_GREEN, /* CHANNEL_SOURCE_Y */ + GL_BLUE, /* CHANNEL_SOURCE_Z */ + GL_ALPHA, /* CHANNEL_SOURCE_W */ + }; + + swizzle[0] = swizzle_source[fixup.x_source]; + swizzle[1] = swizzle_source[fixup.y_source]; + swizzle[2] = swizzle_source[fixup.z_source]; + swizzle[3] = swizzle_source[fixup.w_source]; +} + /* Context activation is done by the caller. */ -void wined3d_texture_bind(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) +void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, BOOL srgb) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_format *format = texture->resource.format; + const struct wined3d_format *format = texture_gl->t.resource.format; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct color_fixup_desc fixup = format->color_fixup; struct gl_texture *gl_tex; GLenum target; - TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); + TRACE("texture_gl %p, context_gl %p, srgb %#x.\n", texture_gl, context_gl, srgb); - if (!needs_separate_srgb_gl_texture(context, texture)) + if (!needs_separate_srgb_gl_texture(&context_gl->c, &texture_gl->t)) srgb = FALSE; /* sRGB mode cache for preload() calls outside drawprim. */ if (srgb) - texture->flags |= WINED3D_TEXTURE_IS_SRGB; + texture_gl->t.flags |= WINED3D_TEXTURE_IS_SRGB; else - texture->flags &= ~WINED3D_TEXTURE_IS_SRGB; + texture_gl->t.flags &= ~WINED3D_TEXTURE_IS_SRGB; - gl_tex = wined3d_texture_get_gl_texture(texture, srgb); - target = texture->target; + gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, srgb); + target = texture_gl->target; if (gl_tex->name) { - context_bind_texture(context, target, gl_tex->name); + wined3d_context_gl_bind_texture(context_gl, target, gl_tex->name); return; } @@ -780,14 +904,14 @@ void wined3d_texture_bind(struct wined3d_texture *texture, gl_tex->sampler_desc.max_anisotropy = 1; gl_tex->sampler_desc.compare = FALSE; gl_tex->sampler_desc.comparison_func = WINED3D_CMP_LESSEQUAL; - if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) gl_tex->sampler_desc.srgb_decode = TRUE; else gl_tex->sampler_desc.srgb_decode = srgb; gl_tex->base_level = 0; - wined3d_texture_set_dirty(texture); + wined3d_texture_set_dirty(&texture_gl->t); - context_bind_texture(context, target, gl_tex->name); + wined3d_context_gl_bind_texture(context_gl, target, gl_tex->name); /* For a new texture we have to set the texture levels after binding the * texture. Beware that texture rectangles do not support mipmapping, but @@ -797,8 +921,8 @@ void wined3d_texture_bind(struct wined3d_texture *texture, * GL_TEXTURE_RECTANGLE_ARB.) */ if (target != GL_TEXTURE_RECTANGLE_ARB) { - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture->level_count - 1); - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture_gl->t.level_count - 1); + gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture_gl->t.level_count - 1); checkGLcall("glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count)"); } @@ -810,7 +934,7 @@ void wined3d_texture_bind(struct wined3d_texture *texture, gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); } - if (texture->flags & WINED3D_TEXTURE_COND_NP2) + if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) { /* Conditinal non power of two textures use a different clamping * default. If we're using the GL_WINE_normalized_texrect partial @@ -838,35 +962,19 @@ void wined3d_texture_bind(struct wined3d_texture *texture, checkGLcall("glTexParameteri(GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)"); } - if (!is_identity_fixup(fixup) && can_use_texture_swizzle(gl_info, format)) + if (!is_identity_fixup(fixup) && can_use_texture_swizzle(context_gl->c.d3d_info, format)) { - static const GLenum swizzle_source[] = - { - GL_ZERO, /* CHANNEL_SOURCE_ZERO */ - GL_ONE, /* CHANNEL_SOURCE_ONE */ - GL_RED, /* CHANNEL_SOURCE_X */ - GL_GREEN, /* CHANNEL_SOURCE_Y */ - GL_BLUE, /* CHANNEL_SOURCE_Z */ - GL_ALPHA, /* CHANNEL_SOURCE_W */ - }; - struct - { - GLint x, y, z, w; - } - swizzle; + GLint swizzle[4]; - swizzle.x = swizzle_source[fixup.x_source]; - swizzle.y = swizzle_source[fixup.y_source]; - swizzle.z = swizzle_source[fixup.z_source]; - swizzle.w = swizzle_source[fixup.w_source]; - gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, &swizzle.x); - checkGLcall("glTexParameteriv(GL_TEXTURE_SWIZZLE_RGBA)"); + wined3d_gl_texture_swizzle_from_color_fixup(swizzle, fixup); + gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + checkGLcall("set format swizzle"); } } /* Context activation is done by the caller. */ -void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) +void wined3d_texture_gl_bind_and_dirtify(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, BOOL srgb) { /* We don't need a specific texture unit, but after binding the texture * the current unit is dirty. Read the unit back instead of switching to @@ -877,33 +985,33 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, * called from sampler() in state.c. This means we can't touch anything * other than whatever happens to be the currently active texture, or we * would risk marking already applied sampler states dirty again. */ - if (context->active_texture < ARRAY_SIZE(context->rev_tex_unit_map)) + if (context_gl->active_texture < ARRAY_SIZE(context_gl->rev_tex_unit_map)) { - DWORD active_sampler = context->rev_tex_unit_map[context->active_texture]; + unsigned int active_sampler = context_gl->rev_tex_unit_map[context_gl->active_texture]; if (active_sampler != WINED3D_UNMAPPED_STAGE) - context_invalidate_state(context, STATE_SAMPLER(active_sampler)); + context_invalidate_state(&context_gl->c, STATE_SAMPLER(active_sampler)); } /* FIXME: Ideally we'd only do this when touching a binding that's used by * a shader. */ - context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); - context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + context_invalidate_compute_state(&context_gl->c, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); - wined3d_texture_bind(texture, context, srgb); + wined3d_texture_gl_bind(texture_gl, context_gl, srgb); } /* Context activation is done by the caller (state handler). */ /* This function relies on the correct texture being bound and loaded. */ -void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, - const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context) +void wined3d_texture_gl_apply_sampler_desc(struct wined3d_texture_gl *texture_gl, + const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum target = texture->target; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + GLenum target = texture_gl->target; struct gl_texture *gl_tex; DWORD state; - TRACE("texture %p, sampler_desc %p, context %p.\n", texture, sampler_desc, context); + TRACE("texture_gl %p, sampler_desc %p, context_gl %p.\n", texture_gl, sampler_desc, context_gl); - gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB); + gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, texture_gl->t.flags & WINED3D_TEXTURE_IS_SRGB); state = sampler_desc->address_u; if (state != gl_tex->sampler_desc.address_u) @@ -964,7 +1072,7 @@ void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, } if (!sampler_desc->srgb_decode != !gl_tex->sampler_desc.srgb_decode - && (context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) + && (context_gl->c.d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) { gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, @@ -1006,18 +1114,83 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture) return refcount; } -static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture) +static void wined3d_texture_destroy_object(void *object) { - wined3d_texture_sub_resources_destroyed(texture); - resource_cleanup(&texture->resource); - wined3d_resource_wait_idle(&texture->resource); - wined3d_texture_cleanup(texture); + const struct wined3d_gl_info *gl_info = NULL; + struct wined3d_texture *texture = object; + struct wined3d_context *context = NULL; + struct wined3d_dc_info *dc_info; + unsigned int sub_count; + GLuint buffer_object; + unsigned int i; + + TRACE("texture %p.\n", texture); + + sub_count = texture->level_count * texture->layer_count; + for (i = 0; i < sub_count; ++i) + { + if (!(buffer_object = texture->sub_resources[i].buffer_object)) + continue; + + TRACE("Deleting buffer object %u.\n", buffer_object); + + /* We may not be able to get a context in + * wined3d_texture_destroy_object() in general, but if a buffer object + * was previously created we can. */ + if (!context) + { + context = context_acquire(texture->resource.device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; + } + + GL_EXTCALL(glDeleteBuffers(1, &buffer_object)); + } + + if (context) + context_release(context); + + if ((dc_info = texture->dc_info)) + { + for (i = 0; i < sub_count; ++i) + { + if (dc_info[i].dc) + { + struct wined3d_texture_idx texture_idx = {texture, i}; + + wined3d_texture_destroy_dc(&texture_idx); + } + } + heap_free(dc_info); + } + + if (texture->overlay_info) + { + for (i = 0; i < sub_count; ++i) + { + struct wined3d_overlay_info *info = &texture->overlay_info[i]; + struct wined3d_overlay_info *overlay, *cur; + + list_remove(&info->entry); + LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry) + { + list_remove(&overlay->entry); + } + } + heap_free(texture->overlay_info); + } } -static void wined3d_texture_destroy_object(void *object) +void wined3d_texture_cleanup(struct wined3d_texture *texture) +{ + resource_cleanup(&texture->resource); + wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture); +} + +static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture) { - wined3d_texture_cleanup(object); - heap_free(object); + wined3d_texture_sub_resources_destroyed(texture); + wined3d_texture_cleanup(texture); + wined3d_resource_wait_idle(&texture->resource); } ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) @@ -1037,13 +1210,10 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) /* Wait for the texture to become idle if it's using user memory, * since the application is allowed to free that memory once the * texture is destroyed. Note that this implies that - * wined3d_texture_destroy_object() can't access that memory either. */ + * the destroy handler can't access that memory either. */ if (texture->user_memory) wined3d_resource_wait_idle(&texture->resource); - wined3d_texture_sub_resources_destroyed(texture); - texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); - resource_cleanup(&texture->resource); - wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture); + texture->resource.device->adapter->adapter_ops->adapter_destroy_texture(texture); } return refcount; @@ -1185,16 +1355,18 @@ void CDECL wined3d_texture_get_pitch(const struct wined3d_texture *texture, DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) { + struct wined3d_resource *resource; DWORD old = texture->lod; TRACE("texture %p, lod %u.\n", texture, lod); /* The d3d9:texture test shows that SetLOD is ignored on non-managed * textures. The call always returns 0, and GetLOD always returns 0. */ - if (!wined3d_resource_access_is_managed(texture->resource.access)) + resource = &texture->resource; + if (!wined3d_resource_access_is_managed(resource->access)) { TRACE("Ignoring LOD on texture with resource access %s.\n", - wined3d_debug_resource_access(texture->resource.access)); + wined3d_debug_resource_access(resource->access)); return 0; } @@ -1203,14 +1375,14 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) if (texture->lod != lod) { - struct wined3d_device *device = texture->resource.device; + struct wined3d_device *device = resource->device; - wined3d_resource_wait_idle(&texture->resource); + wined3d_resource_wait_idle(resource); texture->lod = lod; - texture->texture_rgb.base_level = ~0u; - texture->texture_srgb.base_level = ~0u; - if (texture->resource.bind_count) + wined3d_texture_gl(texture)->texture_rgb.base_level = ~0u; + wined3d_texture_gl(texture)->texture_srgb.base_level = ~0u; + if (resource->bind_count) wined3d_cs_emit_set_sampler_state(device->cs, texture->sampler, WINED3D_SAMP_MAX_MIP_LEVEL, device->state.sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]); } @@ -1252,117 +1424,101 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture, return WINED3D_OK; } -static void texture2d_create_dc(void *object) +/* In D3D the depth stencil dimensions have to be greater than or equal to the + * render target dimensions. With FBOs, the dimensions have to be an exact match. */ +/* TODO: We should synchronize the renderbuffer's content with the texture's content. */ +/* Context activation is done by the caller. */ +void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, unsigned int level, const struct wined3d_rendertarget_info *rt) { - struct wined3d_surface *surface = object; - struct wined3d_context *context = NULL; - const struct wined3d_format *format; - unsigned int row_pitch, slice_pitch; - struct wined3d_texture *texture; - struct wined3d_bo_address data; - D3DKMT_CREATEDCFROMMEMORY desc; - unsigned int sub_resource_idx; - struct wined3d_device *device; - NTSTATUS status; - - TRACE("surface %p.\n", surface); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_renderbuffer_entry *entry; + unsigned int src_width, src_height; + unsigned int width, height; + GLuint renderbuffer = 0; - texture = surface->container; - sub_resource_idx = surface_get_sub_resource_idx(surface); - device = texture->resource.device; + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) + return; - format = texture->resource.format; - if (!format->ddi_format) + if (rt && rt->resource->format->id != WINED3DFMT_NULL) { - WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id)); - return; - } + struct wined3d_texture *rt_texture; + unsigned int rt_level; - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); + if (rt->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type)); + return; + } + rt_texture = wined3d_texture_from_resource(rt->resource); + rt_level = rt->sub_resource_idx % rt_texture->level_count; - wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); - wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); - wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch); - wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); - desc.pMemory = context_map_bo_address(context, &data, - texture->sub_resources[sub_resource_idx].size, - GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE); + width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level); + height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level); + } + else + { + width = wined3d_texture_get_level_pow2_width(&texture_gl->t, level); + height = wined3d_texture_get_level_pow2_height(&texture_gl->t, level); + } - if (context) - context_release(context); + src_width = wined3d_texture_get_level_pow2_width(&texture_gl->t, level); + src_height = wined3d_texture_get_level_pow2_height(&texture_gl->t, level); - desc.Format = format->ddi_format; - desc.Width = wined3d_texture_get_level_width(texture, surface->texture_level); - desc.Height = wined3d_texture_get_level_height(texture, surface->texture_level); - desc.Pitch = row_pitch; - desc.hDeviceDc = CreateCompatibleDC(NULL); - desc.pColorTable = NULL; + /* A depth stencil smaller than the render target is not valid */ + if (width > src_width || height > src_height) + return; - status = D3DKMTCreateDCFromMemory(&desc); - DeleteDC(desc.hDeviceDc); - if (status) + /* Remove any renderbuffer set if the sizes match */ + if (width == src_width && height == src_height) { - WARN("Failed to create DC, status %#x.\n", status); + texture_gl->current_renderbuffer = NULL; return; } - surface->dc = desc.hDc; - surface->bitmap = desc.hBitmap; - - TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface); -} - -static void texture2d_destroy_dc(void *object) -{ - struct wined3d_surface *surface = object; - D3DKMT_DESTROYDCFROMMEMORY destroy_desc; - struct wined3d_context *context = NULL; - struct wined3d_texture *texture; - struct wined3d_bo_address data; - unsigned int sub_resource_idx; - struct wined3d_device *device; - NTSTATUS status; - - texture = surface->container; - sub_resource_idx = surface_get_sub_resource_idx(surface); - device = texture->resource.device; - - if (!surface->dc) + /* Look if we've already got a renderbuffer of the correct dimensions */ + LIST_FOR_EACH_ENTRY(entry, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry) { - ERR("Surface %p has no DC.\n", surface); - return; + if (entry->width == width && entry->height == height) + { + renderbuffer = entry->id; + texture_gl->current_renderbuffer = entry; + break; + } } - TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap); + if (!renderbuffer) + { + const struct wined3d_format_gl *format_gl; - destroy_desc.hDc = surface->dc; - destroy_desc.hBitmap = surface->bitmap; - if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) - ERR("Failed to destroy dc, status %#x.\n", status); - surface->dc = NULL; - surface->bitmap = NULL; + format_gl = wined3d_format_gl(texture_gl->t.resource.format); + gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format_gl->internal, width, height); - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); + entry = heap_alloc(sizeof(*entry)); + entry->width = width; + entry->height = height; + entry->id = renderbuffer; + list_add_head(&texture_gl->renderbuffers, &entry->entry); - wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); - context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + texture_gl->current_renderbuffer = entry; + } - if (context) - context_release(context); + checkGLcall("set compatible renderbuffer"); } HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality, void *mem, UINT pitch) { - struct wined3d_device *device = texture->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, texture->resource.usage); - UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_surface *surface; + const struct wined3d_d3d_info *d3d_info; + const struct wined3d_gl_info *gl_info; + const struct wined3d_format *format; + const struct wined3d *d3d; + struct wined3d_device *device; + unsigned int resource_size; DWORD valid_location = 0; BOOL create_dib = FALSE; @@ -1370,6 +1526,13 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT "mem %p, pitch %u.\n", texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch); + device = texture->resource.device; + d3d = device->wined3d; + gl_info = &device->adapter->gl_info; + d3d_info = &device->adapter->d3d_info; + format = wined3d_get_format(device->adapter, format_id, texture->resource.bind_flags); + resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); + if (!resource_size) return WINED3DERR_INVALIDCALL; @@ -1385,12 +1548,6 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT return WINED3DERR_INVALIDCALL; } - if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D) - { - FIXME("Not yet supported for 1D textures.\n"); - return WINED3DERR_INVALIDCALL; - } - if (texture->resource.map_count) { WARN("Texture is mapped.\n"); @@ -1415,11 +1572,12 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT wined3d_resource_wait_idle(&texture->resource); sub_resource = &texture->sub_resources[0]; - surface = sub_resource->u.surface; - if (surface->dc) + if (texture->dc_info && texture->dc_info[0].dc) { - wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + struct wined3d_texture_idx texture_idx = {texture, 0}; + + wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); create_dib = TRUE; } @@ -1437,17 +1595,28 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT texture->resource.multisample_quality = multisample_quality; texture->resource.width = width; texture->resource.height = height; + if (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) + adapter_adjust_memory(device->adapter, (INT64)texture->slice_pitch - texture->resource.size); texture->resource.size = texture->slice_pitch; sub_resource->size = texture->slice_pitch; sub_resource->locations = WINED3D_LOCATION_DISCARDED; - if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) - texture->target = GL_TEXTURE_2D_MULTISAMPLE; - else - texture->target = GL_TEXTURE_2D; + if (texture->texture_ops == &texture_gl_ops) + { + if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) + { + wined3d_texture_gl(texture)->target = GL_TEXTURE_2D_MULTISAMPLE; + texture->flags &= ~WINED3D_TEXTURE_DOWNLOADABLE; + } + else + { + wined3d_texture_gl(texture)->target = GL_TEXTURE_2D; + texture->flags |= WINED3D_TEXTURE_DOWNLOADABLE; + } + } - if ((!is_power_of_two(width) || !is_power_of_two(height)) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] - && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) + if (((width & (width - 1)) || (height & (height - 1))) && !d3d_info->texture_npot + && !d3d_info->texture_npot_conditional) { texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; texture->pow2_width = texture->pow2_height = 1; @@ -1470,7 +1639,8 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT } else { - wined3d_texture_prepare_location(texture, 0, NULL, WINED3D_LOCATION_SYSMEM); + if (!wined3d_resource_prepare_sysmem(&texture->resource)) + ERR("Failed to allocate resource memory.\n"); valid_location = WINED3D_LOCATION_SYSMEM; } @@ -1486,8 +1656,10 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT if (create_dib) { - wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + struct wined3d_texture_idx texture_idx = {texture, 0}; + + wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); } return WINED3D_OK; @@ -1495,16 +1667,11 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT /* Context activation is done by the caller. */ static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, -#if !defined(STAGING_CSMT) unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) -#else /* STAGING_CSMT */ - unsigned int sub_resource_idx, struct wined3d_context *context) -#endif /* STAGING_CSMT */ { struct wined3d_texture_sub_resource *sub_resource; sub_resource = &texture->sub_resources[sub_resource_idx]; -#if !defined(STAGING_CSMT) if (sub_resource->buffer_object) return; @@ -1516,16 +1683,6 @@ static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *textur TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", sub_resource->buffer_object, texture, sub_resource_idx); -#else /* STAGING_CSMT */ - if (sub_resource->buffer) - return; - - sub_resource->buffer = wined3d_device_get_bo(texture->resource.device, - sub_resource->size, GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); - - TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", - sub_resource->buffer->name, texture, sub_resource_idx); -#endif /* STAGING_CSMT */ } static void wined3d_texture_force_reload(struct wined3d_texture *texture) @@ -1543,119 +1700,114 @@ static void wined3d_texture_force_reload(struct wined3d_texture *texture) } } -void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +/* Context activation is done by the caller. */ +void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, BOOL srgb) { DWORD alloc_flag = srgb ? WINED3D_TEXTURE_SRGB_ALLOCATED : WINED3D_TEXTURE_RGB_ALLOCATED; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_resource *resource = &texture_gl->t.resource; + const struct wined3d_device *device = resource->device; + const struct wined3d_format *format = resource->format; + const struct wined3d_color_key_conversion *conversion; + const struct wined3d_format_gl *format_gl; + GLenum internal; + + TRACE("texture_gl %p, context_gl %p, format %s.\n", texture_gl, context_gl, debug_d3dformat(format->id)); if (!d3d_info->shader_color_key - && !(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY) - != !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) + && !(texture_gl->t.async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY) + != !(texture_gl->t.async.color_key_flags & WINED3D_CKEY_SRC_BLT)) { - wined3d_texture_force_reload(texture); + wined3d_texture_force_reload(&texture_gl->t); - if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) - texture->async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY; + if (texture_gl->t.async.color_key_flags & WINED3D_CKEY_SRC_BLT) + texture_gl->t.async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY; } - if (texture->flags & alloc_flag) + if (texture_gl->t.flags & alloc_flag) return; - texture->texture_ops->texture_prepare_texture(texture, context, srgb); - texture->flags |= alloc_flag; + if (resource->format_flags & WINED3DFMT_FLAG_DECOMPRESS) + { + TRACE("WINED3DFMT_FLAG_DECOMPRESS set.\n"); + texture_gl->t.flags |= WINED3D_TEXTURE_CONVERTED; + format = wined3d_resource_get_decompress_format(resource); + } + else if (format->conv_byte_count) + { + texture_gl->t.flags |= WINED3D_TEXTURE_CONVERTED; + } + else if ((conversion = wined3d_format_get_color_key_conversion(&texture_gl->t, TRUE))) + { + texture_gl->t.flags |= WINED3D_TEXTURE_CONVERTED; + format = wined3d_get_format(device->adapter, conversion->dst_format, resource->bind_flags); + TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id)); + } + format_gl = wined3d_format_gl(format); + + wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, srgb); + + if (srgb) + internal = format_gl->srgb_internal; + else if (resource->bind_flags & WINED3D_BIND_RENDER_TARGET && wined3d_resource_is_offscreen(resource)) + internal = format_gl->rt_internal; + else + internal = format_gl->internal; + + if (!internal) + FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id)); + + TRACE("internal %#x, format %#x, type %#x.\n", internal, format_gl->format, format_gl->type); + + if (wined3d_texture_use_immutable_storage(&texture_gl->t, gl_info)) + wined3d_texture_gl_allocate_immutable_storage(texture_gl, internal, gl_info); + else + wined3d_texture_gl_allocate_mutable_storage(texture_gl, internal, format_gl, gl_info); + texture_gl->t.flags |= alloc_flag; } -static void wined3d_texture_prepare_rb(struct wined3d_texture *texture, +static void wined3d_texture_gl_prepare_rb(struct wined3d_texture_gl *texture_gl, const struct wined3d_gl_info *gl_info, BOOL multisample) { - const struct wined3d_format *format = texture->resource.format; + const struct wined3d_format_gl *format_gl; + format_gl = wined3d_format_gl(texture_gl->t.resource.format); if (multisample) { DWORD samples; - if (texture->rb_multisample) + if (texture_gl->rb_multisample) return; - samples = wined3d_texture_get_gl_sample_count(texture); + samples = wined3d_resource_get_sample_count(&texture_gl->t.resource); - gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample); - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample); + gl_info->fbo_ops.glGenRenderbuffers(1, &texture_gl->rb_multisample); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture_gl->rb_multisample); gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - format->glInternal, texture->resource.width, texture->resource.height); + format_gl->internal, texture_gl->t.resource.width, texture_gl->t.resource.height); checkGLcall("glRenderbufferStorageMultisample()"); - TRACE("Created multisample rb %u.\n", texture->rb_multisample); + TRACE("Created multisample rb %u.\n", texture_gl->rb_multisample); } else { - if (texture->rb_resolved) + if (texture_gl->rb_resolved) return; - gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_resolved); - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_resolved); - gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format->glInternal, - texture->resource.width, texture->resource.height); + gl_info->fbo_ops.glGenRenderbuffers(1, &texture_gl->rb_resolved); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture_gl->rb_resolved); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format_gl->internal, + texture_gl->t.resource.width, texture_gl->t.resource.height); checkGLcall("glRenderbufferStorage()"); - TRACE("Created resolved rb %u.\n", texture->rb_resolved); + TRACE("Created resolved rb %u.\n", texture_gl->rb_resolved); } } -/* Context activation is done by the caller. Context may be NULL in - * WINED3D_NO3D mode. */ -BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD location) +BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) { - switch (location) - { - case WINED3D_LOCATION_SYSMEM: - if (texture->resource.heap_memory) - return TRUE; - - if (!wined3d_resource_allocate_sysmem(&texture->resource)) - { - ERR("Failed to allocate system memory.\n"); - return FALSE; - } - return TRUE; - - case WINED3D_LOCATION_USER_MEMORY: - if (!texture->user_memory) - ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n"); - return TRUE; - - case WINED3D_LOCATION_BUFFER: -#if !defined(STAGING_CSMT) - wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info); -#else /* STAGING_CSMT */ - wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context); -#endif /* STAGING_CSMT */ - return TRUE; - - case WINED3D_LOCATION_TEXTURE_RGB: - wined3d_texture_prepare_texture(texture, context, FALSE); - return TRUE; - - case WINED3D_LOCATION_TEXTURE_SRGB: - wined3d_texture_prepare_texture(texture, context, TRUE); - return TRUE; - - case WINED3D_LOCATION_DRAWABLE: - if (!texture->swapchain && wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER) - ERR("Texture %p does not have a drawable.\n", texture); - return TRUE; - - case WINED3D_LOCATION_RB_MULTISAMPLE: - wined3d_texture_prepare_rb(texture, context->gl_info, TRUE); - return TRUE; - - case WINED3D_LOCATION_RB_RESOLVED: - wined3d_texture_prepare_rb(texture, context->gl_info, FALSE); - return TRUE; - - default: - ERR("Invalid location %s.\n", wined3d_debug_location(location)); - return FALSE; - } + return texture->texture_ops->texture_prepare_location(texture, sub_resource_idx, context, location); } static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture, @@ -1693,126 +1845,386 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, return WINED3D_OK; } -void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_box *box, - const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +static void wined3d_texture_gl_upload_bo(const struct wined3d_format *src_format, GLenum target, + unsigned int level, unsigned int src_row_pitch, unsigned int dst_x, unsigned int dst_y, + unsigned int dst_z, unsigned int update_w, unsigned int update_h, unsigned int update_d, + const BYTE *addr, BOOL srgb, struct wined3d_texture *dst_texture, + const struct wined3d_gl_info *gl_info) { - texture->texture_ops->texture_upload_data(texture, sub_resource_idx, - context, box, data, row_pitch, slice_pitch); -} + const struct wined3d_format_gl *format_gl = wined3d_format_gl(src_format); + if (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + { + unsigned int dst_row_pitch, dst_slice_pitch; + GLenum internal; -/* This call just uploads data, the caller is responsible for binding the - * correct texture. */ -/* Context activation is done by the caller. */ -static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data, - unsigned int row_pitch, unsigned int slice_pitch) -{ - struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; - const struct wined3d_format *format = texture->resource.format; - unsigned int level = sub_resource_idx % texture->level_count; - const struct wined3d_gl_info *gl_info = context->gl_info; - const void *mem = data->addr; - void *converted_mem = NULL; - unsigned int width, x, update_w; - GLenum target; + if (srgb) + internal = format_gl->srgb_internal; + else if (dst_texture->resource.bind_flags & WINED3D_BIND_RENDER_TARGET + && wined3d_resource_is_offscreen(&dst_texture->resource)) + internal = format_gl->rt_internal; + else + internal = format_gl->internal; - TRACE("texture %p, sub_resource_idx %u, context %p, box %p, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n", - texture, sub_resource_idx, context, box, data->buffer_object, data->addr, row_pitch, slice_pitch); + wined3d_format_calculate_pitch(src_format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); - width = wined3d_texture_get_level_width(texture, level); + TRACE("Uploading compressed data, target %#x, level %u, x %u, y %u, z %u, " + "w %u, h %u, d %u, format %#x, image_size %#x, addr %p.\n", + target, level, dst_x, dst_y, dst_z, update_w, update_h, + update_d, internal, dst_slice_pitch, addr); - if (!box) - { - x = 0; - update_w = width; + if (target == GL_TEXTURE_1D) + { + GL_EXTCALL(glCompressedTexSubImage1D(target, level, dst_x, + update_w, internal, dst_row_pitch, addr)); + } + else if (dst_row_pitch == src_row_pitch) + { + if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D) + { + GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, dst_y, dst_z, + update_w, update_h, update_d, internal, dst_slice_pitch * update_d, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, dst_y, + update_w, update_h, internal, dst_slice_pitch, addr)); + } + } + else + { + unsigned int row_count = (update_h + src_format->block_height - 1) / src_format->block_height; + unsigned int row, y, z; + + /* glCompressedTexSubImage2D() ignores pixel store state, so we + * can't use the unpack row length like for glTexSubImage2D. */ + for (z = dst_z; z < dst_z + update_d; ++z) + { + for (row = 0, y = dst_y; row < row_count; ++row) + { + if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D) + { + GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, y, z, + update_w, src_format->block_height, 1, internal, dst_row_pitch, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, y, + update_w, src_format->block_height, internal, dst_row_pitch, addr)); + } + + y += src_format->block_height; + addr += src_row_pitch; + } + } + } + checkGLcall("Upload compressed texture data"); } else { - x = box->left; - update_w = box->right - box->left; - } - - if (format->upload) - { - unsigned int dst_row_pitch; + unsigned int y, y_count; - if (data->buffer_object) - ERR("Loading a converted texture from a PBO.\n"); - if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) - ERR("Converting a block-based format.\n"); - - dst_row_pitch = update_w * format->conv_byte_count; + TRACE("Uploading data, target %#x, level %u, x %u, y %u, z %u, " + "w %u, h %u, d %u, format %#x, type %#x, addr %p.\n", + target, level, dst_x, dst_y, dst_z, update_w, update_h, + update_d, format_gl->format, format_gl->type, addr); - converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_row_pitch); - format->upload(data->addr, converted_mem, row_pitch, slice_pitch, dst_row_pitch, dst_row_pitch, update_w, 1, 1); - mem = converted_mem; - } + if (src_row_pitch) + { + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_row_pitch / src_format->byte_count); + y_count = 1; + } + else + { + y_count = update_h; + update_h = 1; + } - if (data->buffer_object) + for (y = 0; y < y_count; ++y) + { + if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D) + { + GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y + y, dst_z, + update_w, update_h, update_d, format_gl->format, format_gl->type, addr)); + } + else if (target == GL_TEXTURE_1D) + { + gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x, + update_w, format_gl->format, format_gl->type, addr); + } + else + { + gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y + y, + update_w, update_h, format_gl->format, format_gl->type, addr); + } + } + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + checkGLcall("Upload texture data"); + } +} + +static void wined3d_texture_gl_upload_data(struct wined3d_context *context, + const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format, + const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int update_w = src_box->right - src_box->left; + unsigned int update_h = src_box->bottom - src_box->top; + unsigned int update_d = src_box->back - src_box->front; + struct wined3d_bo_address bo; + unsigned int level; + BOOL decompress; + GLenum target; + + BOOL srgb = FALSE; + + TRACE("context %p, src_bo_addr %s, src_format %s, src_box %s, src_row_pitch %u, src_slice_pitch %u, " + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_x %u, dst_y %u, dst_z %u.\n", + context, debug_const_bo_address(src_bo_addr), debug_d3dformat(src_format->id), debug_box(src_box), + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, + wined3d_debug_location(dst_location), dst_x, dst_y, dst_z); + + if (dst_location == WINED3D_LOCATION_TEXTURE_SRGB) { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); + srgb = TRUE; + } + else if (dst_location != WINED3D_LOCATION_TEXTURE_RGB) + { + FIXME("Unhandled location %s.\n", wined3d_debug_location(dst_location)); + return; + } + + wined3d_texture_gl_bind_and_dirtify(wined3d_texture_gl(dst_texture), wined3d_context_gl(context), srgb); + + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count) + { + WARN("Uploading a texture that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n"); + dst_texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; } - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - if (target == GL_TEXTURE_1D_ARRAY) + if (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) { - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count); + update_h *= src_format->height_scale.numerator; + update_h /= src_format->height_scale.denominator; + } - gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem); - checkGLcall("glTexSubImage2D"); + target = wined3d_texture_gl_get_sub_resource_target(wined3d_texture_gl(dst_texture), dst_sub_resource_idx); + level = dst_sub_resource_idx % dst_texture->level_count; - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + switch (target) + { + case GL_TEXTURE_1D_ARRAY: + dst_y = dst_sub_resource_idx / dst_texture->level_count; + update_h = 1; + break; + case GL_TEXTURE_2D_ARRAY: + dst_z = dst_sub_resource_idx / dst_texture->level_count; + update_d = 1; + break; + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + FIXME("Not supported for multisample textures.\n"); + return; + } + + bo.buffer_object = src_bo_addr->buffer_object; + bo.addr = (BYTE *)src_bo_addr->addr + src_box->front * src_slice_pitch; + if (dst_texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) + { + bo.addr += (src_box->top / src_format->block_height) * src_row_pitch; + bo.addr += (src_box->left / src_format->block_width) * src_format->block_byte_count; } else { - gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, x, update_w, format->glFormat, format->glType, mem); - checkGLcall("glTexSubImage1D"); + bo.addr += src_box->top * src_row_pitch; + bo.addr += src_box->left * src_format->byte_count; } - if (data->buffer_object) + decompress = dst_texture->resource.format_flags & WINED3DFMT_FLAG_DECOMPRESS; + if (src_format->upload || decompress) { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); + const struct wined3d_format *compressed_format = src_format; + unsigned int dst_row_pitch, dst_slice_pitch; + struct wined3d_format_gl f; + void *converted_mem; + unsigned int z; + BYTE *src_mem; + + if (decompress) + { + src_format = wined3d_resource_get_decompress_format(&dst_texture->resource); + } + else + { + if (dst_texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) + ERR("Converting a block-based format.\n"); + + f = *wined3d_format_gl(src_format); + f.f.byte_count = src_format->conv_byte_count; + src_format = &f.f; + } + + wined3d_format_calculate_pitch(src_format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); + + if (!(converted_mem = heap_alloc(dst_slice_pitch))) + { + ERR("Failed to allocate upload buffer.\n"); + return; + } + + src_mem = wined3d_context_gl_map_bo_address(context_gl, &bo, + src_slice_pitch * update_d, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); + + for (z = 0; z < update_d; ++z, src_mem += src_slice_pitch) + { + if (decompress) + compressed_format->decompress(src_mem, converted_mem, src_row_pitch, src_slice_pitch, + dst_row_pitch, dst_slice_pitch, update_w, update_h, 1); + else + src_format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch, + dst_row_pitch, dst_slice_pitch, update_w, update_h, 1); + + wined3d_texture_gl_upload_bo(src_format, target, level, dst_row_pitch, dst_x, dst_y, + dst_z + z, update_w, update_h, 1, converted_mem, srgb, dst_texture, gl_info); + } + + wined3d_context_gl_unmap_bo_address(context_gl, &bo, GL_PIXEL_UNPACK_BUFFER, 0, NULL); + heap_free(converted_mem); + } + else + { + if (bo.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bo.buffer_object)); + checkGLcall("glBindBuffer"); + } + + wined3d_texture_gl_upload_bo(src_format, target, level, src_row_pitch, dst_x, dst_y, + dst_z, update_w, update_h, update_d, bo.addr, srgb, dst_texture, gl_info); + + if (bo.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } } - HeapFree(GetProcessHeap(), 0, converted_mem); + if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) + { + struct wined3d_device *device = dst_texture->resource.device; + unsigned int i; + + for (i = 0; i < device->context_count; ++i) + { + wined3d_context_gl_texture_update(wined3d_context_gl(device->contexts[i]), wined3d_texture_gl(dst_texture)); + } + } } -/* Context activation is done by the caller. */ -static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_bo_address *data) +static void wined3d_texture_gl_download_data_slow_path(struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *data) { - struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; - const struct wined3d_format *format = texture->resource.format; - const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_texture_sub_resource *sub_resource; + unsigned int dst_row_pitch, dst_slice_pitch; + unsigned int src_row_pitch, src_slice_pitch; + const struct wined3d_format_gl *format_gl; BYTE *temporary_mem = NULL; - void *mem; + unsigned int level; GLenum target; + void *mem; - sub_resource = &texture->sub_resources[sub_resource_idx]; + format_gl = wined3d_format_gl(texture_gl->t.resource.format); - if (format->conv_byte_count) + /* Only support read back of converted P8 textures. */ + if (texture_gl->t.flags & WINED3D_TEXTURE_CONVERTED && format_gl->f.id != WINED3DFMT_P8_UINT + && !format_gl->f.download) { - FIXME("Attempting to download a converted 1d texture, format %s.\n", - debug_d3dformat(format->id)); + ERR("Trying to read back converted texture %p, %u with format %s.\n", + texture_gl, sub_resource_idx, debug_d3dformat(format_gl->f.id)); return; } - target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx); - if (target == GL_TEXTURE_1D_ARRAY) + sub_resource = &texture_gl->t.sub_resources[sub_resource_idx]; + target = wined3d_texture_gl_get_sub_resource_target(texture_gl, sub_resource_idx); + level = sub_resource_idx % texture_gl->t.level_count; + + if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY) + { + if (format_gl->f.download) + { + FIXME("Reading back converted array texture %p is not supported.\n", texture_gl); + return; + } + + /* NP2 emulation is not allowed on array textures. */ + if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + ERR("Array texture %p uses NP2 emulation.\n", texture_gl); + + WARN_(d3d_perf)("Downloading all miplevel layers to get the data for a single sub-resource.\n"); + + if (!(temporary_mem = heap_calloc(texture_gl->t.layer_count, sub_resource->size))) + { + ERR("Out of memory.\n"); + return; + } + } + + if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2_EMULATED) { - WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); + if (format_gl->f.download) + { + FIXME("Reading back converted texture %p with NP2 emulation is not supported.\n", texture_gl); + return; + } - if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size))) + wined3d_texture_get_pitch(&texture_gl->t, level, &dst_row_pitch, &dst_slice_pitch); + wined3d_format_calculate_pitch(&format_gl->f, texture_gl->t.resource.device->surface_alignment, + wined3d_texture_get_level_pow2_width(&texture_gl->t, level), + wined3d_texture_get_level_pow2_height(&texture_gl->t, level), + &src_row_pitch, &src_slice_pitch); + if (!(temporary_mem = heap_alloc(src_slice_pitch))) { ERR("Out of memory.\n"); return; } + if (data->buffer_object) + ERR("NP2 emulated texture uses PBO unexpectedly.\n"); + if (texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + ERR("Unexpected compressed format for NP2 emulated texture.\n"); + } + + if (format_gl->f.download) + { + struct wined3d_format f; + + if (data->buffer_object) + ERR("Converted texture %p uses PBO unexpectedly.\n", texture_gl); + + WARN_(d3d_perf)("Downloading converted texture %p, %u with format %s.\n", + texture_gl, sub_resource_idx, debug_d3dformat(format_gl->f.id)); + + f = format_gl->f; + f.byte_count = format_gl->f.conv_byte_count; + wined3d_texture_get_pitch(&texture_gl->t, level, &dst_row_pitch, &dst_slice_pitch); + wined3d_format_calculate_pitch(&f, texture_gl->t.resource.device->surface_alignment, + wined3d_texture_get_level_width(&texture_gl->t, level), + wined3d_texture_get_level_height(&texture_gl->t, level), + &src_row_pitch, &src_slice_pitch); + + if (!(temporary_mem = heap_alloc(src_slice_pitch))) + { + ERR("Failed to allocate memory.\n"); + return; + } + } + + if (temporary_mem) + { mem = temporary_mem; } else if (data->buffer_object) @@ -1822,15 +2234,102 @@ static void texture1d_download_data(struct wined3d_texture *texture, unsigned in mem = data->addr; } else + { mem = data->addr; + } - gl_info->gl_ops.gl.p_glGetTexImage(target, sub_resource_idx, - format->glFormat, format->glType, mem); - checkGLcall("glGetTexImage"); + if (texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + { + TRACE("Downloading compressed texture %p, %u, level %u, format %#x, type %#x, data %p.\n", + texture_gl, sub_resource_idx, level, format_gl->format, format_gl->type, mem); - if (temporary_mem) + GL_EXTCALL(glGetCompressedTexImage(target, level, mem)); + checkGLcall("glGetCompressedTexImage"); + } + else + { + TRACE("Downloading texture %p, %u, level %u, format %#x, type %#x, data %p.\n", + texture_gl, sub_resource_idx, level, format_gl->format, format_gl->type, mem); + + gl_info->gl_ops.gl.p_glGetTexImage(target, level, format_gl->format, format_gl->type, mem); + checkGLcall("glGetTexImage"); + } + + if (format_gl->f.download) { - void *src_data = temporary_mem + surface->texture_layer * sub_resource->size; + format_gl->f.download(mem, data->addr, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, + wined3d_texture_get_level_width(&texture_gl->t, level), + wined3d_texture_get_level_height(&texture_gl->t, level), 1); + } + else if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + { + const BYTE *src_data; + unsigned int h, y; + BYTE *dst_data; + /* Some games (e.g. Warhammer 40,000) don't properly handle texture + * pitches, preventing us from using the texture pitch to box NPOT + * textures. Instead, we repack the texture's CPU copy so that its + * pitch equals bpp * width instead of bpp * pow2width. + * + * Instead of boxing the texture: + * + * │<── texture width ──>│ pow2 width ──>│ + * ├─────────────────────┼───────────────┼─ + * │111111111111111111111│ │ʌ + * │222222222222222222222│ ││ + * │333333333333333333333│ padding │texture height + * │444444444444444444444│ ││ + * │555555555555555555555│ │v + * ├─────────────────────┘ ├─ + * │ │pow2 height + * │ padding padding ││ + * │ │v + * └─────────────────────────────────────┴─ + * + * we're repacking the data to the expected texture width + * + * │<── texture width ──>│ pow2 width ──>│ + * ├─────────────────────┴───────────────┼─ + * │1111111111111111111112222222222222222│ʌ + * │2222233333333333333333333344444444444││ + * │4444444444555555555555555555555 │texture height + * │ ││ + * │ padding padding │v + * │ ├─ + * │ │pow2 height + * │ padding padding ││ + * │ │v + * └─────────────────────────────────────┴─ + * + * == is the same as + * + * │<── texture width ──>│ + * ├─────────────────────┼─ + * │111111111111111111111│ʌ + * │222222222222222222222││ + * │333333333333333333333│texture height + * │444444444444444444444││ + * │555555555555555555555│v + * └─────────────────────┴─ + * + * This also means that any references to surface memory should work + * with the data as if it were a standard texture with a NPOT width + * instead of a texture boxed up to be a power-of-two texture. */ + src_data = mem; + dst_data = data->addr; + TRACE("Repacking the surface data from pitch %u to pitch %u.\n", src_row_pitch, dst_row_pitch); + h = wined3d_texture_get_level_height(&texture_gl->t, level); + for (y = 0; y < h; ++y) + { + memcpy(dst_data, src_data, dst_row_pitch); + src_data += src_row_pitch; + dst_data += dst_row_pitch; + } + } + else if (temporary_mem) + { + unsigned int layer = sub_resource_idx / texture_gl->t.level_count; + void *src_data = temporary_mem + layer * sub_resource->size; if (data->buffer_object) { GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); @@ -1850,361 +2349,514 @@ static void texture1d_download_data(struct wined3d_texture *texture, unsigned in checkGLcall("glBindBuffer"); } - HeapFree(GetProcessHeap(), 0, temporary_mem); + heap_free(temporary_mem); } -/* Context activation is done by the caller. */ -static void texture1d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, BOOL dest_is_srgb) +static void wined3d_texture_gl_download_data(struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, + const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, + const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch) { - struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; - unsigned int row_pitch, slice_pitch; - struct wined3d_bo_address data; - - WARN_(d3d_perf)("Performing slow rgb/srgb 1d texture transfer.\n"); - data.buffer_object = 0; - if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size))) - return; - - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb); - texture1d_download_data(texture, sub_resource_idx, context, &data); - wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb); - texture1d_upload_data(texture, sub_resource_idx, context, NULL, - wined3d_const_bo_address(&data), row_pitch, slice_pitch); + struct wined3d_texture_gl *src_texture_gl = wined3d_texture_gl(src_texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + unsigned int src_level, src_width, src_height, src_depth; + unsigned int src_row_pitch, src_slice_pitch; + const struct wined3d_format_gl *format_gl; + BOOL srgb = FALSE; + GLenum target; + struct wined3d_texture_sub_resource *sub_resource; - HeapFree(GetProcessHeap(), 0, data.addr); -} + TRACE("context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_box %s, dst_bo_addr %s, " + "dst_format %s, dst_x %u, dst_y %u, dst_z %u, dst_row_pitch %u, dst_slice_pitch %u.\n", + context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), + debug_box(src_box), debug_bo_address(dst_bo_addr), debug_d3dformat(dst_format->id), + dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); -/* Context activation is done by the caller. */ -static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD location) -{ - struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; - DWORD required_access = wined3d_resource_access_from_location(location); - unsigned int row_pitch, slice_pitch; + if (src_location == WINED3D_LOCATION_TEXTURE_SRGB) + { + srgb = TRUE; + } + else if (src_location != WINED3D_LOCATION_TEXTURE_RGB) + { + FIXME("Unhandled location %s.\n", wined3d_debug_location(src_location)); + return; + } - TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", - texture, sub_resource_idx, context, wined3d_debug_location(location)); + src_level = src_sub_resource_idx % src_texture->level_count; + src_width = wined3d_texture_get_level_width(src_texture, src_level); + src_height = wined3d_texture_get_level_height(src_texture, src_level); + src_depth = wined3d_texture_get_level_depth(src_texture, src_level); + if (src_box->left || src_box->top || src_box->right != src_width || src_box->bottom != src_height + || src_box->front || src_box->back != src_depth) + { + FIXME("Unhandled source box %s.\n", debug_box(src_box)); + return; + } - TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations)); + if (dst_x || dst_y || dst_z) + { + FIXME("Unhandled destination (%u, %u, %u).\n", dst_x, dst_y, dst_z); + return; + } - if ((sub_resource->locations & location) == location) + if (dst_format->id != src_texture->resource.format->id) { - TRACE("Location(s) already up to date.\n"); - return TRUE; + FIXME("Unhandled format conversion (%s -> %s).\n", + debug_d3dformat(src_texture->resource.format->id), + debug_d3dformat(dst_format->id)); + return; } - if ((texture->resource.access & required_access) != required_access) + wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); + if (src_row_pitch != dst_row_pitch || src_slice_pitch != dst_slice_pitch) { - ERR("Operation requires %#x access, but 1d texture only has %#x.\n", - required_access, texture->resource.access); - return FALSE; + FIXME("Unhandled destination pitches %u/%u (source pitches %u/%u).\n", + dst_row_pitch, dst_slice_pitch, src_row_pitch, src_slice_pitch); + return; } - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) - return FALSE; + wined3d_texture_gl_bind_and_dirtify(src_texture_gl, context_gl, srgb); - if (sub_resource->locations & WINED3D_LOCATION_DISCARDED) + format_gl = wined3d_format_gl(src_texture->resource.format); + target = wined3d_texture_gl_get_sub_resource_target(src_texture_gl, src_sub_resource_idx); + sub_resource = &src_texture->sub_resources[src_sub_resource_idx]; + + if ((src_texture->resource.type == WINED3D_RTYPE_TEXTURE_2D + && (target == GL_TEXTURE_2D_ARRAY || format_gl->f.conv_byte_count + || src_texture->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_COND_NP2_EMULATED))) + || target == GL_TEXTURE_1D_ARRAY) { - TRACE("1d texture previously discarded, nothing to do.\n"); - wined3d_texture_validate_location(texture, sub_resource_idx, location); - wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED); - goto done; + wined3d_texture_gl_download_data_slow_path(src_texture_gl, src_sub_resource_idx, context_gl, dst_bo_addr); + return; } - switch (location) + if (format_gl->f.conv_byte_count) { - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) - { - struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; - data.addr += sub_resource->offset; - wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); - } - else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) - { -#if !defined(STAGING_CSMT) - struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; -#else /* STAGING_CSMT */ - struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL}; -#endif /* STAGING_CSMT */ - wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); - } - else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - { - texture1d_srgb_transfer(texture, sub_resource_idx, context, TRUE); - } - else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB) - { - texture1d_srgb_transfer(texture, sub_resource_idx, context, FALSE); - } - else - { - FIXME("Implement 1d texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - case WINED3D_LOCATION_SYSMEM: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, texture->resource.heap_memory}; + FIXME("Attempting to download a converted texture, type %s format %s.\n", + debug_d3dresourcetype(src_texture->resource.type), + debug_d3dformat(format_gl->f.id)); + return; + } - data.addr += sub_resource->offset; - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - else - wined3d_texture_bind_and_dirtify(texture, context, TRUE); + if (dst_bo_addr->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, dst_bo_addr->buffer_object)); + checkGLcall("glBindBuffer"); + } - texture1d_download_data(texture, sub_resource_idx, context, &data); - ++texture->download_count; - } - else - { - FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; + if (src_texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + { + TRACE("Downloading compressed texture %p, %u, level %u, format %#x, type %#x, data %p.\n", + src_texture, src_sub_resource_idx, src_level, format_gl->format, format_gl->type, dst_bo_addr->addr); - case WINED3D_LOCATION_BUFFER: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { -#if !defined(STAGING_CSMT) - struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; -#else /* STAGING_CSMT */ - struct wined3d_bo_address data = {sub_resource->buffer->name, NULL}; -#endif /* STAGING_CSMT */ - - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - else - wined3d_texture_bind_and_dirtify(texture, context, TRUE); + GL_EXTCALL(glGetCompressedTexImage(target, src_level, dst_bo_addr->addr)); + checkGLcall("glGetCompressedTexImage"); + } + else if (dst_bo_addr->buffer_object && src_texture->resource.bind_flags & WINED3D_BIND_RENDER_TARGET) + { + /* PBO texture download is not accelerated on Mesa. Use glReadPixels if possible. */ + TRACE("Downloading (glReadPixels) texture %p, %u, level %u, format %#x, type %#x, data %p.\n", + src_texture, src_sub_resource_idx, src_level, format_gl->format, format_gl->type, dst_bo_addr->addr); - texture1d_download_data(texture, sub_resource_idx, context, &data); - } - else - { - FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, &src_texture->resource, src_sub_resource_idx, NULL, + 0, sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)); + wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER); + context_invalidate_state(context, STATE_FRAMEBUFFER); + gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); + checkGLcall("glReadBuffer()"); - default: - FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), - wined3d_debug_location(sub_resource->locations)); - return FALSE; + gl_info->gl_ops.gl.p_glReadPixels(0, 0, wined3d_texture_get_level_width(src_texture, src_level), + wined3d_texture_get_level_height(src_texture, src_level), format_gl->format, format_gl->type, dst_bo_addr->addr); + checkGLcall("glReadPixels"); } + else + { + TRACE("Downloading texture %p, %u, level %u, format %#x, type %#x, data %p.\n", + src_texture, src_sub_resource_idx, src_level, format_gl->format, format_gl->type, dst_bo_addr->addr); -done: - wined3d_texture_validate_location(texture, sub_resource_idx, location); + gl_info->gl_ops.gl.p_glGetTexImage(target, src_level, format_gl->format, format_gl->type, dst_bo_addr->addr); + checkGLcall("glGetTexImage"); + } - return TRUE; + if (dst_bo_addr->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } } -static void texture1d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +/* Context activation is done by the caller. */ +static BOOL wined3d_texture_gl_load_sysmem(struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl, DWORD dst_location) { - const struct wined3d_format *format = texture->resource.format; - unsigned int sub_count = texture->level_count * texture->layer_count; - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int width; - GLenum internal; + struct wined3d_texture_sub_resource *sub_resource; - wined3d_texture_bind_and_dirtify(texture, context, srgb); + sub_resource = &texture_gl->t.sub_resources[sub_resource_idx]; - if (srgb) - internal = format->glGammaInternal; - else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET - && wined3d_resource_is_offscreen(&texture->resource)) - internal = format->rtInternal; - else - internal = format->glInternal; + /* We cannot download data from multisample textures directly. */ + if (wined3d_texture_gl_is_multisample_location(texture_gl, WINED3D_LOCATION_TEXTURE_RGB)) + { + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_RB_RESOLVED); + texture2d_read_from_framebuffer(&texture_gl->t, sub_resource_idx, &context_gl->c, + WINED3D_LOCATION_RB_RESOLVED, dst_location); + return TRUE; + } + + if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_TEXTURE_RGB); - if (wined3d_texture_use_immutable_storage(texture, gl_info)) + /* Download the sub-resource to system memory. */ + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { - width = wined3d_texture_get_level_width(texture, 0); + unsigned int row_pitch, slice_pitch, level; + struct wined3d_bo_address data; + struct wined3d_box src_box; + unsigned int src_location; - if (texture->target == GL_TEXTURE_1D_ARRAY) - { - GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, internal, width, texture->layer_count)); - checkGLcall("glTexStorage2D"); - } - else - { - GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, internal, width)); - checkGLcall("glTexStorage1D"); - } + level = sub_resource_idx % texture_gl->t.level_count; + wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data, dst_location); + src_location = sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB + ? WINED3D_LOCATION_TEXTURE_RGB : WINED3D_LOCATION_TEXTURE_SRGB; + wined3d_texture_get_level_box(&texture_gl->t, level, &src_box); + wined3d_texture_get_pitch(&texture_gl->t, level, &row_pitch, &slice_pitch); + wined3d_texture_gl_download_data(&context_gl->c, &texture_gl->t, sub_resource_idx, src_location, + &src_box, &data, texture_gl->t.resource.format, 0, 0, 0, row_pitch, slice_pitch); + + ++texture_gl->t.download_count; + return TRUE; } - else + + if (!(texture_gl->t.resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL) + && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) { - unsigned int i; + texture2d_read_from_framebuffer(&texture_gl->t, sub_resource_idx, &context_gl->c, + texture_gl->t.resource.draw_binding, dst_location); + return TRUE; + } - for (i = 0; i < sub_count; ++i) - { - GLenum target; - struct wined3d_surface *surface = texture->sub_resources[i].u.surface; - width = wined3d_texture_get_level_width(texture, surface->texture_level); - target = wined3d_texture_get_sub_resource_target(texture, i); + FIXME("Can't load texture %p, %u with location flags %s into sysmem.\n", + texture_gl, sub_resource_idx, wined3d_debug_location(sub_resource->locations)); - if (texture->target == GL_TEXTURE_1D_ARRAY) - { - gl_info->gl_ops.gl.p_glTexImage2D(target, surface->texture_level, - internal, width, texture->layer_count, 0, format->glFormat, format->glType, NULL); - checkGLcall("glTexImage2D"); - } - else - { - gl_info->gl_ops.gl.p_glTexImage1D(target, surface->texture_level, - internal, width, 0, format->glFormat, format->glType, NULL); - checkGLcall("glTexImage1D"); - } - } - } + return FALSE; } -static void texture1d_cleanup_sub_resources(struct wined3d_texture *texture) -{ -} - -static const struct wined3d_texture_ops texture1d_ops = -{ - texture1d_upload_data, - texture1d_load_location, - texture1d_prepare_texture, - texture1d_cleanup_sub_resources, -}; - -static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_box *box, - const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +static BOOL wined3d_texture_load_drawable(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context) { - unsigned int texture_level; - POINT dst_point; - RECT src_rect; + struct wined3d_device *device; + unsigned int level; + RECT r; - src_rect.left = 0; - src_rect.top = 0; - if (box) + if (texture->resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL) { - dst_point.x = box->left; - dst_point.y = box->top; - src_rect.right = box->right - box->left; - src_rect.bottom = box->bottom - box->top; + DWORD current = texture->sub_resources[sub_resource_idx].locations; + FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", + wined3d_debug_location(current)); + return FALSE; } - else + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && wined3d_resource_is_offscreen(&texture->resource)) { - dst_point.x = dst_point.y = 0; - texture_level = sub_resource_idx % texture->level_count; - src_rect.right = wined3d_texture_get_level_width(texture, texture_level); - src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level); + ERR("Trying to load offscreen texture into WINED3D_LOCATION_DRAWABLE.\n"); + return FALSE; } - wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info, - texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data); + device = texture->resource.device; + level = sub_resource_idx % texture->level_count; + SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, level), + wined3d_texture_get_level_height(texture, level)); + wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, + texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &r, + texture, sub_resource_idx, WINED3D_LOCATION_DRAWABLE, &r, + NULL, WINED3D_TEXF_POINT); + + return TRUE; } -static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD location) +static BOOL wined3d_texture_load_renderbuffer(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD dst_location) { - return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location); + unsigned int level = sub_resource_idx % texture->level_count; + const RECT rect = {0, 0, + wined3d_texture_get_level_width(texture, level), + wined3d_texture_get_level_height(texture, level)}; + struct wined3d_texture_sub_resource *sub_resource; + DWORD src_location, locations; + + sub_resource = &texture->sub_resources[sub_resource_idx]; + locations = sub_resource->locations; + if (texture->resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL) + { + FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", + wined3d_debug_location(locations)); + return FALSE; + } + + if (locations & WINED3D_LOCATION_RB_MULTISAMPLE) + src_location = WINED3D_LOCATION_RB_MULTISAMPLE; + else if (locations & WINED3D_LOCATION_RB_RESOLVED) + src_location = WINED3D_LOCATION_RB_RESOLVED; + else if (locations & WINED3D_LOCATION_TEXTURE_SRGB) + src_location = WINED3D_LOCATION_TEXTURE_SRGB; + else if (locations & WINED3D_LOCATION_TEXTURE_RGB) + src_location = WINED3D_LOCATION_TEXTURE_RGB; + else if (locations & WINED3D_LOCATION_DRAWABLE) + src_location = WINED3D_LOCATION_DRAWABLE; + else /* texture2d_blt_fbo() will load the source location if necessary. */ + src_location = WINED3D_LOCATION_TEXTURE_RGB; + + texture2d_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, texture, + sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect); + + return TRUE; } -/* Context activation is done by the caller. */ -static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl, BOOL srgb) { - const struct wined3d_format *format = texture->resource.format; - const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int width, height, level, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + struct wined3d_device *device = texture_gl->t.resource.device; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; const struct wined3d_color_key_conversion *conversion; - GLenum internal; + struct wined3d_texture_sub_resource *sub_resource; + const struct wined3d_format *format; + struct wined3d_bo_address data; + BYTE *src_mem, *dst_mem = NULL; + struct wined3d_box src_box; + DWORD dst_location; + BOOL depth; - TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id)); + depth = texture_gl->t.resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL; + sub_resource = &texture_gl->t.sub_resources[sub_resource_idx]; - if (format->conv_byte_count) + if (!depth && wined3d_settings.offscreen_rendering_mode != ORM_FBO + && wined3d_resource_is_offscreen(&texture_gl->t.resource) + && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) { - texture->flags |= WINED3D_TEXTURE_CONVERTED; + texture2d_load_fb_texture(texture_gl, sub_resource_idx, srgb, &context_gl->c); + + return TRUE; } - else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) + + level = sub_resource_idx % texture_gl->t.level_count; + wined3d_texture_get_level_box(&texture_gl->t, level, &src_box); + + if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) + && (texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) + && fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info, + &texture_gl->t.resource, WINED3D_LOCATION_TEXTURE_RGB, + &texture_gl->t.resource, WINED3D_LOCATION_TEXTURE_SRGB)) { - texture->flags |= WINED3D_TEXTURE_CONVERTED; - format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage); - TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id)); + RECT src_rect; + + SetRect(&src_rect, src_box.left, src_box.top, src_box.right, src_box.bottom); + if (srgb) + texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, + &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect, + &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect); + else + texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, + &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect, + &texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); + + return TRUE; + } + + if (!depth && sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) + && (!srgb || (texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))) + { + DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ? + WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; + RECT src_rect; + + SetRect(&src_rect, src_box.left, src_box.top, src_box.right, src_box.bottom); + dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; + if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info, + &texture_gl->t.resource, src_location, &texture_gl->t.resource, dst_location)) + texture2d_blt_fbo(device, &context_gl->c, WINED3D_TEXF_POINT, &texture_gl->t, sub_resource_idx, + src_location, &src_rect, &texture_gl->t, sub_resource_idx, dst_location, &src_rect); + + return TRUE; } - wined3d_texture_bind_and_dirtify(texture, context, srgb); + /* Upload from system memory */ if (srgb) - internal = format->glGammaInternal; - else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET - && wined3d_resource_is_offscreen(&texture->resource)) - internal = format->rtInternal; + { + dst_location = WINED3D_LOCATION_TEXTURE_SRGB; + if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture_gl->t.resource.map_binding)) + == WINED3D_LOCATION_TEXTURE_RGB) + { + FIXME_(d3d_perf)("Downloading RGB texture %p, %u to reload it as sRGB.\n", texture_gl, sub_resource_idx); + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, + &context_gl->c, texture_gl->t.resource.map_binding); + } + } else - internal = format->glInternal; + { + dst_location = WINED3D_LOCATION_TEXTURE_RGB; + if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture_gl->t.resource.map_binding)) + == WINED3D_LOCATION_TEXTURE_SRGB) + { + FIXME_(d3d_perf)("Downloading sRGB texture %p, %u to reload it as RGB.\n", texture_gl, sub_resource_idx); + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, + &context_gl->c, texture_gl->t.resource.map_binding); + } + } - if (!internal) - FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id)); + if (!(sub_resource->locations & wined3d_texture_sysmem_locations)) + { + WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); + /* Lets hope we get it from somewhere... */ + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_SYSMEM); + } - TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType); + wined3d_texture_get_pitch(&texture_gl->t, level, &src_row_pitch, &src_slice_pitch); - if (wined3d_texture_use_immutable_storage(texture, gl_info)) - wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info); - else - wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info); + format = texture_gl->t.resource.format; + if ((conversion = wined3d_format_get_color_key_conversion(&texture_gl->t, TRUE))) + format = wined3d_get_format(device->adapter, conversion->dst_format, texture_gl->t.resource.bind_flags); + + /* Don't use PBOs for converted surfaces. During PBO conversion we look at + * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is + * getting called. */ + if (conversion && sub_resource->buffer_object) + { + TRACE("Removing the pbo attached to texture %p, %u.\n", texture_gl, sub_resource_idx); + + wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_SYSMEM); + wined3d_texture_set_map_binding(&texture_gl->t, WINED3D_LOCATION_SYSMEM); + } + + wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data, sub_resource->locations); + if (conversion) + { + width = src_box.right - src_box.left; + height = src_box.bottom - src_box.top; + wined3d_format_calculate_pitch(format, device->surface_alignment, + width, height, &dst_row_pitch, &dst_slice_pitch); + + src_mem = wined3d_context_gl_map_bo_address(context_gl, &data, + src_slice_pitch, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ); + if (!(dst_mem = heap_alloc(dst_slice_pitch))) + { + ERR("Out of memory (%u).\n", dst_slice_pitch); + return FALSE; + } + conversion->convert(src_mem, src_row_pitch, dst_mem, dst_row_pitch, + width, height, &texture_gl->t.async.gl_color_key); + src_row_pitch = dst_row_pitch; + src_slice_pitch = dst_slice_pitch; + wined3d_context_gl_unmap_bo_address(context_gl, &data, GL_PIXEL_UNPACK_BUFFER, 0, NULL); + + data.buffer_object = 0; + data.addr = dst_mem; + } + + wined3d_texture_gl_upload_data(&context_gl->c, wined3d_const_bo_address(&data), format, &src_box, + src_row_pitch, src_slice_pitch, &texture_gl->t, sub_resource_idx, dst_location, 0, 0, 0); + + heap_free(dst_mem); + + return TRUE; } -static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture) +static BOOL wined3d_texture_gl_prepare_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) { - unsigned int sub_count = texture->level_count * texture->layer_count; - struct wined3d_device *device = texture->resource.device; - struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_renderbuffer_entry *entry, *entry2; - const struct wined3d_gl_info *gl_info = NULL; - struct wined3d_context *context = NULL; - struct wined3d_surface *surface; - unsigned int i; + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); - for (i = 0; i < sub_count; ++i) + switch (location) { - sub_resource = &texture->sub_resources[i]; - if (!(surface = sub_resource->u.surface)) - continue; + case WINED3D_LOCATION_SYSMEM: + return wined3d_resource_prepare_sysmem(&texture->resource); + + case WINED3D_LOCATION_USER_MEMORY: + if (!texture->user_memory) + ERR("Preparing WINED3D_LOCATION_USER_MEMORY, but texture->user_memory is NULL.\n"); + return TRUE; - TRACE("surface %p.\n", surface); + case WINED3D_LOCATION_BUFFER: + wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context_gl->gl_info); + return TRUE; - if (!context && !list_empty(&surface->renderbuffers)) - { - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; - } + case WINED3D_LOCATION_TEXTURE_RGB: + wined3d_texture_gl_prepare_texture(texture_gl, context_gl, FALSE); + return TRUE; - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - TRACE("Deleting renderbuffer %u.\n", entry->id); - context_gl_resource_released(device, entry->id, TRUE); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); - heap_free(entry); - } + case WINED3D_LOCATION_TEXTURE_SRGB: + wined3d_texture_gl_prepare_texture(texture_gl, context_gl, TRUE); + return TRUE; + + case WINED3D_LOCATION_DRAWABLE: + if (!texture->swapchain && wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER) + ERR("Texture %p does not have a drawable.\n", texture); + return TRUE; + + case WINED3D_LOCATION_RB_MULTISAMPLE: + wined3d_texture_gl_prepare_rb(texture_gl, context_gl->gl_info, TRUE); + return TRUE; + + case WINED3D_LOCATION_RB_RESOLVED: + wined3d_texture_gl_prepare_rb(texture_gl, context_gl->gl_info, FALSE); + return TRUE; - if (surface->dc) - texture2d_destroy_dc(surface); + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; + } +} + +/* Context activation is done by the caller. */ +static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + if (!wined3d_texture_gl_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + + switch (location) + { + case WINED3D_LOCATION_USER_MEMORY: + case WINED3D_LOCATION_SYSMEM: + case WINED3D_LOCATION_BUFFER: + return wined3d_texture_gl_load_sysmem(texture_gl, sub_resource_idx, context_gl, location); + + case WINED3D_LOCATION_DRAWABLE: + return wined3d_texture_load_drawable(texture, sub_resource_idx, context); + + case WINED3D_LOCATION_RB_RESOLVED: + case WINED3D_LOCATION_RB_MULTISAMPLE: + return wined3d_texture_load_renderbuffer(texture, sub_resource_idx, context, location); + + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + return wined3d_texture_gl_load_texture(texture_gl, sub_resource_idx, + context_gl, location == WINED3D_LOCATION_TEXTURE_SRGB); + + default: + FIXME("Unhandled %s load from %s.\n", wined3d_debug_location(location), + wined3d_debug_location(texture->sub_resources[sub_resource_idx].locations)); + return FALSE; } - if (context) - context_release(context); - heap_free(texture->sub_resources[0].u.surface); } -static const struct wined3d_texture_ops texture2d_ops = +static const struct wined3d_texture_ops texture_gl_ops = { - texture2d_upload_data, - texture2d_load_location, - texture2d_prepare_texture, - texture2d_cleanup_sub_resources, + wined3d_texture_gl_prepare_location, + wined3d_texture_gl_load_location, + wined3d_texture_gl_upload_data, + wined3d_texture_gl_download_data, }; struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource) @@ -2232,28 +2884,29 @@ static void texture_resource_preload(struct wined3d_resource *resource) context_release(context); } -static void wined3d_texture_unload(struct wined3d_resource *resource) +static void wined3d_texture_gl_unload(struct wined3d_resource *resource) { - struct wined3d_texture *texture = texture_from_resource(resource); - UINT sub_count = texture->level_count * texture->layer_count; + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource)); + UINT sub_count = texture_gl->t.level_count * texture_gl->t.layer_count; + struct wined3d_renderbuffer_entry *entry, *entry2; struct wined3d_device *device = resource->device; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; UINT i; - TRACE("texture %p.\n", texture); + TRACE("texture_gl %p.\n", texture_gl); context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; + gl_info = wined3d_context_gl(context)->gl_info; for (i = 0; i < sub_count; ++i) { - struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i]; + struct wined3d_texture_sub_resource *sub_resource = &texture_gl->t.sub_resources[i]; if (resource->access & WINED3D_RESOURCE_ACCESS_CPU - && wined3d_texture_load_location(texture, i, context, resource->map_binding)) + && wined3d_texture_load_location(&texture_gl->t, i, context, resource->map_binding)) { - wined3d_texture_invalidate_location(texture, i, ~resource->map_binding); + wined3d_texture_invalidate_location(&texture_gl->t, i, ~resource->map_binding); } else { @@ -2264,39 +2917,28 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) ERR("Discarding %s %p sub-resource %u with resource access %s.\n", debug_d3dresourcetype(resource->type), resource, i, wined3d_debug_resource_access(resource->access)); - wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED); - wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED); + wined3d_texture_validate_location(&texture_gl->t, i, WINED3D_LOCATION_DISCARDED); + wined3d_texture_invalidate_location(&texture_gl->t, i, ~WINED3D_LOCATION_DISCARDED); } -#if !defined(STAGING_CSMT) if (sub_resource->buffer_object) - wined3d_texture_remove_buffer_object(texture, i, context->gl_info); -#else /* STAGING_CSMT */ - if (sub_resource->buffer) - wined3d_texture_remove_buffer_object(texture, i, context); -#endif /* STAGING_CSMT */ - - if (resource->type == WINED3D_RTYPE_TEXTURE_2D) - { - struct wined3d_surface *surface = sub_resource->u.surface; - struct wined3d_renderbuffer_entry *entry, *entry2; + wined3d_texture_remove_buffer_object(&texture_gl->t, i, gl_info); + } - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - context_gl_resource_released(device, entry->id, TRUE); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); - list_remove(&entry->entry); - heap_free(entry); - } - list_init(&surface->renderbuffers); - surface->current_renderbuffer = NULL; - } + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + context_gl_resource_released(device, entry->id, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); + list_remove(&entry->entry); + heap_free(entry); } + list_init(&texture_gl->renderbuffers); + texture_gl->current_renderbuffer = NULL; context_release(context); - wined3d_texture_force_reload(texture); - wined3d_texture_unload_gl_texture(texture); + wined3d_texture_force_reload(&texture_gl->t); + wined3d_texture_gl_unload_texture(texture_gl); } static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, @@ -2306,7 +2948,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour struct wined3d_texture_sub_resource *sub_resource; struct wined3d_device *device = resource->device; unsigned int fmt_flags = resource->format_flags; - struct wined3d_context *context = NULL; + struct wined3d_context *context; struct wined3d_texture *texture; struct wined3d_bo_address data; unsigned int texture_level; @@ -2341,8 +2983,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour return WINED3DERR_INVALIDCALL; } - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); + context = context_acquire(device, NULL, 0); if (flags & WINED3D_MAP_DISCARD) { @@ -2370,11 +3011,11 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding); wined3d_texture_get_memory(texture, sub_resource_idx, &data, resource->map_binding); - base_memory = context_map_bo_address(context, &data, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, flags); + base_memory = wined3d_context_map_bo_address(context, &data, sub_resource->size, 0, flags); + sub_resource->map_flags = flags; TRACE("Base memory pointer %p.\n", base_memory); - if (context) - context_release(context); + context_release(context); if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) { @@ -2464,9 +3105,10 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso { struct wined3d_texture_sub_resource *sub_resource; struct wined3d_device *device = resource->device; - struct wined3d_context *context = NULL; + struct wined3d_context *context; struct wined3d_texture *texture; struct wined3d_bo_address data; + struct wined3d_map_range range; TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); @@ -2482,14 +3124,14 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso return WINEDDERR_NOTLOCKED; } - if (device->d3d_initialized) - context = context_acquire(device, NULL, 0); + context = context_acquire(device, NULL, 0); wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); - context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + range.offset = 0; + range.size = sub_resource->size; + wined3d_context_unmap_bo_address(context, &data, 0, !!(sub_resource->map_flags & WINED3D_MAP_WRITE), &range); - if (context) - context_release(context); + context_release(context); if (texture->swapchain && texture->swapchain->front_buffer == texture) { @@ -2509,751 +3151,280 @@ static const struct wined3d_resource_ops texture_resource_ops = texture_resource_incref, texture_resource_decref, texture_resource_preload, - wined3d_texture_unload, + wined3d_texture_gl_unload, texture_resource_sub_resource_map, texture_resource_sub_resource_map_info, texture_resource_sub_resource_unmap, }; -static HRESULT texture1d_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent, - const struct wined3d_parent_ops *parent_ops) +static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, + void *parent, const struct wined3d_parent_ops *parent_ops, void *sub_resources, + const struct wined3d_texture_ops *texture_ops) { + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_device_parent *device_parent = device->device_parent; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_surface *surfaces; - unsigned int i, j; + unsigned int sub_count, i, j, size, offset = 0; + unsigned int pow2_width, pow2_height; + const struct wined3d_format *format; HRESULT hr; - if (layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY]) - { - WARN("OpenGL implementation does not support array textures.\n"); + TRACE("texture %p, resource_type %s, format %s, multisample_type %#x, multisample_quality %#x, " + "usage %s, access %s, width %u, height %u, depth %u, layer_count %u, level_count %u, " + "flags %#x, device %p, parent %p, parent_ops %p, sub_resources %p, texture_ops %p.\n", + texture, debug_d3dresourcetype(desc->resource_type), debug_d3dformat(desc->format), + desc->multisample_type, desc->multisample_quality, debug_d3dusage(desc->usage), + wined3d_debug_resource_access(desc->access), desc->width, desc->height, desc->depth, + layer_count, level_count, flags, device, parent, parent_ops, sub_resources, texture_ops); + + if (!desc->width || !desc->height || !desc->depth) return WINED3DERR_INVALIDCALL; + + if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D && layer_count != 1) + { + ERR("Invalid layer count for volume texture.\n"); + return E_INVALIDARG; } + texture->sub_resources = sub_resources; + /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= desc->format) { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + WARN("Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n"); return WINED3DERR_INVALIDCALL; } + format = wined3d_get_format(device->adapter, desc->format, desc->bind_flags); - if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) - { - WARN("1d textures can not be used for cube mapping, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if ((desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access)) - || (desc->usage & WINED3DUSAGE_SCRATCH)) + if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access) + || desc->usage & WINED3DUSAGE_SCRATCH)) { - WARN("Attempted to create a DYNAMIC texture in pool %s.\n", wined3d_debug_resource_access(desc->access)); + WARN("Attempted to create a dynamic texture with access %s and usage %s.\n", + wined3d_debug_resource_access(desc->access), debug_d3dusage(desc->usage)); return WINED3DERR_INVALIDCALL; } - if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !is_power_of_two(desc->width)) + pow2_width = desc->width; + pow2_height = desc->height; + if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)) || (desc->depth & (desc->depth - 1))) + && !d3d_info->texture_npot) { - if (desc->usage & WINED3DUSAGE_SCRATCH) + /* level_count == 0 returns an error as well. */ + if (level_count != 1 || layer_count != 1 || desc->resource_type == WINED3D_RTYPE_TEXTURE_3D) { - WARN("Creating a scratch NPOT 1d texture despite lack of HW support.\n"); + if (!(desc->usage & WINED3DUSAGE_SCRATCH)) + { + WARN("Attempted to create a mipmapped/cube/array/volume NPOT " + "texture without unconditional NPOT support.\n"); + return WINED3DERR_INVALIDCALL; + } + + WARN("Creating a scratch mipmapped/cube/array NPOT texture despite lack of HW support.\n"); } - else + texture->flags |= WINED3D_TEXTURE_COND_NP2; + + if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !d3d_info->texture_npot_conditional) { - WARN("Attempted to create a NPOT 1d texture (%u, %u, %u) without GL support.\n", - desc->width, desc->height, desc->depth); - return WINED3DERR_INVALIDCALL; + /* TODO: Add support for non-power-of-two compressed textures. */ + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] + & (WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_HEIGHT_SCALE)) + { + FIXME("Compressed or height scaled non-power-of-two (%ux%u) textures are not supported.\n", + desc->width, desc->height); + return WINED3DERR_NOTAVAILABLE; + } + + /* Find the nearest pow2 match. */ + pow2_width = pow2_height = 1; + while (pow2_width < desc->width) + pow2_width <<= 1; + while (pow2_height < desc->height) + pow2_height <<= 1; + texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; } } + texture->pow2_width = pow2_width; + texture->pow2_height = pow2_height; - if (desc->usage & WINED3DUSAGE_QUERY_GENMIPMAP) + if ((pow2_width > d3d_info->limits.texture_size || pow2_height > d3d_info->limits.texture_size) + && (desc->bind_flags & WINED3D_BIND_SHADER_RESOURCE)) { - if (level_count != 1) + /* One of four options: + * 1: Do the same as we do with NPOT and scale the texture. (Any + * texture ops would require the texture to be scaled which is + * potentially slow.) + * 2: Set the texture to the maximum size (bad idea). + * 3: WARN and return WINED3DERR_NOTAVAILABLE. + * 4: Create the surface, but allow it to be used only for DirectDraw + * Blts. Some apps (e.g. Swat 3) create textures with a height of + * 16 and a width > 3000 and blt 16x16 letter areas from them to + * the render target. */ + if (desc->access & WINED3D_RESOURCE_ACCESS_GPU) { - WARN("WINED3DUSAGE_QUERY_GENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; + WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height); + return WINED3DERR_NOTAVAILABLE; } - } - if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc, - 0, device, parent, parent_ops, &texture_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); - return hr; + /* We should never use this surface in combination with OpenGL. */ + TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); } - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; - texture->pow2_matrix[10] = 1.0f; - texture->pow2_matrix[15] = 1.0f; - texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D; - - if (wined3d_texture_use_pbo(texture, gl_info)) + for (i = 0; i < layer_count; ++i) { - wined3d_resource_free_sysmem(&texture->resource); - texture->resource.map_binding = WINED3D_LOCATION_BUFFER; - } - - if (level_count > ~(SIZE_T)0 / layer_count - || !(surfaces = heap_calloc(level_count * layer_count, sizeof(*surfaces)))) - { - wined3d_texture_cleanup_sync(texture); - return E_OUTOFMEMORY; - } - - /* Generate all the surfaces. */ - for (i = 0; i < texture->level_count; ++i) - { - for (j = 0; j < texture->layer_count; ++j) + for (j = 0; j < level_count; ++j) { - struct wined3d_texture_sub_resource *sub_resource; - unsigned int idx = j * texture->level_count + i; - struct wined3d_surface *surface; - - surface = &surfaces[idx]; - surface->container = texture; - surface->texture_level = i; - surface->texture_layer = j; - list_init(&surface->renderbuffers); - - sub_resource = &texture->sub_resources[idx]; - sub_resource->locations = WINED3D_LOCATION_DISCARDED; - sub_resource->u.surface = surface; - - if (FAILED(hr = device_parent->ops->surface_created(device_parent, - texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) - { - WARN("Failed to create texture1d parent, hr %#x.\n", hr); - sub_resource->parent = NULL; - wined3d_texture_cleanup_sync(texture); - return hr; - } - - TRACE("parent %p, parent_ops %p.\n", parent, parent_ops); + unsigned int idx = i * level_count + j; - TRACE("Created 1d texture surface level %u, layer %u @ %p.\n", i, j, surface); + size = wined3d_format_calculate_size(format, device->surface_alignment, + max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j)); + texture->sub_resources[idx].offset = offset; + texture->sub_resources[idx].size = size; + offset += size; } + offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1); } - return WINED3D_OK; -} - -static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, - void *parent, const struct wined3d_parent_ops *parent_ops) -{ - struct wined3d_device_parent *device_parent = device->device_parent; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_surface *surfaces; - UINT pow2_width, pow2_height; - unsigned int i, j, sub_count; - HRESULT hr; - - if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 - && !gl_info->supported[EXT_TEXTURE_ARRAY]) - { - WARN("OpenGL implementation does not support array textures.\n"); - return WINED3DERR_INVALIDCALL; - } - - /* TODO: It should only be possible to create textures for formats - * that are reported as supported. */ - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + if (!offset) return WINED3DERR_INVALIDCALL; - } - - if (desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access)) - FIXME("Trying to create a managed texture with dynamic usage.\n"); - if (!(desc->usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)) - && (flags & WINED3D_TEXTURE_CREATE_MAPPABLE)) - WARN("Creating a mappable texture that doesn't specify dynamic usage.\n"); - if (desc->usage & WINED3DUSAGE_RENDERTARGET && desc->access & WINED3D_RESOURCE_ACCESS_CPU) - FIXME("Trying to create a CPU accessible render target.\n"); - - pow2_width = desc->width; - pow2_height = desc->height; - if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1))) - && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) - { - /* level_count == 0 returns an error as well. */ - if (level_count != 1 || layer_count != 1) - { - if (!(desc->usage & WINED3DUSAGE_SCRATCH)) - { - WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n"); - return WINED3DERR_INVALIDCALL; - } - - WARN("Creating a scratch mipmapped/cube/array NPOT texture despite lack of HW support.\n"); - } - texture->flags |= WINED3D_TEXTURE_COND_NP2; - - if (!gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) - { - const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage); - - /* TODO: Add support for non-power-of-two compressed textures. */ - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] - & (WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_HEIGHT_SCALE)) - { - FIXME("Compressed or height scaled non-power-of-two (%ux%u) textures are not supported.\n", - desc->width, desc->height); - return WINED3DERR_NOTAVAILABLE; - } - /* Find the nearest pow2 match. */ - pow2_width = pow2_height = 1; - while (pow2_width < desc->width) - pow2_width <<= 1; - while (pow2_height < desc->height) - pow2_height <<= 1; - texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; - } - } - texture->pow2_width = pow2_width; - texture->pow2_height = pow2_height; - - if ((pow2_width > gl_info->limits.texture_size || pow2_height > gl_info->limits.texture_size) - && (desc->usage & WINED3DUSAGE_TEXTURE)) + if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, + desc->multisample_type, desc->multisample_quality, desc->usage, desc->bind_flags, desc->access, + desc->width, desc->height, desc->depth, offset, parent, parent_ops, &texture_resource_ops))) { - /* One of four options: - * 1: Do the same as we do with NPOT and scale the texture. (Any - * texture ops would require the texture to be scaled which is - * potentially slow.) - * 2: Set the texture to the maximum size (bad idea). - * 3: WARN and return WINED3DERR_NOTAVAILABLE. - * 4: Create the surface, but allow it to be used only for DirectDraw - * Blts. Some apps (e.g. Swat 3) create textures with a height of - * 16 and a width > 3000 and blt 16x16 letter areas from them to - * the render target. */ - if (desc->access & WINED3D_RESOURCE_ACCESS_GPU) - { - WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height); - return WINED3DERR_NOTAVAILABLE; - } + static unsigned int once; - /* We should never use this surface in combination with OpenGL. */ - TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); - } + /* DXTn 3D textures are not supported. Do not write the ERR for them. */ + if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3 + || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5) + && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) + && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++) + ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n"); - if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, - flags, device, parent, parent_ops, &texture_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); + WARN("Failed to initialize resource, returning %#x\n", hr); return hr; } + wined3d_resource_update_draw_binding(&texture->resource); - /* Precalculated scaling for 'faked' non power of two texture coords. */ - if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT) - { - texture->pow2_matrix[0] = (float)desc->width; - texture->pow2_matrix[5] = (float)desc->height; - texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS); - texture->target = GL_TEXTURE_RECTANGLE_ARB; - } - else - { - if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) - { - texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width)); - texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height)); - texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; - } - else - { - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; - } - if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) - { - texture->target = GL_TEXTURE_CUBE_MAP_ARB; - } - else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) - { - if (layer_count > 1) - texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; - else - texture->target = GL_TEXTURE_2D_MULTISAMPLE; - } - else - { - if (layer_count > 1) - texture->target = GL_TEXTURE_2D_ARRAY; - else - texture->target = GL_TEXTURE_2D; - } - } - texture->pow2_matrix[10] = 1.0f; - texture->pow2_matrix[15] = 1.0f; - TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]); - - if (wined3d_texture_use_pbo(texture, gl_info)) - texture->resource.map_binding = WINED3D_LOCATION_BUFFER; - - sub_count = level_count * layer_count; - if (sub_count / layer_count != level_count - || !(surfaces = heap_calloc(sub_count, sizeof(*surfaces)))) - { - wined3d_texture_cleanup_sync(texture); - return E_OUTOFMEMORY; - } - - if (desc->usage & WINED3DUSAGE_OVERLAY) - { - if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info)))) - { - heap_free(surfaces); - wined3d_texture_cleanup_sync(texture); - return E_OUTOFMEMORY; - } - - for (i = 0; i < sub_count; ++i) - { - list_init(&texture->overlay_info[i].entry); - list_init(&texture->overlay_info[i].overlays); - } - } - - /* Generate all the surfaces. */ - for (i = 0; i < texture->level_count; ++i) - { - for (j = 0; j < texture->layer_count; ++j) - { - struct wined3d_texture_sub_resource *sub_resource; - unsigned int idx = j * texture->level_count + i; - struct wined3d_surface *surface; - - surface = &surfaces[idx]; - surface->container = texture; - surface->texture_level = i; - surface->texture_layer = j; - list_init(&surface->renderbuffers); - - sub_resource = &texture->sub_resources[idx]; - sub_resource->locations = WINED3D_LOCATION_DISCARDED; - sub_resource->u.surface = surface; - if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) - { - wined3d_texture_validate_location(texture, idx, WINED3D_LOCATION_SYSMEM); - wined3d_texture_invalidate_location(texture, idx, ~WINED3D_LOCATION_SYSMEM); - } - - if (FAILED(hr = device_parent->ops->surface_created(device_parent, - texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) - { - WARN("Failed to create surface parent, hr %#x.\n", hr); - sub_resource->parent = NULL; - wined3d_texture_cleanup_sync(texture); - return hr; - } - - TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops); - - TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface); - - if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D)) - { - wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (!surface->dc) - { - wined3d_texture_cleanup_sync(texture); - return WINED3DERR_INVALIDCALL; - } - } - } - } - - return WINED3D_OK; -} - -/* This call just uploads data, the caller is responsible for binding the - * correct texture. */ -/* Context activation is done by the caller. */ -static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_box *box, - const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) -{ - const struct wined3d_format *format = texture->resource.format; - unsigned int level = sub_resource_idx % texture->level_count; - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int x, y, z, update_w, update_h, update_d; - unsigned int dst_row_pitch, dst_slice_pitch; - unsigned int width, height, depth; - const void *mem = data->addr; - void *converted_mem = NULL; - - TRACE("texture %p, sub_resource_idx %u, context %p, box %s, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n", - texture, sub_resource_idx, context, debug_box(box), - data->buffer_object, data->addr, row_pitch, slice_pitch); - - width = wined3d_texture_get_level_width(texture, level); - height = wined3d_texture_get_level_height(texture, level); - depth = wined3d_texture_get_level_depth(texture, level); - - if (!box) - { - x = y = z = 0; - update_w = width; - update_h = height; - update_d = depth; - } - else - { - x = box->left; - y = box->top; - z = box->front; - update_w = box->right - box->left; - update_h = box->bottom - box->top; - update_d = box->back - box->front; - } - - if (format->conv_byte_count) - { - if (data->buffer_object) - ERR("Loading a converted texture from a PBO.\n"); - if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) - ERR("Converting a block-based format.\n"); - - dst_row_pitch = update_w * format->conv_byte_count; - dst_slice_pitch = dst_row_pitch * update_h; - - converted_mem = heap_calloc(update_d, dst_slice_pitch); - format->upload(data->addr, converted_mem, row_pitch, slice_pitch, - dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d); - mem = converted_mem; - } - else - { - wined3d_texture_get_pitch(texture, sub_resource_idx, &dst_row_pitch, &dst_slice_pitch); - if (row_pitch != dst_row_pitch || slice_pitch != dst_slice_pitch) - FIXME("Ignoring row/slice pitch (%u/%u).\n", row_pitch, slice_pitch); - } - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); - } - - GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, level, x, y, z, - update_w, update_h, update_d, format->glFormat, format->glType, mem)); - checkGLcall("glTexSubImage3D"); - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - - heap_free(converted_mem); -} - -/* Context activation is done by the caller. */ -static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_bo_address *data) -{ - const struct wined3d_format *format = texture->resource.format; - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (format->conv_byte_count) - { - FIXME("Attempting to download a converted volume, format %s.\n", - debug_d3dformat(format->id)); - return; - } - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); - } - - gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, sub_resource_idx, - format->glFormat, format->glType, data->addr); - checkGLcall("glGetTexImage"); - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - -} - -/* Context activation is done by the caller. */ -static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, BOOL dest_is_srgb) -{ - struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; - unsigned int row_pitch, slice_pitch; - struct wined3d_bo_address data; - - /* Optimisations are possible, but the effort should be put into either - * implementing EXT_SRGB_DECODE in the driver or finding out why we - * picked the wrong copy for the original upload and fixing that. - * - * Also keep in mind that we want to avoid using resource.heap_memory - * for DEFAULT pool surfaces. */ - WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n"); - data.buffer_object = 0; - if (!(data.addr = heap_alloc(sub_resource->size))) - return; - - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb); - texture3d_download_data(texture, sub_resource_idx, context, &data); - wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb); - texture3d_upload_data(texture, sub_resource_idx, context, - NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch); - - heap_free(data.addr); -} - -/* Context activation is done by the caller. */ -static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD location) -{ - struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; - unsigned int row_pitch, slice_pitch; - - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) - return FALSE; - - switch (location) - { - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) - { - struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; - data.addr += sub_resource->offset; - wined3d_texture_bind_and_dirtify(texture, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); - } - else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) - { -#if !defined(STAGING_CSMT) - struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; -#else /* STAGING_CSMT */ - struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL}; -#endif /* STAGING_CSMT */ - wined3d_texture_bind_and_dirtify(texture, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); - texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); - } - else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - { - texture3d_srgb_transfer(texture, sub_resource_idx, context, TRUE); - } - else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB) - { - texture3d_srgb_transfer(texture, sub_resource_idx, context, FALSE); - } - else - { - FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - case WINED3D_LOCATION_SYSMEM: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, texture->resource.heap_memory}; - - data.addr += sub_resource->offset; - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - else - wined3d_texture_bind_and_dirtify(texture, context, TRUE); - - texture3d_download_data(texture, sub_resource_idx, context, &data); - ++texture->download_count; - } - else - { - FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - case WINED3D_LOCATION_BUFFER: - if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { -#if !defined(STAGING_CSMT) - struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; -#else /* STAGING_CSMT */ - struct wined3d_bo_address data = {sub_resource->buffer->name, NULL}; -#endif /* STAGING_CSMT */ - - if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - else - wined3d_texture_bind_and_dirtify(texture, context, TRUE); - - texture3d_download_data(texture, sub_resource_idx, context, &data); - } - else - { - FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - break; - - default: - FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), - wined3d_debug_location(sub_resource->locations)); - return FALSE; - } - - return TRUE; -} - -static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) -{ - const struct wined3d_format *format = texture->resource.format; - GLenum internal = srgb ? format->glGammaInternal : format->glInternal; - unsigned int sub_count = texture->level_count * texture->layer_count; - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i; - - wined3d_texture_bind_and_dirtify(texture, context, srgb); - - if (wined3d_texture_use_immutable_storage(texture, gl_info)) - { - GL_EXTCALL(glTexStorage3D(GL_TEXTURE_3D, texture->level_count, internal, - wined3d_texture_get_level_width(texture, 0), - wined3d_texture_get_level_height(texture, 0), - wined3d_texture_get_level_depth(texture, 0))); - checkGLcall("glTexStorage3D"); - } - else - { - for (i = 0; i < sub_count; ++i) - { - GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, i, internal, - wined3d_texture_get_level_width(texture, i), - wined3d_texture_get_level_height(texture, i), - wined3d_texture_get_level_depth(texture, i), - 0, format->glFormat, format->glType, NULL)); - checkGLcall("glTexImage3D"); - } - } -} - -static void texture3d_cleanup_sub_resources(struct wined3d_texture *texture) -{ -} - -static const struct wined3d_texture_ops texture3d_ops = -{ - texture3d_upload_data, - texture3d_load_location, - texture3d_prepare_texture, - texture3d_cleanup_sub_resources, -}; - -static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - UINT layer_count, UINT level_count, DWORD flags, struct wined3d_device *device, void *parent, - const struct wined3d_parent_ops *parent_ops) -{ - struct wined3d_device_parent *device_parent = device->device_parent; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - unsigned int i; - HRESULT hr; + texture->texture_ops = texture_ops; - if (layer_count != 1) + texture->layer_count = layer_count; + texture->level_count = level_count; + texture->lod = 0; + texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS + | WINED3D_TEXTURE_DOWNLOADABLE; + if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) + texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT; + if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)) + texture->flags |= WINED3D_TEXTURE_GET_DC; + if (flags & WINED3D_TEXTURE_CREATE_DISCARD) + texture->flags |= WINED3D_TEXTURE_DISCARD; + if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS) { - ERR("Invalid layer count for volume texture.\n"); - return E_INVALIDARG; + if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP)) + WARN("Format doesn't support mipmaps generation, " + "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); + else + texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS; } - /* TODO: It should only be possible to create textures for formats - * that are reported as supported. */ - if (WINED3DFMT_UNKNOWN >= desc->format) + /* Precalculated scaling for 'faked' non power of two texture coords. */ + if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT) { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); - return WINED3DERR_INVALIDCALL; + texture->pow2_matrix[0] = (float)desc->width; + texture->pow2_matrix[5] = (float)desc->height; + texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS); } - - if (!gl_info->supported[EXT_TEXTURE3D]) + else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) { - WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); - return WINED3DERR_INVALIDCALL; + texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width)); + texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height)); + texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; } - - if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access) - || desc->usage & WINED3DUSAGE_SCRATCH)) + else { - WARN("Attempted to create a DYNAMIC texture with access %s.\n", - wined3d_debug_resource_access(desc->access)); - return WINED3DERR_INVALIDCALL; + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; } + texture->pow2_matrix[10] = 1.0f; + texture->pow2_matrix[15] = 1.0f; + TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]); - if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + if (wined3d_texture_use_pbo(texture, gl_info)) + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + + if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D + || !wined3d_texture_use_pbo(texture, gl_info)) { - if (!is_power_of_two(desc->width) || !is_power_of_two(desc->height) || !is_power_of_two(desc->depth)) + if (!wined3d_resource_prepare_sysmem(&texture->resource)) { - if (desc->usage & WINED3DUSAGE_SCRATCH) - { - WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n"); - } - else - { - WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", - desc->width, desc->height, desc->depth); - return WINED3DERR_INVALIDCALL; - } + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; } } - if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, level_count, desc, - flags, device, parent, parent_ops, &texture_resource_ops))) + sub_count = level_count * layer_count; + if (sub_count / layer_count != level_count) { - WARN("Failed to initialize texture, returning %#x.\n", hr); - return hr; + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; } - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; - texture->pow2_matrix[10] = 1.0f; - texture->pow2_matrix[15] = 1.0f; - texture->target = GL_TEXTURE_3D; - - if (wined3d_texture_use_pbo(texture, gl_info)) + if (desc->usage & WINED3DUSAGE_OVERLAY) { - wined3d_resource_free_sysmem(&texture->resource); - texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info)))) + { + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; + } + + for (i = 0; i < sub_count; ++i) + { + list_init(&texture->overlay_info[i].entry); + list_init(&texture->overlay_info[i].overlays); + } } - /* Generate all the sub resources. */ - for (i = 0; i < texture->level_count; ++i) + /* Generate all sub-resources. */ + for (i = 0; i < sub_count; ++i) { struct wined3d_texture_sub_resource *sub_resource; sub_resource = &texture->sub_resources[i]; sub_resource->locations = WINED3D_LOCATION_DISCARDED; + if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D) + { + wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM); + wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM); + } - if (FAILED(hr = device_parent->ops->volume_created(device_parent, - texture, i, &sub_resource->parent, &sub_resource->parent_ops))) + if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent, + desc->resource_type, texture, i, &sub_resource->parent, &sub_resource->parent_ops))) { - WARN("Failed to create volume parent, hr %#x.\n", hr); + WARN("Failed to create sub-resource parent, hr %#x.\n", hr); sub_resource->parent = NULL; wined3d_texture_cleanup_sync(texture); return hr; } - TRACE("parent %p, parent_ops %p.\n", parent, parent_ops); + TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops); + + TRACE("Created sub-resource %u (level %u, layer %u).\n", + i, i % texture->level_count, i / texture->level_count); - TRACE("Created volume level %u.\n", i); + if (desc->usage & WINED3DUSAGE_OWNDC) + { + struct wined3d_texture_idx texture_idx = {texture, i}; + + wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!texture->dc_info || !texture->dc_info[i].dc) + { + wined3d_texture_cleanup_sync(texture); + return WINED3DERR_INVALIDCALL; + } + } } return WINED3D_OK; @@ -3294,19 +3465,8 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned if (dst_texture->sub_resources[dst_sub_resource_idx].map_count || src_texture->sub_resources[src_sub_resource_idx].map_count) { -#if !defined(STAGING_CSMT) WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n"); return WINEDDERR_SURFACEBUSY; -#else /* STAGING_CSMT */ - struct wined3d_device *device = dst_texture->resource.device; - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (dst_texture->sub_resources[dst_sub_resource_idx].map_count - || (src_texture && src_texture->sub_resources[src_sub_resource_idx].map_count)) - { - WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n"); - return WINEDDERR_SURFACEBUSY; - } -#endif /* STAGING_CSMT */ } if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) @@ -3316,6 +3476,12 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned return WINED3DERR_INVALIDCALL; } + if (dst_texture->resource.device != src_texture->resource.device) + { + FIXME("Rejecting cross-device blit.\n"); + return E_NOTIMPL; + } + wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx, &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter); @@ -3337,7 +3503,7 @@ HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture } overlay = &texture->overlay_info[sub_resource_idx]; - if (!overlay->dst) + if (!overlay->dst_texture) { TRACE("Overlay not visible.\n"); *x = 0; @@ -3380,9 +3546,8 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags) { - struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource; - struct wined3d_surface *surface, *dst_surface; struct wined3d_overlay_info *overlay; + unsigned int level, dst_level; TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, " "dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n", @@ -3390,14 +3555,14 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), flags); if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D - || !(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) + || sub_resource_idx >= texture->level_count * texture->layer_count) { WARN("Invalid sub-resource specified.\n"); return WINEDDERR_NOTAOVERLAYSURFACE; } if (!dst_texture || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D - || !(dst_sub_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx))) + || dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count) { WARN("Invalid destination sub-resource specified.\n"); return WINED3DERR_INVALIDCALL; @@ -3405,33 +3570,35 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un overlay = &texture->overlay_info[sub_resource_idx]; - surface = sub_resource->u.surface; + level = sub_resource_idx % texture->level_count; if (src_rect) overlay->src_rect = *src_rect; else SetRect(&overlay->src_rect, 0, 0, - wined3d_texture_get_level_width(texture, surface->texture_level), - wined3d_texture_get_level_height(texture, surface->texture_level)); + wined3d_texture_get_level_width(texture, level), + wined3d_texture_get_level_height(texture, level)); - dst_surface = dst_sub_resource->u.surface; + dst_level = dst_sub_resource_idx % dst_texture->level_count; if (dst_rect) overlay->dst_rect = *dst_rect; else SetRect(&overlay->dst_rect, 0, 0, - wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level), - wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level)); + wined3d_texture_get_level_width(dst_texture, dst_level), + wined3d_texture_get_level_height(dst_texture, dst_level)); - if (overlay->dst && (overlay->dst != dst_surface || flags & WINEDDOVER_HIDE)) + if (overlay->dst_texture && (overlay->dst_texture != dst_texture + || overlay->dst_sub_resource_idx != dst_sub_resource_idx || flags & WINEDDOVER_HIDE)) { - overlay->dst = NULL; + overlay->dst_texture = NULL; list_remove(&overlay->entry); } if (flags & WINEDDOVER_SHOW) { - if (overlay->dst != dst_surface) + if (overlay->dst_texture != dst_texture || overlay->dst_sub_resource_idx != dst_sub_resource_idx) { - overlay->dst = dst_surface; + overlay->dst_texture = dst_texture; + overlay->dst_sub_resource_idx = dst_sub_resource_idx; list_add_tail(&texture->overlay_info[dst_sub_resource_idx].overlays, &overlay->entry); } } @@ -3440,7 +3607,7 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un /* Tests show that the rectangles are erased on hide. */ SetRectEmpty(&overlay->src_rect); SetRectEmpty(&overlay->dst_rect); - overlay->dst = NULL; + overlay->dst_texture = NULL; } return WINED3D_OK; @@ -3497,6 +3664,7 @@ HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture desc->multisample_type = resource->multisample_type; desc->multisample_quality = resource->multisample_quality; desc->usage = resource->usage; + desc->bind_flags = resource->bind_flags; desc->access = resource->access; level_idx = sub_resource_idx % texture->level_count; @@ -3508,11 +3676,90 @@ HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture return WINED3D_OK; } +HRESULT wined3d_texture_gl_init(struct wined3d_texture_gl *texture_gl, struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + HRESULT hr; + + TRACE("texture_gl %p, device %p, desc %p, layer_count %u, " + "level_count %u, flags %#x, parent %p, parent_ops %p.\n", + texture_gl, device, desc, layer_count, + level_count, flags, parent, parent_ops); + + if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 + && !gl_info->supported[EXT_TEXTURE_ARRAY]) + { + WARN("OpenGL implementation does not support array textures.\n"); + return WINED3DERR_INVALIDCALL; + } + + switch (desc->resource_type) + { + case WINED3D_RTYPE_TEXTURE_1D: + if (layer_count > 1) + texture_gl->target = GL_TEXTURE_1D_ARRAY; + else + texture_gl->target = GL_TEXTURE_1D; + break; + + case WINED3D_RTYPE_TEXTURE_2D: + if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) + { + texture_gl->target = GL_TEXTURE_CUBE_MAP_ARB; + } + else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) + { + if (layer_count > 1) + texture_gl->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; + else + texture_gl->target = GL_TEXTURE_2D_MULTISAMPLE; + } + else + { + if (layer_count > 1) + texture_gl->target = GL_TEXTURE_2D_ARRAY; + else + texture_gl->target = GL_TEXTURE_2D; + } + break; + + case WINED3D_RTYPE_TEXTURE_3D: + if (!gl_info->supported[EXT_TEXTURE3D]) + { + WARN("OpenGL implementation does not support 3D textures.\n"); + return WINED3DERR_INVALIDCALL; + } + texture_gl->target = GL_TEXTURE_3D; + break; + + default: + ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); + return WINED3DERR_INVALIDCALL; + } + + list_init(&texture_gl->renderbuffers); + + if (FAILED(hr = wined3d_texture_init(&texture_gl->t, desc, layer_count, level_count, + flags, device, parent, parent_ops, &texture_gl[1], &texture_gl_ops))) + return hr; + + if (texture_gl->t.resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT) + texture_gl->target = GL_TEXTURE_RECTANGLE_ARB; + + if (texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE) + texture_gl->t.flags &= ~WINED3D_TEXTURE_DOWNLOADABLE; + + return WINED3D_OK; +} + HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { - struct wined3d_texture *object; + unsigned int sub_count = level_count * layer_count; + unsigned int i; HRESULT hr; TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, data %p, " @@ -3538,8 +3785,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct if (desc->multisample_type != WINED3D_MULTISAMPLE_NONE) { - const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, - desc->format, desc->usage); + const struct wined3d_format *format = wined3d_get_format(device->adapter, desc->format, desc->bind_flags); if (desc->multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE && desc->multisample_quality >= wined3d_popcount(format->multisample_types)) @@ -3550,7 +3796,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct } if (desc->multisample_type != WINED3D_MULTISAMPLE_NON_MASKABLE && (!(format->multisample_types & 1u << (desc->multisample_type - 1)) - || desc->multisample_quality)) + || (desc->multisample_quality && desc->multisample_quality != WINED3D_STANDARD_MULTISAMPLE_PATTERN))) { WARN("Unsupported multisample type %u quality %u requested.\n", desc->multisample_type, desc->multisample_quality); @@ -3558,64 +3804,37 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct } } - if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture, - sub_resources[level_count * layer_count])))) - return E_OUTOFMEMORY; - - switch (desc->resource_type) + if (data) { - case WINED3D_RTYPE_TEXTURE_1D: - hr = texture1d_init(object, desc, layer_count, level_count, device, parent, parent_ops); - break; - - case WINED3D_RTYPE_TEXTURE_2D: - hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); - break; - - case WINED3D_RTYPE_TEXTURE_3D: - hr = volumetexture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); - break; + for (i = 0; i < sub_count; ++i) + { + if (data[i].data) + continue; - default: - ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); - hr = WINED3DERR_INVALIDCALL; - break; + WARN("Invalid sub-resource data specified for sub-resource %u.\n", i); + return E_INVALIDARG; + } } - if (FAILED(hr)) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); - heap_free(object); + if (FAILED(hr = device->adapter->adapter_ops->adapter_create_texture(device, desc, + layer_count, level_count, flags, parent, parent_ops, texture))) return hr; - } /* FIXME: We'd like to avoid ever allocating system memory for the texture * in this case. */ if (data) { - unsigned int sub_count = level_count * layer_count; - unsigned int i; - - for (i = 0; i < sub_count; ++i) - { - if (!data[i].data) - { - WARN("Invalid sub-resource data specified for sub-resource %u.\n", i); - wined3d_texture_cleanup_sync(object); - heap_free(object); - return E_INVALIDARG; - } - } + struct wined3d_box box; for (i = 0; i < sub_count; ++i) { - wined3d_device_update_sub_resource(device, &object->resource, - i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch); + wined3d_texture_get_level_box(*texture, i % (*texture)->level_count, &box); + wined3d_cs_emit_update_sub_resource(device->cs, &(*texture)->resource, + i, &box, data[i].data, data[i].row_pitch, data[i].slice_pitch); } } - TRACE("Created texture %p.\n", object); - *texture = object; + TRACE("Created texture %p.\n", *texture); return WINED3D_OK; } @@ -3624,7 +3843,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i { struct wined3d_device *device = texture->resource.device; struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_surface *surface; + struct wined3d_dc_info *dc_info; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -3644,25 +3863,25 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i return WINED3DERR_INVALIDCALL; } - surface = sub_resource->u.surface; - if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) return WINED3DERR_INVALIDCALL; - if (!surface->dc) + if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc) { - wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx}; + + wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc) + return WINED3DERR_INVALIDCALL; } - if (!surface->dc) - return WINED3DERR_INVALIDCALL; if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) texture->flags |= WINED3D_TEXTURE_DC_IN_USE; ++texture->resource.map_count; ++sub_resource->map_count; - *dc = surface->dc; + *dc = dc_info[sub_resource_idx].dc; TRACE("Returning dc %p.\n", *dc); return WINED3D_OK; @@ -3672,7 +3891,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign { struct wined3d_device *device = texture->resource.device; struct wined3d_texture_sub_resource *sub_resource; - struct wined3d_surface *surface; + struct wined3d_dc_info *dc_info; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -3685,21 +3904,22 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign return WINED3DERR_INVALIDCALL; } - surface = sub_resource->u.surface; - if (!(texture->flags & (WINED3D_TEXTURE_GET_DC_LENIENT | WINED3D_TEXTURE_DC_IN_USE))) return WINED3DERR_INVALIDCALL; - if (surface->dc != dc) + if (!(dc_info = texture->dc_info) || dc_info[sub_resource_idx].dc != dc) { - WARN("Application tries to release invalid DC %p, surface DC is %p.\n", dc, surface->dc); + WARN("Application tries to release invalid DC %p, sub-resource DC is %p.\n", + dc, dc_info ? dc_info[sub_resource_idx].dc : NULL); return WINED3DERR_INVALIDCALL; } - if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D)) + if (!(texture->resource.usage & WINED3DUSAGE_OWNDC)) { - wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface); - device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx}; + + wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); } --sub_resource->map_count; @@ -3710,3 +3930,226 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign return WINED3D_OK; } + +void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture, + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) +{ + unsigned int src_row_pitch, src_slice_pitch; + unsigned int update_w, update_h, update_d; + unsigned int src_level, dst_level; + struct wined3d_context *context; + struct wined3d_bo_address data; + + TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " + "src_texture %p, src_sub_resource_idx %u, src_box %s.\n", + dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z, + src_texture, src_sub_resource_idx, debug_box(src_box)); + + context = context_acquire(dst_texture->resource.device, NULL, 0); + + /* Only load the sub-resource for partial updates. For newly allocated + * textures the texture wouldn't be the current location, and we'd upload + * zeroes just to overwrite them again. */ + update_w = src_box->right - src_box->left; + update_h = src_box->bottom - src_box->top; + update_d = src_box->back - src_box->front; + dst_level = dst_sub_resource_idx % dst_texture->level_count; + if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level) + && update_h == wined3d_texture_get_level_height(dst_texture, dst_level) + && update_d == wined3d_texture_get_level_depth(dst_texture, dst_level)) + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + else + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + + src_level = src_sub_resource_idx % src_texture->level_count; + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, + src_texture->sub_resources[src_sub_resource_idx].locations); + wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); + + dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&data), + src_texture->resource.format, src_box, src_row_pitch, src_slice_pitch, dst_texture, + dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, dst_x, dst_y, dst_z); + + context_release(context); + + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); +} + +/* Partial downloads are not supported. */ +void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx) +{ + unsigned int src_level, dst_level, dst_row_pitch, dst_slice_pitch; + unsigned int dst_location = dst_texture->resource.map_binding; + struct wined3d_context *context; + struct wined3d_bo_address data; + struct wined3d_box src_box; + unsigned int src_location; + + context = context_acquire(src_texture->resource.device, NULL, 0); + + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); + wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &data, dst_location); + + if (src_texture->sub_resources[src_sub_resource_idx].locations & WINED3D_LOCATION_TEXTURE_RGB) + src_location = WINED3D_LOCATION_TEXTURE_RGB; + else + src_location = WINED3D_LOCATION_TEXTURE_SRGB; + src_level = src_sub_resource_idx % src_texture->level_count; + wined3d_texture_get_level_box(src_texture, src_level, &src_box); + + dst_level = dst_sub_resource_idx % dst_texture->level_count; + wined3d_texture_get_pitch(dst_texture, dst_level, &dst_row_pitch, &dst_slice_pitch); + + src_texture->texture_ops->texture_download_data(context, src_texture, src_sub_resource_idx, src_location, + &src_box, &data, dst_texture->resource.format, 0, 0, 0, dst_row_pitch, dst_slice_pitch); + + context_release(context); + + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location); +} + +static void wined3d_texture_no3d_upload_data(struct wined3d_context *context, + const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format, + const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) +{ + FIXME("Not implemented.\n"); +} + +static void wined3d_texture_no3d_download_data(struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, + const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, + const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch) +{ + FIXME("Not implemented.\n"); +} + +static BOOL wined3d_texture_no3d_prepare_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) +{ + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + return wined3d_resource_prepare_sysmem(&texture->resource); + + case WINED3D_LOCATION_USER_MEMORY: + if (!texture->user_memory) + ERR("Preparing WINED3D_LOCATION_USER_MEMORY, but texture->user_memory is NULL.\n"); + return TRUE; + + default: + FIXME("Unhandled location %s.\n", wined3d_debug_location(location)); + return FALSE; + } +} + +static BOOL wined3d_texture_no3d_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + if (location == WINED3D_LOCATION_USER_MEMORY || location == WINED3D_LOCATION_SYSMEM) + return TRUE; + + ERR("Unhandled location %s.\n", wined3d_debug_location(location)); + + return FALSE; +} + +static const struct wined3d_texture_ops wined3d_texture_no3d_ops = +{ + wined3d_texture_no3d_prepare_location, + wined3d_texture_no3d_load_location, + wined3d_texture_no3d_upload_data, + wined3d_texture_no3d_download_data, +}; + +HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("texture_no3d %p, device %p, desc %p, layer_count %u, " + "level_count %u, flags %#x, parent %p, parent_ops %p.\n", + texture_no3d, device, desc, layer_count, + level_count, flags, parent, parent_ops); + + return wined3d_texture_init(texture_no3d, desc, layer_count, level_count, + flags, device, parent, parent_ops, &texture_no3d[1], &wined3d_texture_no3d_ops); +} + +static void wined3d_texture_vk_upload_data(struct wined3d_context *context, + const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format, + const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) +{ + FIXME("Not implemented.\n"); +} + +static void wined3d_texture_vk_download_data(struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, + const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, + const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch) +{ + FIXME("Not implemented.\n"); +} + +static BOOL wined3d_texture_vk_prepare_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) +{ + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + return wined3d_resource_prepare_sysmem(&texture->resource); + + case WINED3D_LOCATION_USER_MEMORY: + if (!texture->user_memory) + ERR("Preparing WINED3D_LOCATION_USER_MEMORY, but texture->user_memory is NULL.\n"); + return TRUE; + + case WINED3D_LOCATION_TEXTURE_RGB: + /* The Vulkan image is created during resource creation. */ + return TRUE; + + default: + FIXME("Unhandled location %s.\n", wined3d_debug_location(location)); + return FALSE; + } +} + +static BOOL wined3d_texture_vk_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + FIXME("Not implemented.\n"); + + return FALSE; +} + +static const struct wined3d_texture_ops wined3d_texture_vk_ops = +{ + wined3d_texture_vk_prepare_location, + wined3d_texture_vk_load_location, + wined3d_texture_vk_upload_data, + wined3d_texture_vk_download_data, +}; + +HRESULT wined3d_texture_vk_init(struct wined3d_texture_vk *texture_vk, struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("texture_vk %p, device %p, desc %p, layer_count %u, " + "level_count %u, flags %#x, parent %p, parent_ops %p.\n", + texture_vk, device, desc, layer_count, + level_count, flags, parent, parent_ops); + + return wined3d_texture_init(&texture_vk->t, desc, layer_count, level_count, + flags, device, parent, parent_ops, &texture_vk[1], &wined3d_texture_vk_ops); +} diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c index 3c6d218f27d..dc0823197ce 100644 --- a/dll/directx/wine/wined3d/utils.c +++ b/dll/directx/wine/wined3d/utils.c @@ -122,10 +122,7 @@ static const struct wined3d_format_channels formats[] = /* Bump mapping stuff */ {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0}, {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0}, - {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0}, - {WINED3DFMT_R10G10B10X2_UINT, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, - {WINED3DFMT_R10G10B10X2_SNORM, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0}, /* Depth stencil formats */ {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, @@ -133,8 +130,6 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1}, {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0}, {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4}, - {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, - {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0}, {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8}, /* Vendor-specific formats */ {WINED3DFMT_ATI1N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, @@ -158,6 +153,7 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0}, {WINED3DFMT_R32G8X24_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 8, 32, 8}, {WINED3DFMT_R10G10B10A2_TYPELESS, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0}, + {WINED3DFMT_R10G10B10X2_TYPELESS, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0}, {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, @@ -230,6 +226,8 @@ static const struct wined3d_typed_format_info typed_formats[] = {WINED3DFMT_R10G10B10A2_SNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "iiii"}, {WINED3DFMT_R10G10B10A2_UINT, WINED3DFMT_R10G10B10A2_TYPELESS, "UUUU"}, {WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "uuuu"}, + {WINED3DFMT_R10G10B10X2_SNORM, WINED3DFMT_R10G10B10X2_TYPELESS, "iiiX"}, + {WINED3DFMT_R10G10B10X2_UINT, WINED3DFMT_R10G10B10X2_TYPELESS, "UUUX"}, {WINED3DFMT_R8G8B8A8_UINT, WINED3DFMT_R8G8B8A8_TYPELESS, "UUUU"}, {WINED3DFMT_R8G8B8A8_SINT, WINED3DFMT_R8G8B8A8_TYPELESS, "IIII"}, {WINED3DFMT_R8G8B8A8_SNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "iiii"}, @@ -330,8 +328,10 @@ struct wined3d_format_base_flags * resource size. */ static const struct wined3d_format_base_flags format_base_flags[] = { - {WINED3DFMT_ATI1N, WINED3DFMT_FLAG_BROKEN_PITCH}, - {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH}, + {WINED3DFMT_ATI1N, WINED3DFMT_FLAG_MAPPABLE | WINED3DFMT_FLAG_BROKEN_PITCH}, + {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_MAPPABLE | WINED3DFMT_FLAG_BROKEN_PITCH}, + {WINED3DFMT_D16_LOCKABLE, WINED3DFMT_FLAG_MAPPABLE}, + {WINED3DFMT_INTZ, WINED3DFMT_FLAG_MAPPABLE}, {WINED3DFMT_R11G11B10_FLOAT, WINED3DFMT_FLAG_FLOAT}, {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, @@ -342,85 +342,311 @@ static const struct wined3d_format_base_flags format_base_flags[] = {WINED3DFMT_RESZ, WINED3DFMT_FLAG_EXTENSION}, }; +static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b) +{ + BYTE c; + + /* (2⁸ - 1) / (2⁵ - 1) ≈ 2⁸ / 2⁵ + 2⁸ / 2¹⁰ + * (2⁸ - 1) / (2⁶ - 1) ≈ 2⁸ / 2⁶ + 2⁸ / 2¹² */ + c = rgb565 >> 11; + *r = (c << 3) + (c >> 2); + c = (rgb565 >> 5) & 0x3f; + *g = (c << 2) + (c >> 4); + c = rgb565 & 0x1f; + *b = (c << 3) + (c >> 2); +} + +static void build_dxtn_colour_table(WORD colour0, WORD colour1, + DWORD colour_table[4], enum wined3d_format_id format_id) +{ + unsigned int i; + struct + { + BYTE r, g, b; + } c[4]; + + rgb888_from_rgb565(colour0, &c[0].r, &c[0].g, &c[0].b); + rgb888_from_rgb565(colour1, &c[1].r, &c[1].g, &c[1].b); + + if (format_id == WINED3DFMT_BC1_UNORM && colour0 <= colour1) + { + c[2].r = (c[0].r + c[1].r) / 2; + c[2].g = (c[0].g + c[1].g) / 2; + c[2].b = (c[0].b + c[1].b) / 2; + + c[3].r = 0; + c[3].g = 0; + c[3].b = 0; + } + else + { + for (i = 0; i < 2; ++i) + { + c[i + 2].r = (2 * c[i].r + c[1 - i].r) / 3; + c[i + 2].g = (2 * c[i].g + c[1 - i].g) / 3; + c[i + 2].b = (2 * c[i].b + c[1 - i].b) / 3; + } + } + + for (i = 0; i < 4; ++i) + { + colour_table[i] = (c[i].r << 16) | (c[i].g << 8) | c[i].b; + } +} + +static void build_bc3_alpha_table(BYTE alpha0, BYTE alpha1, BYTE alpha_table[8]) +{ + unsigned int i; + + alpha_table[0] = alpha0; + alpha_table[1] = alpha1; + + if (alpha0 > alpha1) + { + for (i = 0; i < 6; ++i) + { + alpha_table[2 + i] = ((6 - i) * alpha0 + (i + 1) * alpha1) / 7; + } + return; + } + else + { + for (i = 0; i < 4; ++i) + { + alpha_table[2 + i] = ((4 - i) * alpha0 + (i + 1) * alpha1) / 5; + } + alpha_table[6] = 0x00; + alpha_table[7] = 0xff; + } +} + +static void decompress_dxtn_block(const BYTE *src, BYTE *dst, unsigned int width, + unsigned int height, unsigned int dst_row_pitch, enum wined3d_format_id format_id) +{ + const UINT64 *s = (const UINT64 *)src; + BOOL bc1_alpha = FALSE; + DWORD colour_table[4]; + BYTE alpha_table[8]; + UINT64 alpha_bits; + DWORD colour_bits; + unsigned int x, y; + BYTE colour_idx; + DWORD *dst_row; + BYTE alpha; + + if (format_id == WINED3DFMT_BC1_UNORM) + { + WORD colour0, colour1; + + alpha_bits = 0; + + colour0 = s[0] & 0xffff; + colour1 = (s[0] >> 16) & 0xffff; + colour_bits = (s[0] >> 32) & 0xffffffff; + build_dxtn_colour_table(colour0, colour1, colour_table, format_id); + if (colour0 <= colour1) + bc1_alpha = TRUE; + } + else + { + alpha_bits = s[0]; + if (format_id == WINED3DFMT_BC3_UNORM) + { + build_bc3_alpha_table(alpha_bits & 0xff, (alpha_bits >> 8) & 0xff, alpha_table); + alpha_bits >>= 16; + } + + colour_bits = (s[1] >> 32) & 0xffffffff; + build_dxtn_colour_table(s[1] & 0xffff, (s[1] >> 16) & 0xffff, colour_table, format_id); + } + + for (y = 0; y < height; ++y) + { + dst_row = (DWORD *)&dst[y * dst_row_pitch]; + for (x = 0; x < width; ++x) + { + colour_idx = (colour_bits >> (y * 8 + x * 2)) & 0x3; + switch (format_id) + { + case WINED3DFMT_BC1_UNORM: + alpha = bc1_alpha && colour_idx == 3 ? 0x00 : 0xff; + break; + + case WINED3DFMT_BC2_UNORM: + alpha = (alpha_bits >> (y * 16 + x * 4)) & 0xf; + /* (2⁸ - 1) / (2⁴ - 1) ≈ 2⁸ / 2⁴ + 2⁸ / 2⁸ */ + alpha |= alpha << 4; + break; + + case WINED3DFMT_BC3_UNORM: + alpha = alpha_table[(alpha_bits >> (y * 12 + x * 3)) & 0x7]; + break; + + default: + alpha = 0xff; + break; + } + dst_row[x] = (alpha << 24) | colour_table[colour_idx]; + } + } +} + +static void decompress_dxtn(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, + unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned int dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth, enum wined3d_format_id format_id) +{ + unsigned int block_byte_count, block_w, block_h; + const BYTE *src_row, *src_slice = src; + BYTE *dst_row, *dst_slice = dst; + unsigned int x, y, z; + + block_byte_count = format_id == WINED3DFMT_BC1_UNORM ? 8 : 16; + + for (z = 0; z < depth; ++z) + { + src_row = src_slice; + dst_row = dst_slice; + for (y = 0; y < height; y += 4) + { + for (x = 0; x < width; x += 4) + { + block_w = min(width - x, 4); + block_h = min(height - y, 4); + decompress_dxtn_block(&src_row[x * (block_byte_count / 4)], + &dst_row[x * 4], block_w, block_h, dst_row_pitch, format_id); + } + src_row += src_row_pitch; + dst_row += dst_row_pitch * 4; + } + src_slice += src_slice_pitch; + dst_slice += dst_slice_pitch; + } +} + +static void decompress_bc3(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, + unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned int dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth) +{ + decompress_dxtn(src, dst, src_row_pitch, src_slice_pitch, dst_row_pitch, + dst_slice_pitch, width, height, depth, WINED3DFMT_BC3_UNORM); +} + +static void decompress_bc2(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, + unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned int dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth) +{ + decompress_dxtn(src, dst, src_row_pitch, src_slice_pitch, dst_row_pitch, + dst_slice_pitch, width, height, depth, WINED3DFMT_BC2_UNORM); +} + +static void decompress_bc1(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, + unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned int dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth) +{ + decompress_dxtn(src, dst, src_row_pitch, src_slice_pitch, dst_row_pitch, + dst_slice_pitch, width, height, depth, WINED3DFMT_BC1_UNORM); +} + +static const struct wined3d_format_decompress_info +{ + enum wined3d_format_id id; + void (*decompress)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth); +} +format_decompress_info[] = +{ + {WINED3DFMT_DXT1, decompress_bc1}, + {WINED3DFMT_DXT2, decompress_bc2}, + {WINED3DFMT_DXT3, decompress_bc2}, + {WINED3DFMT_DXT4, decompress_bc3}, + {WINED3DFMT_DXT5, decompress_bc3}, + {WINED3DFMT_BC1_UNORM, decompress_bc1}, + {WINED3DFMT_BC2_UNORM, decompress_bc2}, + {WINED3DFMT_BC3_UNORM, decompress_bc3}, +}; + struct wined3d_format_block_info { enum wined3d_format_id id; UINT block_width; UINT block_height; UINT block_byte_count; - BOOL verify; + unsigned int flags; }; static const struct wined3d_format_block_info format_block_info[] = { - {WINED3DFMT_DXT1, 4, 4, 8, TRUE}, - {WINED3DFMT_DXT2, 4, 4, 16, TRUE}, - {WINED3DFMT_DXT3, 4, 4, 16, TRUE}, - {WINED3DFMT_DXT4, 4, 4, 16, TRUE}, - {WINED3DFMT_DXT5, 4, 4, 16, TRUE}, - {WINED3DFMT_BC1_UNORM, 4, 4, 8, TRUE}, - {WINED3DFMT_BC2_UNORM, 4, 4, 16, TRUE}, - {WINED3DFMT_BC3_UNORM, 4, 4, 16, TRUE}, - {WINED3DFMT_BC4_UNORM, 4, 4, 8, TRUE}, - {WINED3DFMT_BC4_SNORM, 4, 4, 8, TRUE}, - {WINED3DFMT_BC5_UNORM, 4, 4, 16, TRUE}, - {WINED3DFMT_BC5_SNORM, 4, 4, 16, TRUE}, - {WINED3DFMT_BC6H_UF16, 4, 4, 16, TRUE}, - {WINED3DFMT_BC6H_SF16, 4, 4, 16, TRUE}, - {WINED3DFMT_BC7_UNORM, 4, 4, 16, TRUE}, - {WINED3DFMT_ATI1N, 4, 4, 8, FALSE}, - {WINED3DFMT_ATI2N, 4, 4, 16, FALSE}, - {WINED3DFMT_YUY2, 2, 1, 4, FALSE}, - {WINED3DFMT_UYVY, 2, 1, 4, FALSE}, + {WINED3DFMT_DXT1, 4, 4, 8, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_DXT2, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_DXT3, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_DXT4, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_DXT5, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC1_UNORM, 4, 4, 8, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC2_UNORM, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC3_UNORM, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC4_UNORM, 4, 4, 8, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC4_SNORM, 4, 4, 8, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC5_UNORM, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC5_SNORM, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC6H_UF16, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC6H_SF16, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_BC7_UNORM, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED}, + {WINED3DFMT_ATI1N, 4, 4, 8, WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY}, + {WINED3DFMT_ATI2N, 4, 4, 16, WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY}, + {WINED3DFMT_YUY2, 2, 1, 4, WINED3DFMT_FLAG_BLOCKS_NO_VERIFY}, + {WINED3DFMT_UYVY, 2, 1, 4, WINED3DFMT_FLAG_BLOCKS_NO_VERIFY}, }; struct wined3d_format_vertex_info { enum wined3d_format_id id; enum wined3d_ffp_emit_idx emit_idx; - unsigned int component_count; GLenum gl_vtx_type; - GLboolean gl_normalized; enum wined3d_gl_extension extension; }; static const struct wined3d_format_vertex_info format_vertex_info[] = { - {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, GL_FALSE}, - {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, GL_FALSE}, - {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, GL_FALSE}, - {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, GL_FALSE}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE }, - {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, GL_FALSE}, - {WINED3DFMT_R16G16_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_SHORT, GL_FALSE}, - {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, GL_FALSE}, - {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, GL_FALSE}, - {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, GL_TRUE }, - {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, GL_TRUE }, - {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, GL_TRUE }, - {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, GL_TRUE }, - {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, GL_TRUE }, - {WINED3DFMT_R10G10B10X2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, GL_FALSE}, - {WINED3DFMT_R10G10B10X2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, GL_TRUE }, - {WINED3DFMT_R10G10B10A2_UNORM, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, + {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, GL_FLOAT}, + {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, GL_FLOAT}, + {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, GL_FLOAT}, + {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, GL_FLOAT}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, GL_UNSIGNED_BYTE}, + {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, GL_UNSIGNED_BYTE}, + {WINED3DFMT_R16G16_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_SHORT}, + {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, GL_SHORT}, + {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, GL_SHORT}, + {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, GL_UNSIGNED_BYTE}, + {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, GL_SHORT}, + {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, GL_SHORT}, + {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, GL_UNSIGNED_SHORT}, + {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, GL_UNSIGNED_SHORT}, + {WINED3DFMT_R10G10B10X2_UINT, WINED3D_FFP_EMIT_UDEC3, GL_UNSIGNED_SHORT}, + {WINED3DFMT_R10G10B10X2_SNORM, WINED3D_FFP_EMIT_DEC3N, GL_SHORT}, + {WINED3DFMT_R10G10B10A2_UNORM, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_INT_2_10_10_10_REV, ARB_VERTEX_TYPE_2_10_10_10_REV}, - {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_HALF_FLOAT, GL_FALSE}, - {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_HALF_FLOAT, GL_FALSE}, - {WINED3DFMT_R8G8B8A8_SNORM, WINED3D_FFP_EMIT_INVALID, 4, GL_BYTE, GL_TRUE }, - {WINED3DFMT_R8G8B8A8_SINT, WINED3D_FFP_EMIT_INVALID, 4, GL_BYTE, GL_FALSE}, - {WINED3DFMT_R16G16B16A16_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_SHORT, GL_FALSE}, - {WINED3DFMT_R8_UNORM, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_BYTE, GL_TRUE}, - {WINED3DFMT_R8_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_BYTE, GL_FALSE}, - {WINED3DFMT_R8_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_BYTE, GL_FALSE}, - {WINED3DFMT_R16_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_SHORT, GL_FALSE}, - {WINED3DFMT_R16_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_SHORT, GL_FALSE}, - {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, GL_FALSE}, - {WINED3DFMT_R32_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_INT, GL_FALSE}, - {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, GL_FALSE}, - {WINED3DFMT_R32G32_SINT, WINED3D_FFP_EMIT_INVALID, 2, GL_INT, GL_FALSE}, - {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, GL_FALSE}, - {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, GL_FALSE}, - {WINED3DFMT_R32G32B32A32_SINT, WINED3D_FFP_EMIT_INVALID, 4, GL_INT, GL_FALSE}, + /* Without ARB_half_float_vertex we convert these on upload. */ + {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, GL_FLOAT}, + {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, GL_HALF_FLOAT, ARB_HALF_FLOAT_VERTEX}, + {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, GL_FLOAT}, + {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, GL_HALF_FLOAT, ARB_HALF_FLOAT_VERTEX}, + {WINED3DFMT_R8G8B8A8_SNORM, WINED3D_FFP_EMIT_INVALID, GL_BYTE}, + {WINED3DFMT_R8G8B8A8_SINT, WINED3D_FFP_EMIT_INVALID, GL_BYTE}, + {WINED3DFMT_R8G8_UNORM, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_BYTE}, + {WINED3DFMT_R16G16B16A16_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_SHORT}, + {WINED3DFMT_R8_UNORM, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_BYTE}, + {WINED3DFMT_R8_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_BYTE}, + {WINED3DFMT_R8_SINT, WINED3D_FFP_EMIT_INVALID, GL_BYTE}, + {WINED3DFMT_R16_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_SHORT}, + {WINED3DFMT_R16_SINT, WINED3D_FFP_EMIT_INVALID, GL_SHORT}, + {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_INT}, + {WINED3DFMT_R32_SINT, WINED3D_FFP_EMIT_INVALID, GL_INT}, + {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_INT}, + {WINED3DFMT_R32G32_SINT, WINED3D_FFP_EMIT_INVALID, GL_INT}, + {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_INT}, + {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, GL_UNSIGNED_INT}, + {WINED3DFMT_R32G32B32A32_SINT, WINED3D_FFP_EMIT_INVALID, GL_INT}, }; struct wined3d_format_texture_info @@ -440,6 +666,9 @@ struct wined3d_format_texture_info void (*download)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned int dst_slice_pitch, unsigned int width, unsigned int height, unsigned int depth); + void (*decompress)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth); }; static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, @@ -895,45 +1124,9 @@ static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD colo && color <= color_key->color_space_high_value; } -static void convert_p8_uint_b8g8r8a8_unorm(const BYTE *src, unsigned int src_pitch, - BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, - const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) -{ - const BYTE *src_row; - unsigned int x, y; - DWORD *dst_row; - - if (!palette) - { - /* FIXME: This should probably use the system palette. */ - FIXME("P8 surface loaded without a palette.\n"); - - for (y = 0; y < height; ++y) - { - memset(&dst[dst_pitch * y], 0, width * 4); - } - - return; - } - - for (y = 0; y < height; ++y) - { - src_row = &src[src_pitch * y]; - dst_row = (DWORD *)&dst[dst_pitch * y]; - for (x = 0; x < width; ++x) - { - BYTE src_color = src_row[x]; - dst_row[x] = 0xff000000 - | (palette->colors[src_color].rgbRed << 16) - | (palette->colors[src_color].rgbGreen << 8) - | palette->colors[src_color].rgbBlue; - } - } -} - static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, - const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) + const struct wined3d_color_key *color_key) { const WORD *src_row; unsigned int x, y; @@ -956,7 +1149,7 @@ static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsig static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, - const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) + const struct wined3d_color_key *color_key) { const WORD *src_row; unsigned int x, y; @@ -979,7 +1172,7 @@ static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, uns static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, - const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) + const struct wined3d_color_key *color_key) { const BYTE *src_row; unsigned int x, y; @@ -1000,7 +1193,7 @@ static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsig static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, - const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) + const struct wined3d_color_key *color_key) { const DWORD *src_row; unsigned int x, y; @@ -1023,7 +1216,7 @@ static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, uns static void convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height, - const struct wined3d_palette *palette, const struct wined3d_color_key *color_key) + const struct wined3d_color_key *color_key) { const DWORD *src_row; unsigned int x, y; @@ -1062,10 +1255,6 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers {WINED3DFMT_B8G8R8X8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key }}, {WINED3DFMT_B8G8R8A8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key }}, }; - static const struct wined3d_color_key_conversion convert_p8 = - { - WINED3DFMT_B8G8R8A8_UNORM, convert_p8_uint_b8g8r8a8_unorm - }; if (need_alpha_ck && (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)) { @@ -1078,17 +1267,13 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers FIXME("Color-keying not supported with format %s.\n", debug_d3dformat(format->id)); } - /* FIXME: This should check if the blitter backend can do P8 conversion, - * instead of checking for ARB_fragment_program. */ - if (format->id == WINED3DFMT_P8_UINT - && !(texture->resource.device->adapter->gl_info.supported[ARB_FRAGMENT_PROGRAM] - && texture->swapchain && texture == texture->swapchain->front_buffer)) - return &convert_p8; - return NULL; } -/* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set: +/* We intentionally don't support WINED3DFMT_D32_UNORM. No hardware driver + * supports it, and applications get confused when we do. + * + * The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set: * * These are never supported on native. * WINED3DFMT_B8G8R8_UNORM @@ -1167,77 +1352,67 @@ static const struct wined3d_format_texture_info format_texture_info[] = {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, + | WINED3DFMT_FLAG_SRGB_READ, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, + | WINED3DFMT_FLAG_SRGB_READ, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, + | WINED3DFMT_FLAG_SRGB_READ, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, + | WINED3DFMT_FLAG_SRGB_READ, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, + | WINED3DFMT_FLAG_SRGB_READ, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_BC4_UNORM, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, GL_RED, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_BC4_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_COMPRESSED_SIGNED_RED_RGTC1, 0, GL_RED, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_BC5_UNORM, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, GL_RG, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_BC5_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_COMPRESSED_SIGNED_RG_RGTC2, 0, GL_RG, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_BC6H_UF16, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_BPTC, NULL}, {WINED3DFMT_BC6H_SF16, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_BPTC, NULL}, {WINED3DFMT_BC7_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_BPTC, NULL}, /* IEEE formats */ {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, @@ -1350,16 +1525,22 @@ static const struct wined3d_format_texture_info format_texture_info[] = ARB_TEXTURE_RG, NULL}, {WINED3DFMT_A8_UNORM, GL_R8, GL_R8, 0, GL_RED, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, ARB_TEXTURE_RG, NULL}, {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, WINED3D_GL_LEGACY_CONTEXT, NULL}, {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, WINED3D_GL_EXT_NONE, NULL}, + {WINED3DFMT_R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGB10_A2UI, 0, + GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RGB10_A2UI, NULL}, {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING @@ -1599,14 +1780,6 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, ARB_DEPTH_TEXTURE, NULL}, - {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, - WINED3DFMT_FLAG_DEPTH, - WINED3D_GL_EXT_NONE, NULL}, - {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, - ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, @@ -1684,30 +1857,22 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_RGBA_INTEGER, GL_INT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, EXT_TEXTURE_INTEGER, NULL}, - {WINED3DFMT_R24_UNORM_X8_TYPELESS, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE, NULL}, /* Vendor-specific formats */ {WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, GL_RED, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ATI_TEXTURE_COMPRESSION_3DC, NULL}, {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, EXT_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, GL_RG, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_COMPRESSED, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, ARB_TEXTURE_COMPRESSION_RGTC, NULL}, {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, @@ -1763,7 +1928,27 @@ static inline int get_format_idx(enum wined3d_format_id format_id) return -1; } -static struct wined3d_format *get_format_internal(struct wined3d_gl_info *gl_info, +static struct wined3d_format_gl *wined3d_format_gl_mutable(struct wined3d_format *format) +{ + return CONTAINING_RECORD(format, struct wined3d_format_gl, f); +} + +static struct wined3d_format_vk *wined3d_format_vk_mutable(struct wined3d_format *format) +{ + return CONTAINING_RECORD(format, struct wined3d_format_vk, f); +} + +static struct wined3d_format *get_format_by_idx(const struct wined3d_adapter *adapter, int fmt_idx) +{ + return (struct wined3d_format *)((BYTE *)adapter->formats + fmt_idx * adapter->format_size); +} + +static struct wined3d_format_gl *get_format_gl_by_idx(const struct wined3d_adapter *adapter, int fmt_idx) +{ + return wined3d_format_gl_mutable(get_format_by_idx(adapter, fmt_idx)); +} + +static struct wined3d_format *get_format_internal(const struct wined3d_adapter *adapter, enum wined3d_format_id format_id) { int fmt_idx; @@ -1774,13 +1959,25 @@ static struct wined3d_format *get_format_internal(struct wined3d_gl_info *gl_inf return NULL; } - return &gl_info->formats[fmt_idx]; + return get_format_by_idx(adapter, fmt_idx); +} + +static struct wined3d_format_gl *get_format_gl_internal(const struct wined3d_adapter *adapter, + enum wined3d_format_id format_id) +{ + struct wined3d_format *format; + + if ((format = get_format_internal(adapter, format_id))) + return wined3d_format_gl_mutable(format); + + return NULL; } -static void copy_format(struct wined3d_format *dst_format, const struct wined3d_format *src_format) +static void copy_format(const struct wined3d_adapter *adapter, + struct wined3d_format *dst_format, const struct wined3d_format *src_format) { enum wined3d_format_id id = dst_format->id; - *dst_format = *src_format; + memcpy(dst_format, src_format, adapter->format_size); dst_format->id = id; } @@ -1826,23 +2023,15 @@ static enum wined3d_channel_type map_channel_type(char t) } } -static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) +static BOOL init_format_base_info(struct wined3d_adapter *adapter) { struct wined3d_format *format; unsigned int i, j; - gl_info->format_count = WINED3D_FORMAT_COUNT; - if (!(gl_info->formats = heap_calloc(gl_info->format_count - + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*gl_info->formats)))) - { - ERR("Failed to allocate memory.\n"); - return FALSE; - } - for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (!(format = get_format_internal(gl_info, formats[i].id))) - goto fail; + if (!(format = get_format_internal(adapter, formats[i].id))) + return FALSE; format->id = formats[i].id; format->red_size = formats[i].red_size; @@ -1863,14 +2052,15 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) for (i = 0; i < ARRAY_SIZE(typed_formats); ++i) { - const struct wined3d_format *typeless_format; + struct wined3d_format *typeless_format; + unsigned int component_count = 0; DWORD flags = 0; - if (!(format = get_format_internal(gl_info, typed_formats[i].id))) - goto fail; + if (!(format = get_format_internal(adapter, typed_formats[i].id))) + return FALSE; - if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id))) - goto fail; + if (!(typeless_format = get_format_internal(adapter, typed_formats[i].typeless_id))) + return FALSE; format->id = typed_formats[i].id; format->red_size = typeless_format->red_size; @@ -1889,13 +2079,20 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) format->block_byte_count = typeless_format->block_byte_count; format->typeless_id = typeless_format->id; + typeless_format->typeless_id = typeless_format->id; + for (j = 0; j < strlen(typed_formats[i].channels); ++j) { enum wined3d_channel_type channel_type = map_channel_type(typed_formats[i].channels[j]); + + if (channel_type == WINED3D_CHANNEL_TYPE_UNORM || channel_type == WINED3D_CHANNEL_TYPE_SNORM) + flags |= WINED3DFMT_FLAG_NORMALISED; if (channel_type == WINED3D_CHANNEL_TYPE_UINT || channel_type == WINED3D_CHANNEL_TYPE_SINT) flags |= WINED3DFMT_FLAG_INTEGER; if (channel_type == WINED3D_CHANNEL_TYPE_FLOAT) flags |= WINED3DFMT_FLAG_FLOAT; + if (channel_type != WINED3D_CHANNEL_TYPE_UNUSED) + ++component_count; if (channel_type == WINED3D_CHANNEL_TYPE_DEPTH && !format->depth_size) { @@ -1904,48 +2101,89 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) } } + format->component_count = component_count; format_set_flag(format, flags); } for (i = 0; i < ARRAY_SIZE(ddi_formats); ++i) { - if (!(format = get_format_internal(gl_info, ddi_formats[i].id))) - goto fail; + if (!(format = get_format_internal(adapter, ddi_formats[i].id))) + return FALSE; format->ddi_format = ddi_formats[i].ddi_format; } for (i = 0; i < ARRAY_SIZE(format_base_flags); ++i) { - if (!(format = get_format_internal(gl_info, format_base_flags[i].id))) - goto fail; + if (!(format = get_format_internal(adapter, format_base_flags[i].id))) + return FALSE; format_set_flag(format, format_base_flags[i].flags); } return TRUE; - -fail: - heap_free(gl_info->formats); - return FALSE; } -static BOOL init_format_block_info(struct wined3d_gl_info *gl_info) +static BOOL init_format_block_info(struct wined3d_adapter *adapter) { struct wined3d_format *format; unsigned int i; for (i = 0; i < ARRAY_SIZE(format_block_info); ++i) { - if (!(format = get_format_internal(gl_info, format_block_info[i].id))) + if (!(format = get_format_internal(adapter, format_block_info[i].id))) return FALSE; format->block_width = format_block_info[i].block_width; format->block_height = format_block_info[i].block_height; format->block_byte_count = format_block_info[i].block_byte_count; - format_set_flag(format, WINED3DFMT_FLAG_BLOCKS); - if (!format_block_info[i].verify) - format_set_flag(format, WINED3DFMT_FLAG_BLOCKS_NO_VERIFY); + format_set_flag(format, WINED3DFMT_FLAG_BLOCKS | format_block_info[i].flags); + } + + return TRUE; +} + +/* Most compressed formats are not supported for 3D textures by OpenGL. + * + * In the case of the S3TC/DXTn formats, NV_texture_compression_vtc provides + * these formats for 3D textures, but unfortunately the block layout is + * different from the one used by Direct3D. + * + * Since applications either don't check format availability at all before + * using these, or refuse to run without them, we decompress them on upload. + * + * Affected applications include "Heroes VI", "From Dust", "Halo Online" and + * "Eldorado". */ +static BOOL init_format_decompress_info(struct wined3d_adapter *adapter) +{ + struct wined3d_format *format; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(format_decompress_info); ++i) + { + if (!(format = get_format_internal(adapter, format_decompress_info[i].id))) + return FALSE; + + format->flags[WINED3D_GL_RES_TYPE_TEX_3D] |= WINED3DFMT_FLAG_DECOMPRESS; + format->decompress = format_decompress_info[i].decompress; + } + + return TRUE; +} + +static BOOL init_srgb_formats(struct wined3d_adapter *adapter) +{ + struct wined3d_format *format, *srgb_format; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) + { + if (!(srgb_format = get_format_internal(adapter, format_srgb_info[i].srgb_format_id))) + return FALSE; + if (!(format = get_format_internal(adapter, format_srgb_info[i].base_format_id))) + return FALSE; + + copy_format(adapter, srgb_format, format); } return TRUE; @@ -2231,7 +2469,7 @@ static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d } /* Context activation is done by the caller. */ -static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_format *format) +static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_format_gl *format) { /* Check if the default internal format is supported as a frame buffer * target, otherwise fall back to the render target internal. @@ -2240,24 +2478,24 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 1.0f}; static const struct wined3d_color half_transparent_red = {1.0f, 0.0f, 0.0f, 0.5f}; const struct wined3d_gl_info *gl_info = ctx->gl_info; - GLenum status, rt_internal = format->rtInternal; + GLenum status, rt_internal = format->rt_internal; GLuint object, color_rb; enum wined3d_gl_resource_type type; BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE; gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - for (type = 0; type < ARRAY_SIZE(format->flags); ++type) + for (type = 0; type < ARRAY_SIZE(format->f.flags); ++type) { const char *type_string = "color"; if (type == WINED3D_GL_RES_TYPE_BUFFER) continue; - create_and_bind_fbo_attachment(gl_info, format->flags[type], type, &object, format->glInternal, - format->glFormat, format->glType); + create_and_bind_fbo_attachment(gl_info, format->f.flags[type], type, + &object, format->internal, format->format, format->type); - if (format->flags[type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) + if (format->f.flags[type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) { gl_info->fbo_ops.glGenRenderbuffers(1, &color_rb); gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, color_rb); @@ -2278,39 +2516,39 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("Format %s is supported as FBO %s attachment, type %u.\n", - debug_d3dformat(format->id), type_string, type); - format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE; - format->rtInternal = format->glInternal; + debug_d3dformat(format->f.id), type_string, type); + format->f.flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE; + format->rt_internal = format->internal; regular_fmt_used = TRUE; } else { if (!rt_internal) { - if (format->flags[type] & WINED3DFMT_FLAG_RENDERTARGET) + if (format->f.flags[type] & WINED3DFMT_FLAG_RENDERTARGET) { WARN("Format %s with rendertarget flag is not supported as FBO color attachment (type %u)," - " and no fallback specified.\n", debug_d3dformat(format->id), type); - format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; + " and no fallback specified.\n", debug_d3dformat(format->f.id), type); + format->f.flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; } else { TRACE("Format %s is not supported as FBO %s attachment, type %u.\n", - debug_d3dformat(format->id), type_string, type); + debug_d3dformat(format->f.id), type_string, type); } - format->rtInternal = format->glInternal; + format->rt_internal = format->internal; } else { TRACE("Format %s is not supported as FBO %s attachment (type %u)," " trying rtInternal format as fallback.\n", - debug_d3dformat(format->id), type_string, type); + debug_d3dformat(format->f.id), type_string, type); while (gl_info->gl_ops.gl.p_glGetError()); delete_fbo_attachment(gl_info, type, object); - create_and_bind_fbo_attachment(gl_info, format->flags[type], type, &object, format->rtInternal, - format->glFormat, format->glType); + create_and_bind_fbo_attachment(gl_info, format->f.flags[type], type, + &object, format->rt_internal, format->format, format->type); status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); checkGLcall("Framebuffer format check"); @@ -2318,25 +2556,25 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("Format %s rtInternal format is supported as FBO %s attachment, type %u.\n", - debug_d3dformat(format->id), type_string, type); + debug_d3dformat(format->f.id), type_string, type); fallback_fmt_used = TRUE; } else { WARN("Format %s rtInternal format is not supported as FBO %s attachment, type %u.\n", - debug_d3dformat(format->id), type_string, type); - format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; + debug_d3dformat(format->f.id), type_string, type); + format->f.flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; } } } if (status == GL_FRAMEBUFFER_COMPLETE - && ((format->flags[type] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) + && ((format->f.flags[type] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) - && !(format->flags[type] & WINED3DFMT_FLAG_INTEGER) - && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT - && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA - && (format->red_size || format->alpha_size)) + && !(format->f.flags[type] & WINED3DFMT_FLAG_INTEGER) + && format->f.id != WINED3DFMT_NULL && format->f.id != WINED3DFMT_P8_UINT + && format->format != GL_LUMINANCE && format->format != GL_LUMINANCE_ALPHA + && (format->f.red_size || format->f.alpha_size)) { DWORD readback[16 * 16 * 16], color, r_range, a_range; BYTE r, a; @@ -2364,8 +2602,8 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for { while (gl_info->gl_ops.gl.p_glGetError()); TRACE("Format %s doesn't support post-pixelshader blending, type %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; + debug_d3dformat(format->f.id), type); + format->f.flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; } else { @@ -2428,25 +2666,25 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for a = color >> 24; r = (color & 0x00ff0000u) >> 16; - r_range = format->red_size < 8 ? 1u << (8 - format->red_size) : 1; - a_range = format->alpha_size < 8 ? 1u << (8 - format->alpha_size) : 1; - if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range)) + r_range = format->f.red_size < 8 ? 1u << (8 - format->f.red_size) : 1; + a_range = format->f.alpha_size < 8 ? 1u << (8 - format->f.alpha_size) : 1; + if (format->f.red_size && (r < 0x7f - r_range || r > 0x7f + r_range)) match = FALSE; - else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range)) + else if (format->f.alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range)) match = FALSE; if (!match) { TRACE("Format %s doesn't support post-pixelshader blending, type %u.\n", - debug_d3dformat(format->id), type); + debug_d3dformat(format->f.id), type); TRACE("Color output: %#x\n", color); - format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; + format->f.flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; } else { TRACE("Format %s supports post-pixelshader blending, type %u.\n", - debug_d3dformat(format->id), type); + debug_d3dformat(format->f.id), type); TRACE("Color output: %#x\n", color); - format->flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; + format->f.flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; } } @@ -2460,11 +2698,11 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for } } - if (format->glInternal != format->glGammaInternal) + if (format->internal != format->srgb_internal) { delete_fbo_attachment(gl_info, type, object); - create_and_bind_fbo_attachment(gl_info, format->flags[type], type, &object, format->glGammaInternal, - format->glFormat, format->glType); + create_and_bind_fbo_attachment(gl_info, format->f.flags[type], type, &object, format->srgb_internal, + format->format, format->type); status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); checkGLcall("Framebuffer format check"); @@ -2472,22 +2710,22 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("Format %s's sRGB format is FBO attachable, type %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; + debug_d3dformat(format->f.id), type); + format->f.flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - format->glInternal = format->glGammaInternal; + format->internal = format->srgb_internal; } else { WARN("Format %s's sRGB format is not FBO attachable, type %u.\n", - debug_d3dformat(format->id), type); - format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); + debug_d3dformat(format->f.id), type); + format_clear_flag(&format->f, WINED3DFMT_FLAG_SRGB_WRITE); } } else if (status == GL_FRAMEBUFFER_COMPLETE) - format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; + format->f.flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; - if (format->flags[type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) + if (format->f.flags[type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) { gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); gl_info->fbo_ops.glDeleteRenderbuffers(1, &color_rb); @@ -2500,36 +2738,37 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for if (fallback_fmt_used && regular_fmt_used) { FIXME("Format %s needs different render target formats for different resource types.\n", - debug_d3dformat(format->id)); - format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE + debug_d3dformat(format->f.id)); + format_clear_flag(&format->f, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE | WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING); } } -static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format, +static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format_gl *format, GLint internal, GLenum pname, DWORD flag, const char *string) { GLint value; enum wined3d_gl_resource_type type; - for (type = 0; type < ARRAY_SIZE(format->flags); ++type) + for (type = 0; type < ARRAY_SIZE(format->f.flags); ++type) { gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), internal, pname, 1, &value); if (value == GL_FULL_SUPPORT) { - TRACE("Format %s supports %s, resource type %u.\n", debug_d3dformat(format->id), string, type); - format->flags[type] |= flag; + TRACE("Format %s supports %s, resource type %u.\n", debug_d3dformat(format->f.id), string, type); + format->f.flags[type] |= flag; } else { - TRACE("Format %s doesn't support %s, resource type %u.\n", debug_d3dformat(format->id), string, type); - format->flags[type] &= ~flag; + TRACE("Format %s doesn't support %s, resource type %u.\n", debug_d3dformat(format->f.id), string, type); + format->f.flags[type] &= ~flag; } } } /* Context activation is done by the caller. */ -static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) +static void init_format_fbo_compat_info(const struct wined3d_adapter *adapter, + struct wined3d_caps_gl_ctx *ctx) { const struct wined3d_gl_info *gl_info = ctx->gl_info; unsigned int i, type; @@ -2537,58 +2776,58 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) { - for (i = 0; i < gl_info->format_count; ++i) + for (i = 0; i < WINED3D_FORMAT_COUNT; ++i) { - GLint value; - struct wined3d_format *format = &gl_info->formats[i]; + struct wined3d_format_gl *format = get_format_gl_by_idx(adapter, i); BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE; - GLenum rt_internal = format->rtInternal; + GLenum rt_internal = format->rt_internal; + GLint value; - if (!format->glInternal) + if (!format->internal) continue; - for (type = 0; type < ARRAY_SIZE(format->flags); ++type) + for (type = 0; type < ARRAY_SIZE(format->f.flags); ++type) { gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), - format->glInternal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); + format->internal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); if (value == GL_FULL_SUPPORT) { TRACE("Format %s is supported as FBO color attachment, resource type %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE; - format->rtInternal = format->glInternal; + debug_d3dformat(format->f.id), type); + format->f.flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE; + format->rt_internal = format->internal; regular_fmt_used = TRUE; gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), - format->glInternal, GL_FRAMEBUFFER_BLEND, 1, &value); + format->internal, GL_FRAMEBUFFER_BLEND, 1, &value); if (value == GL_FULL_SUPPORT) { TRACE("Format %s supports post-pixelshader blending, resource type %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; + debug_d3dformat(format->f.id), type); + format->f.flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; } else { TRACE("Format %s doesn't support post-pixelshader blending, resource typed %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; + debug_d3dformat(format->f.id), type); + format->f.flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; } } else { if (!rt_internal) { - if (format->flags[type] & WINED3DFMT_FLAG_RENDERTARGET) + if (format->f.flags[type] & WINED3DFMT_FLAG_RENDERTARGET) { WARN("Format %s with rendertarget flag is not supported as FBO color attachment" " and no fallback specified, resource type %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; + debug_d3dformat(format->f.id), type); + format->f.flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; } else TRACE("Format %s is not supported as FBO color attachment," - " resource type %u.\n", debug_d3dformat(format->id), type); - format->rtInternal = format->glInternal; + " resource type %u.\n", debug_d3dformat(format->f.id), type); + format->rt_internal = format->internal; } else { @@ -2597,46 +2836,46 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) if (value == GL_FULL_SUPPORT) { TRACE("Format %s rtInternal format is supported as FBO color attachment," - " resource type %u.\n", debug_d3dformat(format->id), type); + " resource type %u.\n", debug_d3dformat(format->f.id), type); fallback_fmt_used = TRUE; } else { WARN("Format %s rtInternal format is not supported as FBO color attachment," - " resource type %u.\n", debug_d3dformat(format->id), type); - format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; + " resource type %u.\n", debug_d3dformat(format->f.id), type); + format->f.flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET; } } } - if (format->glInternal != format->glGammaInternal) + if (format->internal != format->srgb_internal) { gl_info->gl_ops.ext.p_glGetInternalformativ(wined3d_gl_type_to_enum(type), - format->glGammaInternal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); + format->srgb_internal, GL_FRAMEBUFFER_RENDERABLE, 1, &value); if (value == GL_FULL_SUPPORT) { TRACE("Format %s's sRGB format is FBO attachable, resource type %u.\n", - debug_d3dformat(format->id), type); - format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; + debug_d3dformat(format->f.id), type); + format->f.flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - format->glInternal = format->glGammaInternal; + format->internal = format->srgb_internal; } else { WARN("Format %s's sRGB format is not FBO attachable, resource type %u.\n", - debug_d3dformat(format->id), type); - format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); + debug_d3dformat(format->f.id), type); + format_clear_flag(&format->f, WINED3DFMT_FLAG_SRGB_WRITE); } } - else if (format->flags[type] & WINED3DFMT_FLAG_FBO_ATTACHABLE) - format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; + else if (format->f.flags[type] & WINED3DFMT_FLAG_FBO_ATTACHABLE) + format->f.flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; } if (fallback_fmt_used && regular_fmt_used) { FIXME("Format %s needs different render target formats for different resource types.\n", - debug_d3dformat(format->id)); - format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE + debug_d3dformat(format->f.id)); + format_clear_flag(&format->f, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE | WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING); } } @@ -2651,27 +2890,28 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); } - for (i = 0; i < gl_info->format_count; ++i) + for (i = 0; i < WINED3D_FORMAT_COUNT; ++i) { - struct wined3d_format *format = &gl_info->formats[i]; + struct wined3d_format_gl *format = get_format_gl_by_idx(adapter, i); - if (!format->glInternal) continue; + if (!format->internal) + continue; - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + if (format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) { TRACE("Skipping format %s because it's a compressed format.\n", - debug_d3dformat(format->id)); + debug_d3dformat(format->f.id)); continue; } if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id)); + TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->f.id)); check_fbo_compat(ctx, format); } else { - format->rtInternal = format->glInternal; + format->rt_internal = format->internal; } } @@ -2790,152 +3030,147 @@ static GLenum lookup_gl_view_class(GLenum internal_format) return GL_NONE; } -static void query_view_class(struct wined3d_format *format) +static void query_view_class(struct wined3d_format_gl *format) { GLenum internal_view_class, gamma_view_class, rt_view_class; - internal_view_class = lookup_gl_view_class(format->glInternal); - gamma_view_class = lookup_gl_view_class(format->glGammaInternal); - rt_view_class = lookup_gl_view_class(format->rtInternal); + internal_view_class = lookup_gl_view_class(format->internal); + gamma_view_class = lookup_gl_view_class(format->srgb_internal); + rt_view_class = lookup_gl_view_class(format->rt_internal); if (internal_view_class == gamma_view_class || gamma_view_class == rt_view_class) { - format->gl_view_class = internal_view_class; + format->view_class = internal_view_class; TRACE("Format %s is member of GL view class %#x.\n", - debug_d3dformat(format->id), format->gl_view_class); + debug_d3dformat(format->f.id), format->view_class); } else { - format->gl_view_class = GL_NONE; + format->view_class = GL_NONE; } } static void query_internal_format(struct wined3d_adapter *adapter, - struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info, + struct wined3d_format_gl *format, const struct wined3d_format_texture_info *texture_info, struct wined3d_gl_info *gl_info, BOOL srgb_write_supported, BOOL srgb_format) { - GLint count, multisample_types[MAX_MULTISAMPLE_TYPES]; + GLint count, multisample_types[8]; unsigned int i, max_log2; GLenum target; if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) { - query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE, + query_format_flag(gl_info, format, format->internal, GL_VERTEX_TEXTURE, WINED3DFMT_FLAG_VTF, "vertex texture usage"); - query_format_flag(gl_info, format, format->glInternal, GL_FILTER, + query_format_flag(gl_info, format, format->internal, GL_FILTER, WINED3DFMT_FLAG_FILTERING, "filtering"); - if (srgb_format || format->glGammaInternal != format->glInternal) + if (srgb_format || format->srgb_internal != format->internal) { - query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ, + query_format_flag(gl_info, format, format->srgb_internal, GL_SRGB_READ, WINED3DFMT_FLAG_SRGB_READ, "sRGB read"); if (srgb_write_supported) - query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE, + query_format_flag(gl_info, format, format->srgb_internal, GL_SRGB_WRITE, WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write"); else - format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); + format_clear_flag(&format->f, WINED3DFMT_FLAG_SRGB_WRITE); - if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE))) - format->glGammaInternal = format->glInternal; - else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) - format->glInternal = format->glGammaInternal; + if (!(format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] + & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE))) + format->srgb_internal = format->internal; + else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + format->internal = format->srgb_internal; } } else { if (!gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]) - format_clear_flag(format, WINED3DFMT_FLAG_VTF); + format_clear_flag(&format->f, WINED3DFMT_FLAG_VTF); if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) - format_set_flag(format, WINED3DFMT_FLAG_FILTERING); - else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT) - format_clear_flag(format, WINED3DFMT_FLAG_VTF); + format_set_flag(&format->f, WINED3DFMT_FLAG_FILTERING); + else if (format->f.id != WINED3DFMT_R32G32B32A32_FLOAT && format->f.id != WINED3DFMT_R32_FLOAT) + format_clear_flag(&format->f, WINED3DFMT_FLAG_VTF); - if (srgb_format || format->glGammaInternal != format->glInternal) + if (srgb_format || format->srgb_internal != format->internal) { /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */ if (!gl_info->supported[EXT_TEXTURE_SRGB]) { - format->glGammaInternal = format->glInternal; - format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); + format->srgb_internal = format->internal; + format_clear_flag(&format->f, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); } - else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) { - format->glInternal = format->glGammaInternal; + format->internal = format->srgb_internal; } } - if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write_supported) - format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); + if ((format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write_supported) + format_clear_flag(&format->f, WINED3DFMT_FLAG_SRGB_WRITE); if (!gl_info->supported[ARB_DEPTH_TEXTURE] && texture_info->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) { - format->flags[WINED3D_GL_RES_TYPE_TEX_1D] &= ~WINED3DFMT_FLAG_TEXTURE; - format->flags[WINED3D_GL_RES_TYPE_TEX_2D] &= ~WINED3DFMT_FLAG_TEXTURE; - format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - format->flags[WINED3D_GL_RES_TYPE_TEX_CUBE] &= ~WINED3DFMT_FLAG_TEXTURE; - format->flags[WINED3D_GL_RES_TYPE_TEX_RECT] &= ~WINED3DFMT_FLAG_TEXTURE; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_1D] &= ~WINED3DFMT_FLAG_TEXTURE; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] &= ~WINED3DFMT_FLAG_TEXTURE; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_CUBE] &= ~WINED3DFMT_FLAG_TEXTURE; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_RECT] &= ~WINED3DFMT_FLAG_TEXTURE; } } query_view_class(format); - if (format->glInternal && format->flags[WINED3D_GL_RES_TYPE_RB] + if (format->internal && format->f.flags[WINED3D_GL_RES_TYPE_RB] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) { if (gl_info->supported[ARB_INTERNALFORMAT_QUERY]) { target = gl_info->supported[ARB_TEXTURE_MULTISAMPLE] ? GL_TEXTURE_2D_MULTISAMPLE : GL_RENDERBUFFER; count = 0; - GL_EXTCALL(glGetInternalformativ(target, format->glInternal, + GL_EXTCALL(glGetInternalformativ(target, format->internal, GL_NUM_SAMPLE_COUNTS, 1, &count)); - count = min(count, MAX_MULTISAMPLE_TYPES); - GL_EXTCALL(glGetInternalformativ(target, format->glInternal, + if (count > ARRAY_SIZE(multisample_types)) + FIXME("Unexpectedly high number of multisample types %d.\n", count); + count = min(count, ARRAY_SIZE(multisample_types)); + GL_EXTCALL(glGetInternalformativ(target, format->internal, GL_SAMPLES, count, multisample_types)); checkGLcall("query sample counts"); for (i = 0; i < count; ++i) { - if (multisample_types[i] > sizeof(format->multisample_types) * CHAR_BIT) + if (multisample_types[i] > sizeof(format->f.multisample_types) * CHAR_BIT) continue; - format->multisample_types |= 1u << (multisample_types[i] - 1); + format->f.multisample_types |= 1u << (multisample_types[i] - 1); } } else { -#ifdef __REACTOS__ - if (gl_info->limits.samples) { -#endif - max_log2 = wined3d_log2i(min(gl_info->limits.samples, - sizeof(format->multisample_types) * CHAR_BIT)); - for (i = 1; i <= max_log2; ++i) - format->multisample_types |= 1u << ((1u << i) - 1); -#ifdef __REACTOS__ - } -#endif + max_log2 = wined3d_log2i(min(gl_info->limits.samples, + sizeof(format->f.multisample_types) * CHAR_BIT)); + for (i = 1; i <= max_log2; ++i) + format->f.multisample_types |= 1u << ((1u << i) - 1); } } } static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) { - struct wined3d_format *format, *srgb_format; + struct wined3d_format_gl *format, *srgb_format; struct fragment_caps fragment_caps; struct shader_caps shader_caps; unsigned int i, j; BOOL srgb_write; - adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); - adapter->shader_backend->shader_get_caps(gl_info, &shader_caps); + adapter->fragment_pipe->get_caps(adapter, &fragment_caps); + adapter->shader_backend->shader_get_caps(adapter, &shader_caps); srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE) && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE); for (i = 0; i < ARRAY_SIZE(format_texture_info); ++i) { - if (!(format = get_format_internal(gl_info, format_texture_info[i].id))) + if (!(format = get_format_gl_internal(adapter, format_texture_info[i].id))) return FALSE; if (!gl_info->supported[format_texture_info[i].extension]) @@ -2944,62 +3179,65 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win /* ARB_texture_rg defines floating point formats, but only if * ARB_texture_float is also supported. */ if (!gl_info->supported[ARB_TEXTURE_FLOAT] - && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)) + && (format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)) continue; /* ARB_texture_rg defines integer formats if EXT_texture_integer is also supported. */ if (!gl_info->supported[EXT_TEXTURE_INTEGER] - && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_INTEGER)) + && (format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_INTEGER)) continue; - format->glInternal = format_texture_info[i].gl_internal; - format->glGammaInternal = format_texture_info[i].gl_srgb_internal; - format->rtInternal = format_texture_info[i].gl_rt_internal; - format->glFormat = format_texture_info[i].gl_format; - format->glType = format_texture_info[i].gl_type; - format->color_fixup = COLOR_FIXUP_IDENTITY; - format->height_scale.numerator = 1; - format->height_scale.denominator = 1; + format->internal = format_texture_info[i].gl_internal; + format->srgb_internal = format_texture_info[i].gl_srgb_internal; + format->rt_internal = format_texture_info[i].gl_rt_internal; + format->format = format_texture_info[i].gl_format; + format->type = format_texture_info[i].gl_type; + format->f.color_fixup = COLOR_FIXUP_IDENTITY; + format->f.height_scale.numerator = 1; + format->f.height_scale.denominator = 1; - format->flags[WINED3D_GL_RES_TYPE_TEX_1D] |= format_texture_info[i].flags; - format->flags[WINED3D_GL_RES_TYPE_TEX_2D] |= format_texture_info[i].flags; - format->flags[WINED3D_GL_RES_TYPE_BUFFER] |= format_texture_info[i].flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_1D] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; + format->f.flags[WINED3D_GL_RES_TYPE_BUFFER] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; /* GL_ARB_depth_texture does not support 3D textures. It also says "cube textures are * problematic", but doesn't explicitly mandate that an error is generated. */ if (gl_info->supported[EXT_TEXTURE3D] && !(format_texture_info[i].flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) - format->flags[WINED3D_GL_RES_TYPE_TEX_3D] |= format_texture_info[i].flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - format->flags[WINED3D_GL_RES_TYPE_TEX_CUBE] |= format_texture_info[i].flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_CUBE] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - format->flags[WINED3D_GL_RES_TYPE_TEX_RECT] |= format_texture_info[i].flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_RECT] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; - format->flags[WINED3D_GL_RES_TYPE_RB] |= format_texture_info[i].flags; - format->flags[WINED3D_GL_RES_TYPE_RB] &= ~WINED3DFMT_FLAG_TEXTURE; + format->f.flags[WINED3D_GL_RES_TYPE_RB] |= format_texture_info[i].flags | WINED3DFMT_FLAG_BLIT; + format->f.flags[WINED3D_GL_RES_TYPE_RB] &= ~WINED3DFMT_FLAG_TEXTURE; - if (format->glGammaInternal != format->glInternal + if (format->srgb_internal != format->internal && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) { - format->glGammaInternal = format->glInternal; - format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); + format->srgb_internal = format->internal; + format_clear_flag(&format->f, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); } + if (!gl_info->supported[ARB_SHADOW] && (format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW)) + format_clear_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); + query_internal_format(adapter, format, &format_texture_info[i], gl_info, srgb_write, FALSE); /* Texture conversion stuff */ - format->conv_byte_count = format_texture_info[i].conv_byte_count; - format->upload = format_texture_info[i].upload; - format->download = format_texture_info[i].download; + format->f.conv_byte_count = format_texture_info[i].conv_byte_count; + format->f.upload = format_texture_info[i].upload; + format->f.download = format_texture_info[i].download; srgb_format = NULL; for (j = 0; j < ARRAY_SIZE(format_srgb_info); ++j) { - if (format_srgb_info[j].base_format_id == format->id) + if (format_srgb_info[j].base_format_id == format->f.id) { - if (!(srgb_format = get_format_internal(gl_info, format_srgb_info[j].srgb_format_id))) + if (!(srgb_format = get_format_gl_internal(adapter, format_srgb_info[j].srgb_format_id))) return FALSE; break; } @@ -3007,14 +3245,14 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win if (!srgb_format) continue; - copy_format(srgb_format, format); + copy_format(adapter, &srgb_format->f, &format->f); if (gl_info->supported[EXT_TEXTURE_SRGB] && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) { - srgb_format->glInternal = format_texture_info[i].gl_srgb_internal; - srgb_format->glGammaInternal = format_texture_info[i].gl_srgb_internal; - format_set_flag(srgb_format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); + srgb_format->internal = format_texture_info[i].gl_srgb_internal; + srgb_format->srgb_internal = format_texture_info[i].gl_srgb_internal; + format_set_flag(&srgb_format->f, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); query_internal_format(adapter, srgb_format, &format_texture_info[i], gl_info, srgb_write, TRUE); } } @@ -3134,10 +3372,12 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) return ret; } -static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) +static void init_format_filter_info(struct wined3d_adapter *adapter, + struct wined3d_gl_info *gl_info) { - struct wined3d_format *format; - unsigned int fmt_idx, i; + enum wined3d_pci_vendor vendor = adapter->driver_info.vendor; + struct wined3d_format_gl *format; + unsigned int i; static const enum wined3d_format_id fmts16[] = { WINED3DFMT_R16_FLOAT, @@ -3146,8 +3386,8 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3 }; BOOL filtered; + /* This was already handled by init_format_texture_info(). */ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) - /* This was already handled by init_format_texture_info(). */ return; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO @@ -3174,8 +3414,8 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3 { for (i = 0; i < ARRAY_SIZE(fmts16); ++i) { - fmt_idx = get_format_idx(fmts16[i]); - format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING); + format = get_format_gl_internal(adapter, fmts16[i]); + format_set_flag(&format->f, WINED3DFMT_FLAG_FILTERING); } } return; @@ -3183,211 +3423,224 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3 for (i = 0; i < ARRAY_SIZE(fmts16); ++i) { - fmt_idx = get_format_idx(fmts16[i]); - format = &gl_info->formats[fmt_idx]; - if (!format->glInternal) continue; /* Not supported by GL */ + format = get_format_gl_internal(adapter, fmts16[i]); + if (!format->internal) + continue; /* Not supported by GL */ - filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal); + filtered = check_filter(gl_info, format->internal); if (filtered) { - TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i])); - format_set_flag(format, WINED3DFMT_FLAG_FILTERING); + TRACE("Format %s supports filtering.\n", debug_d3dformat(format->f.id)); + format_set_flag(&format->f, WINED3DFMT_FLAG_FILTERING); } else { - TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i])); + TRACE("Format %s does not support filtering.\n", debug_d3dformat(format->f.id)); } } } -static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) +static enum fixup_channel_source fixup_source_from_char(char c) { - unsigned int i; - int idx; - - idx = get_format_idx(WINED3DFMT_R16_FLOAT); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); - - idx = get_format_idx(WINED3DFMT_R32_FLOAT); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); - - idx = get_format_idx(WINED3DFMT_R16G16_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); - - idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); - - idx = get_format_idx(WINED3DFMT_R32G32_FLOAT); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W); - - /* GL_ATI_envmap_bumpmap in theory supports R8G8_SNORM but is no longer supported by - * any driver. */ - if (gl_info->supported[NV_TEXTURE_SHADER] || gl_info->supported[EXT_TEXTURE_SNORM]) - { - /* R8G8_SNORM and R16G16_SNORM need a fixup of the undefined blue channel. OpenGL - * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader - * conversion for this format. */ - idx = get_format_idx(WINED3DFMT_R8G8_SNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); - idx = get_format_idx(WINED3DFMT_R16G16_SNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); - } - else + switch (c) { - /* Emulate using unsigned formats. This requires load-time conversion in addition to the - * fixups here. */ - idx = get_format_idx(WINED3DFMT_R8G8_SNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); - idx = get_format_idx(WINED3DFMT_R16G16_SNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); - idx = get_format_idx(WINED3DFMT_R8G8B8A8_SNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W); - idx = get_format_idx(WINED3DFMT_R5G5_SNORM_L6_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE); + default: + case '0': + return CHANNEL_SOURCE_ZERO; + case '1': + return CHANNEL_SOURCE_ONE; + case 'x': + case 'X': + return CHANNEL_SOURCE_X; + case 'y': + case 'Y': + return CHANNEL_SOURCE_Y; + case 'z': + case 'Z': + return CHANNEL_SOURCE_Z; + case 'w': + case 'W': + return CHANNEL_SOURCE_W; } +} + +static unsigned int fixup_sign_from_char(char c) +{ + if (c == 'x' || c == 'y' || c == 'z' || c == 'w') + return 1; + return 0; +} + +static struct color_fixup_desc create_color_fixup_desc_from_string(const char *s) +{ + struct color_fixup_desc fixup; - if (!gl_info->supported[NV_TEXTURE_SHADER]) + if (strlen(s) != 4) { - idx = get_format_idx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W); + ERR("Invalid fixup string %s.\n", wine_dbgstr_a(s)); + return COLOR_FIXUP_IDENTITY; } - if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC]) - { - idx = get_format_idx(WINED3DFMT_ATI1N); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X); + fixup.x_sign_fixup = fixup_sign_from_char(s[0]); + fixup.x_source = fixup_source_from_char(s[0]); + fixup.y_sign_fixup = fixup_sign_from_char(s[1]); + fixup.y_source = fixup_source_from_char(s[1]); + fixup.z_sign_fixup = fixup_sign_from_char(s[2]); + fixup.z_source = fixup_source_from_char(s[2]); + fixup.w_sign_fixup = fixup_sign_from_char(s[3]); + fixup.w_source = fixup_source_from_char(s[3]); - idx = get_format_idx(WINED3DFMT_ATI2N); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); - } - else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]) + return fixup; +} + +static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) +{ + const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; + struct wined3d_format_gl *format; + BOOL use_legacy_fixups; + unsigned int i; + + static const struct { - idx = get_format_idx(WINED3DFMT_ATI2N); - gl_info->formats[idx].color_fixup= create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); + enum wined3d_format_id id; + const char *fixup; + BOOL legacy; + enum wined3d_gl_extension extension; } - - if (!gl_info->supported[APPLE_YCBCR_422] && gl_info->supported[ARB_FRAGMENT_PROGRAM] - && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + fixups[] = { - idx = get_format_idx(WINED3DFMT_YUY2); - gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2); + {WINED3DFMT_R16_FLOAT, "X11W", TRUE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R32_FLOAT, "X11W", TRUE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R16G16_UNORM, "XY1W", TRUE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R16G16_FLOAT, "XY1W", TRUE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R32G32_FLOAT, "XY1W", TRUE, WINED3D_GL_EXT_NONE}, - idx = get_format_idx(WINED3DFMT_UYVY); - gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); - } - else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM] - || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])) + {WINED3DFMT_R8G8_SNORM, "xy11", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R8G8_SNORM, "XY11", TRUE, NV_TEXTURE_SHADER}, + {WINED3DFMT_R8G8_SNORM, "XY11", TRUE, EXT_TEXTURE_SNORM}, + + {WINED3DFMT_R16G16_SNORM, "xy11", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R16G16_SNORM, "XY11", TRUE, NV_TEXTURE_SHADER}, + {WINED3DFMT_R16G16_SNORM, "XY11", TRUE, EXT_TEXTURE_SNORM}, + + {WINED3DFMT_R8G8B8A8_SNORM, "xyzw", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R8G8B8A8_SNORM, "XYZW", FALSE, NV_TEXTURE_SHADER}, + {WINED3DFMT_R8G8B8A8_SNORM, "XYZW", FALSE, EXT_TEXTURE_SNORM}, + + {WINED3DFMT_R5G5_SNORM_L6_UNORM, "xzY1", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R5G5_SNORM_L6_UNORM, "XYZW", FALSE, NV_TEXTURE_SHADER}, + {WINED3DFMT_R5G5_SNORM_L6_UNORM, "XYZW", FALSE, EXT_TEXTURE_SNORM}, + + {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, "xyZW", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, "XYZW", FALSE, NV_TEXTURE_SHADER}, + + {WINED3DFMT_ATI1N, "XXXX", FALSE, EXT_TEXTURE_COMPRESSION_RGTC}, + {WINED3DFMT_ATI1N, "XXXX", FALSE, ARB_TEXTURE_COMPRESSION_RGTC}, + + {WINED3DFMT_ATI2N, "XW11", FALSE, ATI_TEXTURE_COMPRESSION_3DC}, + {WINED3DFMT_ATI2N, "YX11", FALSE, EXT_TEXTURE_COMPRESSION_RGTC}, + {WINED3DFMT_ATI2N, "YX11", FALSE, ARB_TEXTURE_COMPRESSION_RGTC}, + + {WINED3DFMT_A8_UNORM, "000X", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_A8_UNORM, "XYZW", FALSE, WINED3D_GL_LEGACY_CONTEXT}, + + {WINED3DFMT_L8A8_UNORM, "XXXY", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_L8A8_UNORM, "XYZW", FALSE, WINED3D_GL_LEGACY_CONTEXT}, + + {WINED3DFMT_L4A4_UNORM, "XXXY", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_L4A4_UNORM, "XYZW", FALSE, WINED3D_GL_LEGACY_CONTEXT}, + + {WINED3DFMT_L16_UNORM, "XXX1", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_L16_UNORM, "XYZW", FALSE, WINED3D_GL_LEGACY_CONTEXT}, + + {WINED3DFMT_INTZ, "XXXX", FALSE, WINED3D_GL_EXT_NONE}, + {WINED3DFMT_INTZ, "XYZW", FALSE, WINED3D_GL_LEGACY_CONTEXT}, + + {WINED3DFMT_L8_UNORM, "XXX1", FALSE, ARB_TEXTURE_RG}, + }; + + use_legacy_fixups = d3d_info->wined3d_creation_flags & WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR; + for (i = 0; i < ARRAY_SIZE(fixups); ++i) { - idx = get_format_idx(WINED3DFMT_YUY2); - gl_info->formats[idx].glInternal = 0; + if (fixups[i].legacy && !use_legacy_fixups) + continue; + + if (!gl_info->supported[fixups[i].extension]) + continue; - idx = get_format_idx(WINED3DFMT_UYVY); - gl_info->formats[idx].glInternal = 0; + format = get_format_gl_internal(adapter, fixups[i].id); + format->f.color_fixup = create_color_fixup_desc_from_string(fixups[i].fixup); } - if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + if (!gl_info->supported[APPLE_YCBCR_422] && (gl_info->supported[ARB_FRAGMENT_PROGRAM] + || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))) { - idx = get_format_idx(WINED3DFMT_YV12); - format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE); - gl_info->formats[idx].height_scale.numerator = 3; - gl_info->formats[idx].height_scale.denominator = 2; - gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12); + format = get_format_gl_internal(adapter, WINED3DFMT_YUY2); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2); - idx = get_format_idx(WINED3DFMT_NV12); - format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE); - gl_info->formats[idx].height_scale.numerator = 3; - gl_info->formats[idx].height_scale.denominator = 2; - gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12); + format = get_format_gl_internal(adapter, WINED3DFMT_UYVY); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); } - else + else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM] + && (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER]))) { - idx = get_format_idx(WINED3DFMT_YV12); - gl_info->formats[idx].glInternal = 0; + format = get_format_gl_internal(adapter, WINED3DFMT_YUY2); + format_clear_flag(&format->f, WINED3DFMT_FLAG_BLIT); + format->internal = 0; - idx = get_format_idx(WINED3DFMT_NV12); - gl_info->formats[idx].glInternal = 0; + format = get_format_gl_internal(adapter, WINED3DFMT_UYVY); + format_clear_flag(&format->f, WINED3DFMT_FLAG_BLIT); + format->internal = 0; } - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + if (gl_info->supported[ARB_FRAGMENT_PROGRAM] + || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER])) { - idx = get_format_idx(WINED3DFMT_A8_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_X); - idx = get_format_idx(WINED3DFMT_L8A8_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y); - idx = get_format_idx(WINED3DFMT_L4A4_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y); - idx = get_format_idx(WINED3DFMT_L16_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); - idx = get_format_idx(WINED3DFMT_INTZ); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X); - } + format = get_format_gl_internal(adapter, WINED3DFMT_YV12); + format_set_flag(&format->f, WINED3DFMT_FLAG_HEIGHT_SCALE); + format->f.height_scale.numerator = 3; + format->f.height_scale.denominator = 2; + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12); - if (gl_info->supported[ARB_TEXTURE_RG]) - { - idx = get_format_idx(WINED3DFMT_L8_UNORM); - gl_info->formats[idx].color_fixup = create_color_fixup_desc( - 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); + format = get_format_gl_internal(adapter, WINED3DFMT_NV12); + format_set_flag(&format->f, WINED3DFMT_FLAG_HEIGHT_SCALE); + format->f.height_scale.numerator = 3; + format->f.height_scale.denominator = 2; + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12); } - - if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) + else { - idx = get_format_idx(WINED3DFMT_P8_UINT); - gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); - } + format = get_format_gl_internal(adapter, WINED3DFMT_YV12); + format_clear_flag(&format->f, WINED3DFMT_FLAG_BLIT); + format->internal = 0; - if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) - { - idx = get_format_idx(WINED3DFMT_B8G8R8A8_UNORM); - gl_info->formats[idx].gl_vtx_format = GL_BGRA; + format = get_format_gl_internal(adapter, WINED3DFMT_NV12); + format_clear_flag(&format->f, WINED3DFMT_FLAG_BLIT); + format->internal = 0; } - if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) + if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER]) { - /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though. - * It is the job of the vertex buffer code to make sure that the vbos have the right format */ - idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); - gl_info->formats[idx].gl_vtx_type = GL_FLOAT; - - idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT); - gl_info->formats[idx].gl_vtx_type = GL_FLOAT; + format = get_format_gl_internal(adapter, WINED3DFMT_P8_UINT); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); } if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) { - idx = get_format_idx(WINED3DFMT_R16_FLOAT); - format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format = get_format_gl_internal(adapter, WINED3DFMT_R16_FLOAT); + format_clear_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); - idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); - format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format = get_format_gl_internal(adapter, WINED3DFMT_R16G16_FLOAT); + format_clear_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); - idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT); - format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format = get_format_gl_internal(adapter, WINED3DFMT_R16G16B16A16_FLOAT); + format_clear_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); } if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16) { - idx = get_format_idx(WINED3DFMT_R16G16B16A16_UNORM); - format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format = get_format_gl_internal(adapter, WINED3DFMT_R16G16B16A16_UNORM); + format_clear_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); } /* ATI instancing hack: Although ATI cards do not support Shader Model @@ -3405,8 +3658,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ /* FIXME: This should just check the shader backend caps. */ if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER]) { - idx = get_format_idx(WINED3DFMT_INST); - format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format = get_format_gl_internal(adapter, WINED3DFMT_INST); + format_set_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); } /* Depth bound test. To query if the card supports it CheckDeviceFormat() @@ -3417,8 +3670,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ * value. */ if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST]) { - idx = get_format_idx(WINED3DFMT_NVDB); - format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format = get_format_gl_internal(adapter, WINED3DFMT_NVDB); + format_set_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); } /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ @@ -3426,27 +3679,27 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ * RENDERTARGET usage. */ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) { - idx = get_format_idx(WINED3DFMT_RESZ); - format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET); + format = get_format_gl_internal(adapter, WINED3DFMT_RESZ); + format_set_flag(&format->f, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET); } - for (i = 0; i < gl_info->format_count; ++i) + for (i = 0; i < WINED3D_FORMAT_COUNT; ++i) { - struct wined3d_format *format = &gl_info->formats[i]; + format = get_format_gl_by_idx(adapter, i); - if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)) + if (!(format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)) continue; - if (is_identity_fixup(format->color_fixup)) + if (is_identity_fixup(format->f.color_fixup)) continue; TRACE("Checking support for fixup:\n"); - dump_color_fixup_desc(format->color_fixup); - if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup) - || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup)) + dump_color_fixup_desc(format->f.color_fixup); + if (!adapter->shader_backend->shader_color_fixup_supported(format->f.color_fixup) + || !adapter->fragment_pipe->color_fixup_supported(format->f.color_fixup)) { TRACE("[FAILED]\n"); - format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE); + format_clear_flag(&format->f, WINED3DFMT_FLAG_TEXTURE); } else { @@ -3454,107 +3707,52 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ } } - /* GL_EXT_texture_compression_s3tc does not support 3D textures. Some Windows drivers - * for dx9 GPUs support it, some do not, so not supporting DXTn volumes is OK for d3d9. - * - * Note that GL_NV_texture_compression_vtc adds this functionality to OpenGL, but the - * block layout is not compatible with the one used by d3d. See volume_dxt5_test. */ - idx = get_format_idx(WINED3DFMT_DXT1); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_DXT2); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_DXT3); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_DXT4); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_DXT5); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC1_UNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC1_UNORM_SRGB); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC2_UNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC2_UNORM_SRGB); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC3_UNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC3_UNORM_SRGB); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - /* Similarly with ATI1N / ATI2N and GL_ARB_texture_compression_rgtc. */ - idx = get_format_idx(WINED3DFMT_ATI1N); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_ATI2N); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC4_UNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC4_SNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC5_UNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; - idx = get_format_idx(WINED3DFMT_BC5_SNORM); - gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; -} - -static unsigned int calculate_vertex_attribute_size(GLenum type, unsigned int component_count) -{ - switch (type) - { - case GL_HALF_FLOAT: - return component_count * sizeof(GLhalfNV); - case GL_FLOAT: - return component_count * sizeof(GLfloat); - case GL_BYTE: - return component_count * sizeof(GLbyte); - case GL_UNSIGNED_BYTE: - return component_count * sizeof(GLubyte); - case GL_SHORT: - return component_count * sizeof(GLshort); - case GL_UNSIGNED_SHORT: - return component_count * sizeof(GLushort); - case GL_INT: - return component_count * sizeof(GLint); - case GL_UNSIGNED_INT: - return component_count * sizeof(GLuint); - case GL_UNSIGNED_INT_2_10_10_10_REV: - return sizeof(GLuint); - default: - FIXME("Unhandled GL type %#x.\n", type); - return 0; - } + /* These formats are not supported for 3D textures. See also + * WINED3DFMT_FLAG_DECOMPRESS. */ + format = get_format_gl_internal(adapter, WINED3DFMT_ATI1N); + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + format = get_format_gl_internal(adapter, WINED3DFMT_ATI2N); + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + format = get_format_gl_internal(adapter, WINED3DFMT_BC4_UNORM); + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + format = get_format_gl_internal(adapter, WINED3DFMT_BC4_SNORM); + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + format = get_format_gl_internal(adapter, WINED3DFMT_BC5_UNORM); + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + format = get_format_gl_internal(adapter, WINED3DFMT_BC5_SNORM); + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; } -static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info) +static BOOL init_format_vertex_info(const struct wined3d_adapter *adapter, + struct wined3d_gl_info *gl_info) { - struct wined3d_format *format; + struct wined3d_format_gl *format; unsigned int i; for (i = 0; i < ARRAY_SIZE(format_vertex_info); ++i) { - if (!(format = get_format_internal(gl_info, format_vertex_info[i].id))) + if (!(format = get_format_gl_internal(adapter, format_vertex_info[i].id))) return FALSE; if (!gl_info->supported[format_vertex_info[i].extension]) continue; - format->emit_idx = format_vertex_info[i].emit_idx; - format->component_count = format_vertex_info[i].component_count; - format->gl_vtx_type = format_vertex_info[i].gl_vtx_type; - format->gl_vtx_format = format_vertex_info[i].component_count; - format->gl_normalized = format_vertex_info[i].gl_normalized; - if (!(format->attribute_size = calculate_vertex_attribute_size(format->gl_vtx_type, - format->component_count))) - { - ERR("Invalid attribute size for vertex format %s (%#x).\n", - debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id); - return FALSE; - } + format->f.emit_idx = format_vertex_info[i].emit_idx; + format->vtx_type = format_vertex_info[i].gl_vtx_type; + format->vtx_format = format->f.component_count; + format->f.flags[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3DFMT_FLAG_VERTEX_ATTRIBUTE; + } + + if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + { + format = get_format_gl_internal(adapter, WINED3DFMT_B8G8R8A8_UNORM); + format->vtx_format = GL_BGRA; } return TRUE; } -static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) +static BOOL init_typeless_formats(const struct wined3d_adapter *adapter) { unsigned int flags[WINED3D_GL_RES_TYPE_COUNT]; unsigned int i, j; @@ -3563,13 +3761,13 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) { struct wined3d_format *format, *typeless_format; - if (!(format = get_format_internal(gl_info, typed_formats[i].id))) + if (!(format = get_format_internal(adapter, typed_formats[i].id))) return FALSE; - if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id))) + if (!(typeless_format = get_format_internal(adapter, typed_formats[i].typeless_id))) return FALSE; memcpy(flags, typeless_format->flags, sizeof(flags)); - copy_format(typeless_format, format); + copy_format(adapter, typeless_format, format); for (j = 0; j < ARRAY_SIZE(typeless_format->flags); ++j) typeless_format->flags[j] |= flags[j]; } @@ -3580,14 +3778,14 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) struct wined3d_format *depth_view_format, *stencil_view_format; enum wined3d_format_id format_id; - if (!(typeless_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].typeless_id))) + if (!(typeless_format = get_format_internal(adapter, typeless_depth_stencil_formats[i].typeless_id))) return FALSE; - if (!(ds_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].depth_stencil_id))) + if (!(ds_format = get_format_internal(adapter, typeless_depth_stencil_formats[i].depth_stencil_id))) return FALSE; - typeless_ds_format = &gl_info->formats[WINED3D_FORMAT_COUNT + i]; + typeless_ds_format = get_format_by_idx(adapter, WINED3D_FORMAT_COUNT + i); typeless_ds_format->id = typeless_depth_stencil_formats[i].typeless_id; - copy_format(typeless_ds_format, ds_format); + copy_format(adapter, typeless_ds_format, ds_format); for (j = 0; j < ARRAY_SIZE(typeless_ds_format->flags); ++j) { typeless_ds_format->flags[j] = typeless_format->flags[j]; @@ -3597,31 +3795,32 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) if ((format_id = typeless_depth_stencil_formats[i].depth_view_id) && typeless_depth_stencil_formats[i].separate_depth_view_format) { - if (!(depth_view_format = get_format_internal(gl_info, format_id))) + if (!(depth_view_format = get_format_internal(adapter, format_id))) return FALSE; - copy_format(depth_view_format, ds_format); + copy_format(adapter, depth_view_format, ds_format); } if ((format_id = typeless_depth_stencil_formats[i].stencil_view_id)) { - if (!(stencil_view_format = get_format_internal(gl_info, format_id))) + if (!(stencil_view_format = get_format_internal(adapter, format_id))) return FALSE; - copy_format(stencil_view_format, ds_format); + copy_format(adapter, stencil_view_format, ds_format); } } return TRUE; } -static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info) +static void init_format_gen_mipmap_info(const struct wined3d_adapter *adapter, + struct wined3d_gl_info *gl_info) { unsigned int i, j; if (!gl_info->fbo_ops.glGenerateMipmap) return; - for (i = 0; i < gl_info->format_count; ++i) + for (i = 0; i < WINED3D_FORMAT_COUNT; ++i) { - struct wined3d_format *format = &gl_info->formats[i]; + struct wined3d_format *format = get_format_by_idx(adapter, i); for (j = 0; j < ARRAY_SIZE(format->flags); ++j) if (!(~format->flags[j] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))) @@ -3770,66 +3969,307 @@ static float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *c return (float)(1u << cur); } -static void init_format_depth_bias_scale(struct wined3d_caps_gl_ctx *ctx, - const struct wined3d_d3d_info *d3d_info) +static void init_format_depth_bias_scale(struct wined3d_adapter *adapter, + struct wined3d_caps_gl_ctx *ctx) { - const struct wined3d_gl_info *gl_info = ctx->gl_info; + const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; unsigned int i; - for (i = 0; i < gl_info->format_count; ++i) + for (i = 0; i < WINED3D_FORMAT_COUNT; ++i) { - struct wined3d_format *format = &gl_info->formats[i]; + struct wined3d_format_gl *format = get_format_gl_by_idx(adapter, i); - if (format->flags[WINED3D_GL_RES_TYPE_RB] & WINED3DFMT_FLAG_DEPTH) + if (format->f.flags[WINED3D_GL_RES_TYPE_RB] & WINED3DFMT_FLAG_DEPTH) { - TRACE("Testing depth bias scale for format %s.\n", debug_d3dformat(format->id)); - format->depth_bias_scale = wined3d_adapter_find_polyoffset_scale(ctx, format->glInternal); + TRACE("Testing depth bias scale for format %s.\n", debug_d3dformat(format->f.id)); + format->f.depth_bias_scale = wined3d_adapter_find_polyoffset_scale(ctx, format->internal); if (!(d3d_info->wined3d_creation_flags & WINED3D_NORMALIZED_DEPTH_BIAS)) { /* The single-precision binary floating-point format has * a significand precision of 24 bits. */ - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) - format->depth_bias_scale /= 1u << 24; + if (format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) + format->f.depth_bias_scale /= 1u << 24; else - format->depth_bias_scale /= 1u << format->depth_size; + format->f.depth_bias_scale /= 1u << format->f.depth_size; } } } } +static BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, size_t format_size) +{ + unsigned int count = WINED3D_FORMAT_COUNT + ARRAY_SIZE(typeless_depth_stencil_formats); + + if (!(adapter->formats = heap_calloc(count, format_size))) + { + ERR("Failed to allocate memory.\n"); + return FALSE; + } + adapter->format_size = format_size; + + if (!init_format_base_info(adapter)) + goto fail; + if (!init_format_block_info(adapter)) + goto fail; + if (!init_format_decompress_info(adapter)) + goto fail; + if (!init_srgb_formats(adapter)) + goto fail; + + return TRUE; + +fail: + heap_free(adapter->formats); + adapter->formats = NULL; + return FALSE; +} + +BOOL wined3d_adapter_no3d_init_format_info(struct wined3d_adapter *adapter) +{ + struct wined3d_format *format; + unsigned int i; + + static const enum wined3d_format_id blit_formats[] = + { + WINED3DFMT_B8G8R8A8_UNORM, + WINED3DFMT_B8G8R8X8_UNORM, + WINED3DFMT_B5G6R5_UNORM, + WINED3DFMT_B5G5R5X1_UNORM, + WINED3DFMT_B5G5R5A1_UNORM, + WINED3DFMT_B4G4R4A4_UNORM, + WINED3DFMT_B2G3R3_UNORM, + WINED3DFMT_A8_UNORM, + WINED3DFMT_B2G3R3A8_UNORM, + WINED3DFMT_B4G4R4X4_UNORM, + WINED3DFMT_R10G10B10A2_UNORM, + WINED3DFMT_R8G8B8A8_UNORM, + WINED3DFMT_R8G8B8X8_UNORM, + WINED3DFMT_R16G16_UNORM, + WINED3DFMT_B10G10R10A2_UNORM, + WINED3DFMT_R16G16B16A16_UNORM, + WINED3DFMT_P8_UINT, + }; + + if (!wined3d_adapter_init_format_info(adapter, sizeof(struct wined3d_format))) + return FALSE; + + for (i = 0; i < ARRAY_SIZE(blit_formats); ++i) + { + if (!(format = get_format_internal(adapter, blit_formats[i]))) + return FALSE; + + format->flags[WINED3D_GL_RES_TYPE_TEX_2D] |= WINED3DFMT_FLAG_BLIT; + format->flags[WINED3D_GL_RES_TYPE_RB] |= WINED3DFMT_FLAG_BLIT; + } + + return TRUE; +} + /* Context activation is done by the caller. */ -BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) +BOOL wined3d_adapter_gl_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) { struct wined3d_gl_info *gl_info = &adapter->gl_info; - if (!init_format_base_info(gl_info)) return FALSE; - if (!init_format_block_info(gl_info)) goto fail; - - if (!ctx) /* WINED3D_NO3D */ - return TRUE; + if (!wined3d_adapter_init_format_info(adapter, sizeof(struct wined3d_format_gl))) + return FALSE; if (!init_format_texture_info(adapter, gl_info)) goto fail; - if (!init_format_vertex_info(gl_info)) goto fail; + if (!init_format_vertex_info(adapter, gl_info)) goto fail; apply_format_fixups(adapter, gl_info); - init_format_fbo_compat_info(ctx); - init_format_filter_info(gl_info, adapter->driver_info.vendor); - if (!init_typeless_formats(gl_info)) goto fail; - init_format_gen_mipmap_info(gl_info); - init_format_depth_bias_scale(ctx, &adapter->d3d_info); + init_format_fbo_compat_info(adapter, ctx); + init_format_filter_info(adapter, gl_info); + init_format_gen_mipmap_info(adapter, gl_info); + init_format_depth_bias_scale(adapter, ctx); + + if (!init_typeless_formats(adapter)) goto fail; + + return TRUE; + +fail: + heap_free(adapter->formats); + adapter->formats = NULL; + return FALSE; +} + +static void init_vulkan_format_info(struct wined3d_format_vk *format, + const struct wined3d_vk_info *vk_info, VkPhysicalDevice vk_physical_device) +{ + static const struct + { + enum wined3d_format_id id; + VkFormat vk_format; + } + vulkan_formats[] = + { + {WINED3DFMT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, }, + {WINED3DFMT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT, }, + {WINED3DFMT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT, }, + {WINED3DFMT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT, }, + {WINED3DFMT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT, }, + {WINED3DFMT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT, }, + {WINED3DFMT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT, }, + {WINED3DFMT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM, }, + {WINED3DFMT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT, }, + {WINED3DFMT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM, }, + {WINED3DFMT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT, }, + {WINED3DFMT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT, }, + {WINED3DFMT_R32G32_UINT, VK_FORMAT_R32G32_UINT, }, + {WINED3DFMT_R32G32_SINT, VK_FORMAT_R32G32_SINT, }, + {WINED3DFMT_R10G10B10A2_UNORM, VK_FORMAT_A2B10G10R10_UNORM_PACK32,}, + {WINED3DFMT_R11G11B10_FLOAT, VK_FORMAT_B10G11R11_UFLOAT_PACK32, }, + {WINED3DFMT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM, }, + {WINED3DFMT_R8G8_UINT, VK_FORMAT_R8G8_UINT, }, + {WINED3DFMT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM, }, + {WINED3DFMT_R8G8_SINT, VK_FORMAT_R8G8_SINT, }, + {WINED3DFMT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, }, + {WINED3DFMT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB, }, + {WINED3DFMT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT, }, + {WINED3DFMT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM, }, + {WINED3DFMT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT, }, + {WINED3DFMT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT, }, + {WINED3DFMT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM, }, + {WINED3DFMT_R16G16_UINT, VK_FORMAT_R16G16_UINT, }, + {WINED3DFMT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM, }, + {WINED3DFMT_R16G16_SINT, VK_FORMAT_R16G16_SINT, }, + {WINED3DFMT_D32_FLOAT, VK_FORMAT_D32_SFLOAT, }, + {WINED3DFMT_R32_FLOAT, VK_FORMAT_R32_SFLOAT, }, + {WINED3DFMT_R32_UINT, VK_FORMAT_R32_UINT, }, + {WINED3DFMT_R32_SINT, VK_FORMAT_R32_SINT, }, + {WINED3DFMT_R16_FLOAT, VK_FORMAT_R16_SFLOAT, }, + {WINED3DFMT_D16_UNORM, VK_FORMAT_D16_UNORM, }, + {WINED3DFMT_R16_UNORM, VK_FORMAT_R16_UNORM, }, + {WINED3DFMT_R16_UINT, VK_FORMAT_R16_UINT, }, + {WINED3DFMT_R16_SNORM, VK_FORMAT_R16_SNORM, }, + {WINED3DFMT_R16_SINT, VK_FORMAT_R16_SINT, }, + {WINED3DFMT_R8_UNORM, VK_FORMAT_R8_UNORM, }, + {WINED3DFMT_R8_UINT, VK_FORMAT_R8_UINT, }, + {WINED3DFMT_R8_SNORM, VK_FORMAT_R8_SNORM, }, + {WINED3DFMT_R8_SINT, VK_FORMAT_R8_SINT, }, + {WINED3DFMT_A8_UNORM, VK_FORMAT_R8_UNORM, }, + {WINED3DFMT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, }, + {WINED3DFMT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, }, + {WINED3DFMT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, }, + {WINED3DFMT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, }, + {WINED3DFMT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK, }, + {WINED3DFMT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK, }, + {WINED3DFMT_BC3_UNORM, VK_FORMAT_BC3_UNORM_BLOCK, }, + {WINED3DFMT_BC3_UNORM_SRGB, VK_FORMAT_BC3_SRGB_BLOCK, }, + {WINED3DFMT_BC4_UNORM, VK_FORMAT_BC4_UNORM_BLOCK, }, + {WINED3DFMT_BC4_SNORM, VK_FORMAT_BC4_SNORM_BLOCK, }, + {WINED3DFMT_BC5_UNORM, VK_FORMAT_BC5_UNORM_BLOCK, }, + {WINED3DFMT_BC5_SNORM, VK_FORMAT_BC5_SNORM_BLOCK, }, + {WINED3DFMT_BC6H_UF16, VK_FORMAT_BC6H_UFLOAT_BLOCK, }, + {WINED3DFMT_BC6H_SF16, VK_FORMAT_BC6H_SFLOAT_BLOCK, }, + {WINED3DFMT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK, }, + {WINED3DFMT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK, }, + }; + VkFormat vk_format = VK_FORMAT_UNDEFINED; + VkImageFormatProperties image_properties; + VkFormatFeatureFlags texture_flags; + VkFormatProperties properties; + VkImageUsageFlags vk_usage; + unsigned int flags; + unsigned int i; + VkResult vr; + + for (i = 0; i < ARRAY_SIZE(vulkan_formats); ++i) + { + if (vulkan_formats[i].id == format->f.id) + { + vk_format = vulkan_formats[i].vk_format; + break; + } + } + if (!vk_format) + { + WARN("Unsupported format %s.\n", debug_d3dformat(format->f.id)); + return; + } + + format->vk_format = vk_format; + + VK_CALL(vkGetPhysicalDeviceFormatProperties(vk_physical_device, vk_format, &properties)); + + if (properties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) + format->f.flags[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3DFMT_FLAG_VERTEX_ATTRIBUTE; + if (properties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) + format->f.flags[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3DFMT_FLAG_TEXTURE; + + flags = 0; + texture_flags = properties.linearTilingFeatures | properties.optimalTilingFeatures; + if (texture_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) + { + flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_VTF; + } + if (texture_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) + { + flags |= WINED3DFMT_FLAG_RENDERTARGET; + } + if (texture_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) + { + flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; + } + if (texture_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) + { + flags |= WINED3DFMT_FLAG_FILTERING; + } + + format->f.flags[WINED3D_GL_RES_TYPE_TEX_1D] |= flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_2D] |= flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_3D] |= flags; + format->f.flags[WINED3D_GL_RES_TYPE_TEX_CUBE] |= flags; + + vk_usage = 0; + if (texture_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) + vk_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + else if (texture_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + vk_usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + if (vk_usage) + { + if ((vr = VK_CALL(vkGetPhysicalDeviceImageFormatProperties(vk_physical_device, vk_format, + VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, vk_usage, 0, &image_properties))) < 0) + { + ERR("Failed to get image format properties, vr %s.\n", wined3d_debug_vkresult(vr)); + return; + } + format->f.multisample_types = image_properties.sampleCounts; + } +} + +BOOL wined3d_adapter_vk_init_format_info(struct wined3d_adapter_vk *adapter_vk, + const struct wined3d_vk_info *vk_info) +{ + VkPhysicalDevice vk_physical_device = adapter_vk->physical_device; + struct wined3d_adapter *adapter = &adapter_vk->a; + struct wined3d_format_vk *format; + unsigned int i; + + if (!wined3d_adapter_init_format_info(adapter, sizeof(*format))) + return FALSE; + + for (i = 0; i < WINED3D_FORMAT_COUNT; ++i) + { + format = wined3d_format_vk_mutable(get_format_by_idx(adapter, i)); + + if (format->f.id) + init_vulkan_format_info(format, vk_info, vk_physical_device); + } + + if (!init_typeless_formats(adapter)) goto fail; return TRUE; fail: - heap_free(gl_info->formats); - gl_info->formats = NULL; + heap_free(adapter->formats); + adapter->formats = NULL; return FALSE; } -const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, - enum wined3d_format_id format_id, unsigned int resource_usage) +const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *adapter, + enum wined3d_format_id format_id, unsigned int bind_flags) { const struct wined3d_format *format; int idx = get_format_idx(format_id); @@ -3839,22 +4279,22 @@ const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl { FIXME("Can't find format %s (%#x) in the format lookup table.\n", debug_d3dformat(format_id), format_id); - return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)]; + return get_format_internal(adapter, WINED3DFMT_UNKNOWN); } - format = &gl_info->formats[idx]; + format = get_format_by_idx(adapter, idx); - if (resource_usage & WINED3DUSAGE_DEPTHSTENCIL && wined3d_format_is_typeless(format)) + if (bind_flags & WINED3D_BIND_DEPTH_STENCIL && wined3d_format_is_typeless(format)) { for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i) { if (typeless_depth_stencil_formats[i].typeless_id == format_id) - return &gl_info->formats[WINED3D_FORMAT_COUNT + i]; + return get_format_by_idx(adapter, WINED3D_FORMAT_COUNT + i); } FIXME("Cannot find depth/stencil typeless format %s (%#x).\n", debug_d3dformat(format_id), format_id); - return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)]; + return get_format_internal(adapter, WINED3DFMT_UNKNOWN); } return format; @@ -3977,6 +4417,18 @@ const char *debug_vec4(const struct wined3d_vec4 *v) v->x, v->y, v->z, v->w); } +const char *debug_const_bo_address(const struct wined3d_const_bo_address *address) +{ + if (!address) + return "(null)"; + return wine_dbg_sprintf("{%#lx:%p}", address->buffer_object, address->addr); +} + +const char *debug_bo_address(const struct wined3d_bo_address *address) +{ + return debug_const_bo_address((const struct wined3d_const_bo_address *)address); +} + const char *debug_d3dformat(enum wined3d_format_id format_id) { switch (format_id) @@ -3999,21 +4451,10 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM); FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM); + FMT_TO_STR(WINED3DFMT_R10G10B10X2_TYPELESS); FMT_TO_STR(WINED3DFMT_R10G10B10X2_UINT); FMT_TO_STR(WINED3DFMT_R10G10B10X2_SNORM); FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM); - FMT_TO_STR(WINED3DFMT_UYVY); - FMT_TO_STR(WINED3DFMT_YUY2); - FMT_TO_STR(WINED3DFMT_YV12); - FMT_TO_STR(WINED3DFMT_NV12); - FMT_TO_STR(WINED3DFMT_DXT1); - FMT_TO_STR(WINED3DFMT_DXT2); - FMT_TO_STR(WINED3DFMT_DXT3); - FMT_TO_STR(WINED3DFMT_DXT4); - FMT_TO_STR(WINED3DFMT_DXT5); - FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8); - FMT_TO_STR(WINED3DFMT_G8R8_G8B8); - FMT_TO_STR(WINED3DFMT_R8G8_B8G8); FMT_TO_STR(WINED3DFMT_D16_LOCKABLE); FMT_TO_STR(WINED3DFMT_D32_UNORM); FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM); @@ -4022,11 +4463,6 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_L16_UNORM); FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT); FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx); - FMT_TO_STR(WINED3DFMT_ATI1N); - FMT_TO_STR(WINED3DFMT_ATI2N); - FMT_TO_STR(WINED3DFMT_NVDB); - FMT_TO_STR(WINED3DFMT_NVHU); - FMT_TO_STR(WINED3DFMT_NVHS); FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS); FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT); FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT); @@ -4127,11 +4563,29 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_BC7_TYPELESS); FMT_TO_STR(WINED3DFMT_BC7_UNORM); FMT_TO_STR(WINED3DFMT_BC7_UNORM_SRGB); + FMT_TO_STR(WINED3DFMT_UYVY); + FMT_TO_STR(WINED3DFMT_YUY2); + FMT_TO_STR(WINED3DFMT_YV12); + FMT_TO_STR(WINED3DFMT_DXT1); + FMT_TO_STR(WINED3DFMT_DXT2); + FMT_TO_STR(WINED3DFMT_DXT3); + FMT_TO_STR(WINED3DFMT_DXT4); + FMT_TO_STR(WINED3DFMT_DXT5); + FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8); + FMT_TO_STR(WINED3DFMT_G8R8_G8B8); + FMT_TO_STR(WINED3DFMT_R8G8_B8G8); + FMT_TO_STR(WINED3DFMT_ATI1N); + FMT_TO_STR(WINED3DFMT_ATI2N); + FMT_TO_STR(WINED3DFMT_INST); + FMT_TO_STR(WINED3DFMT_NVDB); + FMT_TO_STR(WINED3DFMT_NVHU); + FMT_TO_STR(WINED3DFMT_NVHS); FMT_TO_STR(WINED3DFMT_INTZ); FMT_TO_STR(WINED3DFMT_RESZ); FMT_TO_STR(WINED3DFMT_NULL); FMT_TO_STR(WINED3DFMT_R16); FMT_TO_STR(WINED3DFMT_AL16); + FMT_TO_STR(WINED3DFMT_NV12); #undef FMT_TO_STR default: { @@ -4174,9 +4628,9 @@ struct debug_buffer static void init_debug_buffer(struct debug_buffer *buffer, const char *default_string) { - strcpy(buffer->str, default_string); + snprintf(buffer->str, sizeof(buffer->str), "%s", default_string); buffer->ptr = buffer->str; - buffer->size = ARRAY_SIZE(buffer->str); + buffer->size = sizeof(buffer->str); } static void debug_append(struct debug_buffer *buffer, const char *str, const char *separator) @@ -4189,7 +4643,7 @@ static void debug_append(struct debug_buffer *buffer, const char *str, const cha if (size == -1 || size >= buffer->size) { buffer->size = 0; - strcpy(&buffer->str[ARRAY_SIZE(buffer->str) - 4], "..."); + strcpy(&buffer->str[sizeof(buffer->str) - 4], "..."); return; } @@ -4214,15 +4668,58 @@ const char *wined3d_debug_resource_access(DWORD access) return wine_dbg_sprintf("%s", buffer.str); } +const char *wined3d_debug_bind_flags(DWORD bind_flags) +{ + struct debug_buffer buffer; + + init_debug_buffer(&buffer, "0"); +#define BIND_FLAG_TO_STR(x) if (bind_flags & x) { debug_append(&buffer, #x, " | "); bind_flags &= ~x; } + BIND_FLAG_TO_STR(WINED3D_BIND_VERTEX_BUFFER); + BIND_FLAG_TO_STR(WINED3D_BIND_INDEX_BUFFER); + BIND_FLAG_TO_STR(WINED3D_BIND_CONSTANT_BUFFER); + BIND_FLAG_TO_STR(WINED3D_BIND_SHADER_RESOURCE); + BIND_FLAG_TO_STR(WINED3D_BIND_STREAM_OUTPUT); + BIND_FLAG_TO_STR(WINED3D_BIND_RENDER_TARGET); + BIND_FLAG_TO_STR(WINED3D_BIND_DEPTH_STENCIL); + BIND_FLAG_TO_STR(WINED3D_BIND_UNORDERED_ACCESS); +#undef BIND_FLAG_TO_STR + if (bind_flags) + FIXME("Unrecognised bind flag(s) %#x.\n", bind_flags); + + return wine_dbg_sprintf("%s", buffer.str); +} + +const char *wined3d_debug_view_desc(const struct wined3d_view_desc *d, const struct wined3d_resource *resource) +{ + struct debug_buffer buffer; + unsigned int flags = d->flags; + + init_debug_buffer(&buffer, "0"); +#define VIEW_FLAG_TO_STR(x) if (flags & x) { debug_append(&buffer, #x, " | "); flags &= ~x; } + VIEW_FLAG_TO_STR(WINED3D_VIEW_BUFFER_RAW); + VIEW_FLAG_TO_STR(WINED3D_VIEW_BUFFER_APPEND); + VIEW_FLAG_TO_STR(WINED3D_VIEW_BUFFER_COUNTER); + VIEW_FLAG_TO_STR(WINED3D_VIEW_TEXTURE_CUBE); + VIEW_FLAG_TO_STR(WINED3D_VIEW_TEXTURE_ARRAY); +#undef VIEW_FLAG_TO_STR + if (flags) + FIXME("Unrecognised view flag(s) %#x.\n", flags); + + if (resource->type == WINED3D_RTYPE_BUFFER) + return wine_dbg_sprintf("format %s, flags %s, start_idx %u, count %u", + debug_d3dformat(d->format_id), buffer.str, d->u.buffer.start_idx, d->u.buffer.count); + else + return wine_dbg_sprintf("format %s, flags %s, level_idx %u, level_count %u, layer_idx %u, layer_count %u", + debug_d3dformat(d->format_id), buffer.str, d->u.texture.level_idx, d->u.texture.level_count, + d->u.texture.layer_idx, d->u.texture.layer_count); +} + const char *debug_d3dusage(DWORD usage) { struct debug_buffer buffer; init_debug_buffer(&buffer, "0"); #define WINED3DUSAGE_TO_STR(x) if (usage & x) { debug_append(&buffer, #x, " | "); usage &= ~x; } - WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET); - WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL); - WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY); WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING); WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP); WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS); @@ -4235,7 +4732,6 @@ const char *debug_d3dusage(DWORD usage) WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP); WINED3DUSAGE_TO_STR(WINED3DUSAGE_TEXTAPI); WINED3DUSAGE_TO_STR(WINED3DUSAGE_LEGACY_CUBEMAP); - WINED3DUSAGE_TO_STR(WINED3DUSAGE_TEXTURE); WINED3DUSAGE_TO_STR(WINED3DUSAGE_OWNDC); WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL); WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY); @@ -4460,6 +4956,7 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN); D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX); D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE); + D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR); D3DSTATE_TO_STR(WINED3D_RS_BLENDOP); D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE); @@ -4479,18 +4976,11 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL); D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS); D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC); - D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1); D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2); D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3); - D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE4); - D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE5); - D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE6); - D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE7); - D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR); D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE); D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS); - D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIASCLAMP); D3DSTATE_TO_STR(WINED3D_RS_WRAP8); D3DSTATE_TO_STR(WINED3D_RS_WRAP9); D3DSTATE_TO_STR(WINED3D_RS_WRAP10); @@ -4503,7 +4993,6 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA); D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA); D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA); - D3DSTATE_TO_STR(WINED3D_RS_DEPTHCLIP); #undef D3DSTATE_TO_STR default: FIXME("Unrecognized %u render state!\n", state); @@ -4722,8 +5211,8 @@ const char *debug_d3dstate(DWORD state) return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0)); if (STATE_IS_MATERIAL(state)) return "STATE_MATERIAL"; - if (STATE_IS_FRONTFACE(state)) - return "STATE_FRONTFACE"; + if (STATE_IS_RASTERIZER(state)) + return "STATE_RASTERIZER"; if (STATE_IS_POINTSPRITECOORDORIGIN(state)) return "STATE_POINTSPRITECOORDORIGIN"; if (STATE_IS_BASEVERTEXINDEX(state)) @@ -4738,6 +5227,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_STREAM_OUTPUT"; if (STATE_IS_BLEND(state)) return "STATE_BLEND"; + if (STATE_IS_BLEND_FACTOR(state)) + return "STATE_BLEND_FACTOR"; return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } @@ -4811,6 +5302,45 @@ const char *debug_glerror(GLenum error) { } } +const char *wined3d_debug_vkresult(VkResult vr) +{ + switch (vr) + { +#define WINED3D_TO_STR(x) case x: return #x + WINED3D_TO_STR(VK_ERROR_INVALID_DEVICE_ADDRESS_EXT); + WINED3D_TO_STR(VK_ERROR_NOT_PERMITTED_EXT); + WINED3D_TO_STR(VK_ERROR_FRAGMENTATION_EXT); + WINED3D_TO_STR(VK_ERROR_INVALID_EXTERNAL_HANDLE); + WINED3D_TO_STR(VK_ERROR_OUT_OF_POOL_MEMORY); + WINED3D_TO_STR(VK_ERROR_INVALID_SHADER_NV); + WINED3D_TO_STR(VK_ERROR_OUT_OF_DATE_KHR); + WINED3D_TO_STR(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); + WINED3D_TO_STR(VK_ERROR_SURFACE_LOST_KHR); + WINED3D_TO_STR(VK_ERROR_FRAGMENTED_POOL); + WINED3D_TO_STR(VK_ERROR_FORMAT_NOT_SUPPORTED); + WINED3D_TO_STR(VK_ERROR_TOO_MANY_OBJECTS); + WINED3D_TO_STR(VK_ERROR_INCOMPATIBLE_DRIVER); + WINED3D_TO_STR(VK_ERROR_FEATURE_NOT_PRESENT); + WINED3D_TO_STR(VK_ERROR_EXTENSION_NOT_PRESENT); + WINED3D_TO_STR(VK_ERROR_LAYER_NOT_PRESENT); + WINED3D_TO_STR(VK_ERROR_MEMORY_MAP_FAILED); + WINED3D_TO_STR(VK_ERROR_DEVICE_LOST); + WINED3D_TO_STR(VK_ERROR_INITIALIZATION_FAILED); + WINED3D_TO_STR(VK_ERROR_OUT_OF_DEVICE_MEMORY); + WINED3D_TO_STR(VK_ERROR_OUT_OF_HOST_MEMORY); + WINED3D_TO_STR(VK_SUCCESS); + WINED3D_TO_STR(VK_NOT_READY); + WINED3D_TO_STR(VK_TIMEOUT); + WINED3D_TO_STR(VK_EVENT_SET); + WINED3D_TO_STR(VK_EVENT_RESET); + WINED3D_TO_STR(VK_INCOMPLETE); + WINED3D_TO_STR(VK_SUBOPTIMAL_KHR); +#undef WINED3D_TO_STR + default: + return wine_dbg_sprintf("unrecognised(%d)", vr); + } +} + static const char *debug_fixup_channel_source(enum fixup_channel_source source) { switch(source) @@ -4908,8 +5438,8 @@ void get_modelview_matrix(const struct wined3d_context *context, const struct wi void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_matrix *mat) { - BOOL clip_control = context->gl_info->supported[ARB_CLIP_CONTROL]; - BOOL flip = !clip_control && context->render_offscreen; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + BOOL clip_control, flip; float center_offset; /* There are a couple of additional things we have to take into account @@ -4927,7 +5457,9 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w * driver, but small enough to prevent it from interfering with any * anti-aliasing. */ - if (!clip_control && context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) + clip_control = d3d_info->clip_control; + flip = !clip_control && context->render_offscreen; + if (!clip_control && d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; @@ -4935,10 +5467,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w if (context->last_was_rhw) { /* Transform D3D RHW coordinates to OpenGL clip coordinates. */ - float x = state->viewport.x; - float y = state->viewport.y; - float w = state->viewport.width; - float h = state->viewport.height; + float x = state->viewports[0].x; + float y = state->viewports[0].y; + float w = state->viewports[0].width; + float h = state->viewports[0].height; float x_scale = 2.0f / w; float x_offset = (center_offset - (2.0f * x) - w) / w; float y_scale = flip ? 2.0f / h : 2.0f / -h; @@ -4962,10 +5494,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w else { float y_scale = flip ? -1.0f : 1.0f; - float x_offset = center_offset / state->viewport.width; + float x_offset = center_offset / state->viewports[0].width; float y_offset = flip - ? center_offset / state->viewport.height - : -center_offset / state->viewport.height; + ? center_offset / state->viewports[0].height + : -center_offset / state->viewports[0].height; float z_scale = clip_control ? 1.0f : 2.0f; float z_offset = clip_control ? 0.0f : -1.0f; const struct wined3d_matrix projection = @@ -4981,9 +5513,8 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w } /* Setup this textures matrix according to the texture flags. */ -static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const struct wined3d_matrix *matrix, - DWORD flags, BOOL calculated_coords, BOOL transformed, enum wined3d_format_id format_id, - BOOL ffp_proj_control, struct wined3d_matrix *out_matrix) +static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t flags, BOOL calculated_coords, + BOOL transformed, enum wined3d_format_id format_id, BOOL ffp_proj_control, struct wined3d_matrix *out_matrix) { struct wined3d_matrix mat; @@ -5097,13 +5628,12 @@ void get_texture_matrix(const struct wined3d_context *context, const struct wine unsigned int tex, struct wined3d_matrix *mat) { const struct wined3d_device *device = context->device; - const struct wined3d_gl_info *gl_info = context->gl_info; BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], - MAX_TEXTURES - 1); + WINED3D_MAX_TEXTURES - 1); - compute_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + tex], + compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex], state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS], generated, context->last_was_rhw, context->stream_info.use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)) @@ -5165,9 +5695,10 @@ void get_pointsize(const struct wined3d_context *context, const struct wined3d_s b.d = state->render_states[WINED3D_RS_POINTSCALE_B]; c.d = state->render_states[WINED3D_RS_POINTSCALE_C]; + /* Always use first viewport, this path does not apply to d3d10/11 multiple viewports case. */ if (state->render_states[WINED3D_RS_POINTSCALEENABLE]) { - float scale_factor = state->viewport.height * state->viewport.height; + float scale_factor = state->viewports[0].height * state->viewports[0].height; out_att[0] = a.f / scale_factor; out_att[1] = b.f / scale_factor; @@ -5265,14 +5796,27 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con {WINED3DFMT_X8D24_UNORM, { 16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, {WINED3DFMT_D32_UNORM, {4294967295.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, }; + enum wined3d_format_id format_id = format->id; + struct wined3d_color colour_srgb; unsigned int i; DWORD ret; - TRACE("Converting color %s to format %s.\n", debug_color(color), debug_d3dformat(format->id)); + TRACE("Converting colour %s to format %s.\n", debug_color(color), debug_d3dformat(format_id)); + + for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) + { + if (format_id != format_srgb_info[i].srgb_format_id) + continue; + + wined3d_colour_srgb_from_linear(&colour_srgb, color); + format_id = format_srgb_info[i].base_format_id; + color = &colour_srgb; + break; + } for (i = 0; i < ARRAY_SIZE(float_conv); ++i) { - if (format->id != float_conv[i].format_id) + if (format_id != float_conv[i].format_id) continue; ret = ((DWORD)((color->r * float_conv[i].mul.x) + 0.5f)) << float_conv[i].shift.x; @@ -5287,7 +5831,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con for (i = 0; i < ARRAY_SIZE(double_conv); ++i) { - if (format->id != double_conv[i].format_id) + if (format_id != double_conv[i].format_id) continue; ret = ((DWORD)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x; @@ -5300,7 +5844,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con return ret; } - FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id)); + FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format_id)); return 0; } @@ -5384,7 +5928,6 @@ void wined3d_format_get_float_color_key(const struct wined3d_format *format, } } -/* DirectDraw stuff */ enum wined3d_format_id pixelformat_for_depth(DWORD depth) { switch (depth) @@ -5427,329 +5970,8 @@ void multiply_matrix(struct wined3d_matrix *dst, const struct wined3d_matrix *sr *dst = tmp; } -/* Taken and adapted from Mesa. */ -BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in) -{ - float pos, neg, t, det; - struct wined3d_matrix temp; - - /* Calculate the determinant of upper left 3x3 submatrix and - * determine if the matrix is singular. */ - pos = neg = 0.0f; - t = in->_11 * in->_22 * in->_33; - if (t >= 0.0f) - pos += t; - else - neg += t; - - t = in->_21 * in->_32 * in->_13; - if (t >= 0.0f) - pos += t; - else - neg += t; - t = in->_31 * in->_12 * in->_23; - if (t >= 0.0f) - pos += t; - else - neg += t; - - t = -in->_31 * in->_22 * in->_13; - if (t >= 0.0f) - pos += t; - else - neg += t; - t = -in->_21 * in->_12 * in->_33; - if (t >= 0.0f) - pos += t; - else - neg += t; - - t = -in->_11 * in->_32 * in->_23; - if (t >= 0.0f) - pos += t; - else - neg += t; - - det = pos + neg; - - if (fabsf(det) < 1e-25f) - return FALSE; - - det = 1.0f / det; - temp._11 = (in->_22 * in->_33 - in->_32 * in->_23) * det; - temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det; - temp._13 = (in->_12 * in->_23 - in->_22 * in->_13) * det; - temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det; - temp._22 = (in->_11 * in->_33 - in->_31 * in->_13) * det; - temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det; - temp._31 = (in->_21 * in->_32 - in->_31 * in->_22) * det; - temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det; - temp._33 = (in->_11 * in->_22 - in->_21 * in->_12) * det; - - *out = temp; - return TRUE; -} - -static void swap_rows(float **a, float **b) -{ - float *tmp = *a; - - *a = *b; - *b = tmp; -} - -BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) -{ - float wtmp[4][8]; - float m0, m1, m2, m3, s; - float *r0, *r1, *r2, *r3; - - r0 = wtmp[0]; - r1 = wtmp[1]; - r2 = wtmp[2]; - r3 = wtmp[3]; - - r0[0] = m->_11; - r0[1] = m->_12; - r0[2] = m->_13; - r0[3] = m->_14; - r0[4] = 1.0f; - r0[5] = r0[6] = r0[7] = 0.0f; - - r1[0] = m->_21; - r1[1] = m->_22; - r1[2] = m->_23; - r1[3] = m->_24; - r1[5] = 1.0f; - r1[4] = r1[6] = r1[7] = 0.0f; - - r2[0] = m->_31; - r2[1] = m->_32; - r2[2] = m->_33; - r2[3] = m->_34; - r2[6] = 1.0f; - r2[4] = r2[5] = r2[7] = 0.0f; - - r3[0] = m->_41; - r3[1] = m->_42; - r3[2] = m->_43; - r3[3] = m->_44; - r3[7] = 1.0f; - r3[4] = r3[5] = r3[6] = 0.0f; - - /* Choose pivot - or die. */ - if (fabsf(r3[0]) > fabsf(r2[0])) - swap_rows(&r3, &r2); - if (fabsf(r2[0]) > fabsf(r1[0])) - swap_rows(&r2, &r1); - if (fabsf(r1[0]) > fabsf(r0[0])) - swap_rows(&r1, &r0); - if (r0[0] == 0.0f) - return FALSE; - - /* Eliminate first variable. */ - m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0]; - s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; - s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; - s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; - s = r0[4]; - if (s != 0.0f) - { - r1[4] -= m1 * s; - r2[4] -= m2 * s; - r3[4] -= m3 * s; - } - s = r0[5]; - if (s != 0.0f) - { - r1[5] -= m1 * s; - r2[5] -= m2 * s; - r3[5] -= m3 * s; - } - s = r0[6]; - if (s != 0.0f) - { - r1[6] -= m1 * s; - r2[6] -= m2 * s; - r3[6] -= m3 * s; - } - s = r0[7]; - if (s != 0.0f) - { - r1[7] -= m1 * s; - r2[7] -= m2 * s; - r3[7] -= m3 * s; - } - - /* Choose pivot - or die. */ - if (fabsf(r3[1]) > fabsf(r2[1])) - swap_rows(&r3, &r2); - if (fabsf(r2[1]) > fabsf(r1[1])) - swap_rows(&r2, &r1); - if (r1[1] == 0.0f) - return FALSE; - - /* Eliminate second variable. */ - m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1]; - r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; - r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; - s = r1[4]; - if (s != 0.0f) - { - r2[4] -= m2 * s; - r3[4] -= m3 * s; - } - s = r1[5]; - if (s != 0.0f) - { - r2[5] -= m2 * s; - r3[5] -= m3 * s; - } - s = r1[6]; - if (s != 0.0f) - { - r2[6] -= m2 * s; - r3[6] -= m3 * s; - } - s = r1[7]; - if (s != 0.0f) - { - r2[7] -= m2 * s; - r3[7] -= m3 * s; - } - - /* Choose pivot - or die. */ - if (fabsf(r3[2]) > fabsf(r2[2])) - swap_rows(&r3, &r2); - if (r2[2] == 0.0f) - return FALSE; - - /* Eliminate third variable. */ - m3 = r3[2] / r2[2]; - r3[3] -= m3 * r2[3]; - r3[4] -= m3 * r2[4]; - r3[5] -= m3 * r2[5]; - r3[6] -= m3 * r2[6]; - r3[7] -= m3 * r2[7]; - - /* Last check. */ - if (r3[3] == 0.0f) - return FALSE; - - /* Back substitute row 3. */ - s = 1.0f / r3[3]; - r3[4] *= s; - r3[5] *= s; - r3[6] *= s; - r3[7] *= s; - - /* Back substitute row 2. */ - m2 = r2[3]; - s = 1.0f / r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2); - r2[5] = s * (r2[5] - r3[5] * m2); - r2[6] = s * (r2[6] - r3[6] * m2); - r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1; - r1[5] -= r3[5] * m1; - r1[6] -= r3[6] * m1; - r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0; - r0[5] -= r3[5] * m0; - r0[6] -= r3[6] * m0; - r0[7] -= r3[7] * m0; - - /* Back substitute row 1. */ - m1 = r1[2]; - s = 1.0f / r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1); - r1[5] = s * (r1[5] - r2[5] * m1); - r1[6] = s * (r1[6] - r2[6] * m1); - r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0; - r0[5] -= r2[5] * m0; - r0[6] -= r2[6] * m0; - r0[7] -= r2[7] * m0; - - /* Back substitute row 0. */ - m0 = r0[1]; - s = 1.0f / r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0); - r0[5] = s * (r0[5] - r1[5] * m0); - r0[6] = s * (r0[6] - r1[6] * m0); - r0[7] = s * (r0[7] - r1[7] * m0); - - out->_11 = r0[4]; - out->_12 = r0[5]; - out->_13 = r0[6]; - out->_14 = r0[7]; - out->_21 = r1[4]; - out->_22 = r1[5]; - out->_23 = r1[6]; - out->_24 = r1[7]; - out->_31 = r2[4]; - out->_32 = r2[5]; - out->_33 = r2[6]; - out->_34 = r2[7]; - out->_41 = r3[4]; - out->_42 = r3[5]; - out->_43 = r3[6]; - out->_44 = r3[7]; - - return TRUE; -} - -void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) -{ - struct wined3d_matrix temp; - unsigned int i, j; - - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j]; - - *out = temp; -} - -DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { - DWORD size = 0; - int i; - int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; - - if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float); - if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD); - if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD); - if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD); - switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) { - case WINED3DFVF_XYZ: size += 3 * sizeof(float); break; - case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break; - case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break; - case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break; - case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break; - case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break; - case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break; - case WINED3DFVF_XYZW: size += 4 * sizeof(float); break; - default: ERR("Unexpected position mask\n"); - } - for (i = 0; i < numTextures; i++) { - size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float); - } - - return size; -} - -unsigned int wined3d_max_compat_varyings(const struct wined3d_gl_info *gl_info) -{ - /* On core profile we have to also count diffuse and specular colors and the - * fog coordinate. */ - return gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? MAX_TEXTURES * 4 : (MAX_TEXTURES + 2) * 4 + 1; -} - -void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state, - struct ffp_frag_settings *settings, BOOL ignore_textype) +void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state, + struct ffp_frag_settings *settings, BOOL ignore_textype) { #define ARG1 0x01 #define ARG2 0x02 @@ -5787,14 +6009,13 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d unsigned int i; DWORD ttff; DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; - const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; settings->padding = 0; for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i) { - const struct wined3d_texture *texture; + struct wined3d_texture *texture; settings->op[i].padding = 0; if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE) @@ -5804,16 +6025,16 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED; settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED; settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; - settings->op[i].dst = resultreg; + settings->op[i].tmp_dst = 0; settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; - settings->op[i].projected = proj_none; + settings->op[i].projected = WINED3D_PROJECTION_NONE; i++; break; } if ((texture = state->textures[i])) { - if (can_use_texture_swizzle(gl_info, texture->resource.format)) + if (can_use_texture_swizzle(d3d_info, texture->resource.format)) settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; else settings->op[i].color_fixup = texture->resource.format->color_fixup; @@ -5823,7 +6044,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d } else { - switch (texture->target) + switch (wined3d_texture_gl(texture)->target) { case GL_TEXTURE_1D: settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; @@ -5884,7 +6105,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d GLenum texture_dimensions; texture = state->textures[0]; - texture_dimensions = texture->target; + texture_dimensions = wined3d_texture_gl(texture)->target; if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { @@ -5930,15 +6151,15 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d { ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS]; if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3)) - settings->op[i].projected = proj_count3; + settings->op[i].projected = WINED3D_PROJECTION_COUNT3; else if (ttff & WINED3D_TTFF_PROJECTED) - settings->op[i].projected = proj_count4; + settings->op[i].projected = WINED3D_PROJECTION_COUNT4; else - settings->op[i].projected = proj_none; + settings->op[i].projected = WINED3D_PROJECTION_NONE; } else { - settings->op[i].projected = proj_none; + settings->op[i].projected = WINED3D_PROJECTION_NONE; } settings->op[i].cop = cop; @@ -5949,15 +6170,11 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->op[i].aarg0 = aarg0; settings->op[i].aarg1 = aarg1; settings->op[i].aarg2 = aarg2; - - if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP) - settings->op[i].dst = tempreg; - else - settings->op[i].dst = resultreg; + settings->op[i].tmp_dst = state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP; } /* Clear unsupported stages */ - for(; i < MAX_TEXTURES; i++) { + for(; i < WINED3D_MAX_TEXTURES; i++) { memset(&settings->op[i], 0xff, sizeof(settings->op[i])); } @@ -6003,7 +6220,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d break; } } - settings->sRGB_write = !gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb); + settings->sRGB_write = !d3d_info->srgb_write_control && needs_srgb_write(context, state, state->fb); if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING] || !state->render_states[WINED3D_RS_CLIPPLANEENABLE]) { @@ -6030,11 +6247,10 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d * Reading uninitialized varyings on core profile contexts results in an * error while with builtin varyings on legacy contexts you get undefined * behavior. */ - if (d3d_info->limits.varying_count - && d3d_info->limits.varying_count < wined3d_max_compat_varyings(gl_info)) + if (d3d_info->limits.varying_count && !d3d_info->full_ffp_varyings) { settings->texcoords_initialized = 0; - for (i = 0; i < MAX_TEXTURES; ++i) + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) { if (use_vs(state)) { @@ -6047,508 +6263,782 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d unsigned int coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; if ((state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT) & WINED3D_FFP_TCI_MASK - || (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))) + || (coord_idx < WINED3D_MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))) settings->texcoords_initialized |= 1u << i; } } } - else - { - settings->texcoords_initialized = (1u << MAX_TEXTURES) - 1; - } + else + { + settings->texcoords_initialized = (1u << WINED3D_MAX_TEXTURES) - 1; + } + + settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] + && state->gl_primitive_type == GL_POINTS; + + if (d3d_info->ffp_alpha_test) + settings->alpha_test_func = WINED3D_CMP_ALWAYS - 1; + else + settings->alpha_test_func = (state->render_states[WINED3D_RS_ALPHATESTENABLE] + ? wined3d_sanitize_cmp_func(state->render_states[WINED3D_RS_ALPHAFUNC]) + : WINED3D_CMP_ALWAYS) - 1; + + if (d3d_info->emulated_flatshading) + settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + else + settings->flatshading = FALSE; +} + +const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, + const struct ffp_frag_settings *settings) +{ + struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings); + return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL; +} + +void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) +{ + /* Note that the key is the implementation independent part of the ffp_frag_desc structure, + * whereas desc points to an extended structure with implementation specific parts. */ + if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1) + { + ERR("Failed to insert ffp frag shader.\n"); + } +} + +/* Activates the texture dimension according to the bound D3D texture. Does + * not care for the colorop or correct gl texture unit (when using nvrc). + * Requires the caller to activate the correct unit. */ +/* Context activation is done by the caller (state handler). */ +void texture_activate_dimensions(struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) +{ + if (texture) + { + switch (wined3d_texture_gl(texture)->target) + { + case GL_TEXTURE_2D: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); + checkGLcall("glEnable(GL_TEXTURE_2D)"); + break; + case GL_TEXTURE_RECTANGLE_ARB: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)"); + break; + case GL_TEXTURE_3D: + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D); + checkGLcall("glEnable(GL_TEXTURE_3D)"); + break; + case GL_TEXTURE_CUBE_MAP_ARB: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)"); + break; + } + } + else + { + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); + checkGLcall("glEnable(GL_TEXTURE_2D)"); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + /* Binding textures is done by samplers. A dummy texture will be bound */ + } +} + +/* Context activation is done by the caller (state handler). */ +void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + unsigned int sampler = state_id - STATE_SAMPLER(0); + unsigned int mapped_stage; + + /* No need to enable / disable anything here for unused samplers. The + * tex_colorop handler takes care. Also no action is needed with pixel + * shaders, or if tex_colorop will take care of this business. */ + mapped_stage = context_gl->tex_unit_map[sampler]; + if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context_gl->gl_info->limits.textures) + return; + if (sampler >= context->lowest_disabled_stage) + return; + if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) + return; + + texture_activate_dimensions(state->textures[sampler], context_gl->gl_info); +} + +int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct ffp_frag_settings *ka = key; + const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings; + + return memcmp(ka, kb, sizeof(*ka)); +} + +void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, + const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings) +{ + enum wined3d_material_color_source diffuse_source, emissive_source, ambient_source, specular_source; + const struct wined3d_stream_info *si = &context->stream_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + unsigned int coord_idx, i; + + memset(settings, 0, sizeof(*settings)); + + if (si->position_transformed) + { + settings->transformed = 1; + settings->point_size = state->gl_primitive_type == GL_POINTS; + settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); + if (!state->render_states[WINED3D_RS_FOGENABLE]) + settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; + else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) + settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; + else + settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; + + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + { + coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; + if (coord_idx < WINED3D_MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) + settings->texcoords |= 1u << i; + settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; + } + if (d3d_info->full_ffp_varyings) + settings->texcoords = (1u << WINED3D_MAX_TEXTURES) - 1; + + if (d3d_info->emulated_flatshading) + settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + else + settings->flatshading = FALSE; + + settings->swizzle_map = si->swizzle_map; + + return; + } + + switch (state->render_states[WINED3D_RS_VERTEXBLEND]) + { + case WINED3D_VBF_DISABLE: + case WINED3D_VBF_1WEIGHTS: + case WINED3D_VBF_2WEIGHTS: + case WINED3D_VBF_3WEIGHTS: + settings->vertexblends = state->render_states[WINED3D_RS_VERTEXBLEND]; + break; + default: + FIXME("Unsupported vertex blending: %d\n", state->render_states[WINED3D_RS_VERTEXBLEND]); + break; + } + + settings->clipping = state->render_states[WINED3D_RS_CLIPPING] + && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; + settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL)); + settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS]; + settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING]; + settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; + settings->point_size = state->gl_primitive_type == GL_POINTS; + settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); + + wined3d_get_material_colour_source(&diffuse_source, &emissive_source, + &ambient_source, &specular_source, state, si); + settings->diffuse_source = diffuse_source; + settings->emissive_source = emissive_source; + settings->ambient_source = ambient_source; + settings->specular_source = specular_source; + + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + { + coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; + if (coord_idx < WINED3D_MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) + settings->texcoords |= 1u << i; + settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; + } + if (d3d_info->full_ffp_varyings) + settings->texcoords = (1u << WINED3D_MAX_TEXTURES) - 1; + + for (i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) + { + if (!state->light_state.lights[i]) + continue; + + switch (state->light_state.lights[i]->OriginalParms.type) + { + case WINED3D_LIGHT_POINT: + ++settings->point_light_count; + break; + case WINED3D_LIGHT_SPOT: + ++settings->spot_light_count; + break; + case WINED3D_LIGHT_DIRECTIONAL: + ++settings->directional_light_count; + break; + case WINED3D_LIGHT_PARALLELPOINT: + ++settings->parallel_point_light_count; + break; + default: + FIXME("Unhandled light type %#x.\n", state->light_state.lights[i]->OriginalParms.type); + break; + } + } - settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] - && state->gl_primitive_type == GL_POINTS; + if (!state->render_states[WINED3D_RS_FOGENABLE]) + settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; + else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) + { + settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - settings->alpha_test_func = WINED3D_CMP_ALWAYS - 1; + if (state->transforms[WINED3D_TS_PROJECTION]._14 == 0.0f + && state->transforms[WINED3D_TS_PROJECTION]._24 == 0.0f + && state->transforms[WINED3D_TS_PROJECTION]._34 == 0.0f + && state->transforms[WINED3D_TS_PROJECTION]._44 == 1.0f) + settings->ortho_fog = 1; + } + else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE) + settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; + else if (state->render_states[WINED3D_RS_RANGEFOGENABLE]) + settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE; else - settings->alpha_test_func = (state->render_states[WINED3D_RS_ALPHATESTENABLE] - ? wined3d_sanitize_cmp_func(state->render_states[WINED3D_RS_ALPHAFUNC]) - : WINED3D_CMP_ALWAYS) - 1; + settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; if (d3d_info->emulated_flatshading) settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; else settings->flatshading = FALSE; + + settings->swizzle_map = si->swizzle_map; } -const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, - const struct ffp_frag_settings *settings) +int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) { - struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings); - return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL; + const struct wined3d_ffp_vs_settings *ka = key; + const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry, + const struct wined3d_ffp_vs_desc, entry)->settings; + + return memcmp(ka, kb, sizeof(*ka)); } -void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) +const char *wined3d_debug_location(DWORD location) { - /* Note that the key is the implementation independent part of the ffp_frag_desc structure, - * whereas desc points to an extended structure with implementation specific parts. */ - if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1) + struct debug_buffer buffer; + const char *prefix = ""; + const char *suffix = ""; + + if (wined3d_popcount(location) > 16) { - ERR("Failed to insert ffp frag shader.\n"); + prefix = "~("; + location = ~location; + suffix = ")"; + } + + init_debug_buffer(&buffer, "0"); +#define LOCATION_TO_STR(x) if (location & x) { debug_append(&buffer, #x, " | "); location &= ~x; } + LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED); + LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM); + LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY); + LOCATION_TO_STR(WINED3D_LOCATION_BUFFER); + LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB); + LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB); + LOCATION_TO_STR(WINED3D_LOCATION_DRAWABLE); + LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE); + LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED); +#undef LOCATION_TO_STR + if (location) + FIXME("Unrecognized location flag(s) %#x.\n", location); + + return wine_dbg_sprintf("%s%s%s", prefix, buffer.str, suffix); +} + +const char *wined3d_debug_feature_level(enum wined3d_feature_level level) +{ + switch (level) + { +#define LEVEL_TO_STR(level) case level: return #level + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_5); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_6); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_7); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_8); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_1); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_2); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_3); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10_1); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11); + LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11_1); +#undef LEVEL_TO_STR + default: + return wine_dbg_sprintf("%#x", level); } } -/* Activates the texture dimension according to the bound D3D texture. Does - * not care for the colorop or correct gl texture unit (when using nvrc). - * Requires the caller to activate the correct unit. */ -/* Context activation is done by the caller (state handler). */ -void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) +/* Print a floating point value with the %.8e format specifier, always using + * '.' as decimal separator. */ +void wined3d_ftoa(float value, char *s) { - if (texture) + int idx = 1; + + if (copysignf(1.0f, value) < 0.0f) + ++idx; + + /* Be sure to allocate a buffer of at least 17 characters for the result + as sprintf may return a 3 digit exponent when using the MSVC runtime + instead of a 2 digit exponent. */ + sprintf(s, "%.8e", value); + if (isfinite(value)) + s[idx] = '.'; +} + +void wined3d_release_dc(HWND window, HDC dc) +{ + /* You'd figure ReleaseDC() would fail if the DC doesn't match the window. + * However, that's not what actually happens, and there are user32 tests + * that confirm ReleaseDC() with the wrong window is supposed to succeed. + * So explicitly check that the DC belongs to the window, since we want to + * avoid releasing a DC that belongs to some other window if the original + * window was already destroyed. */ + if (WindowFromDC(dc) != window) + WARN("DC %p does not belong to window %p.\n", dc, window); + else if (!ReleaseDC(window, dc)) + ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError()); +} + +BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) +{ + RECT orig = *clipped; + float scale_x = (float)(orig.right - orig.left) / (float)(other->right - other->left); + float scale_y = (float)(orig.bottom - orig.top) / (float)(other->bottom - other->top); + + IntersectRect(clipped, clipped, clip_rect); + + if (IsRectEmpty(clipped)) { - switch (texture->target) - { - case GL_TEXTURE_1D: - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable(GL_TEXTURE_2D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable(GL_TEXTURE_3D)"); - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); - } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); - } - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_1D); - checkGLcall("glEnable(GL_TEXTURE_1D)"); - break; - case GL_TEXTURE_2D: - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); - checkGLcall("glDisable(GL_TEXTURE_1D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable(GL_TEXTURE_3D)"); - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); - } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); - } - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); - checkGLcall("glEnable(GL_TEXTURE_2D)"); - break; - case GL_TEXTURE_RECTANGLE_ARB: - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); - checkGLcall("glDisable(GL_TEXTURE_1D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable(GL_TEXTURE_2D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable(GL_TEXTURE_3D)"); - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); - } - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)"); - break; - case GL_TEXTURE_3D: - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); - } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); - } - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); - checkGLcall("glDisable(GL_TEXTURE_1D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable(GL_TEXTURE_2D)"); - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D); - checkGLcall("glEnable(GL_TEXTURE_3D)"); - break; - case GL_TEXTURE_CUBE_MAP_ARB: - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); - checkGLcall("glDisable(GL_TEXTURE_1D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable(GL_TEXTURE_2D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable(GL_TEXTURE_3D)"); - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); - } - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)"); - break; - } + SetRectEmpty(other); + return FALSE; } - else + + other->left += (LONG)((clipped->left - orig.left) / scale_x); + other->top += (LONG)((clipped->top - orig.top) / scale_y); + other->right -= (LONG)((orig.right - clipped->right) / scale_x); + other->bottom -= (LONG)((orig.bottom - clipped->bottom) / scale_y); + + return TRUE; +} + +void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *gl_limits, + enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) +{ + unsigned int i; + + *base = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); - checkGLcall("glDisable(GL_TEXTURE_1D)"); - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); - checkGLcall("glEnable(GL_TEXTURE_2D)"); - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); - checkGLcall("glDisable(GL_TEXTURE_3D)"); - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); - } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); - } - /* Binding textures is done by samplers. A dummy texture will be bound */ + *count = gl_limits->uniform_blocks[i]; + if (i == shader_type) + return; + *base += *count; + } + + ERR("Unrecognized shader type %#x.\n", shader_type); + *count = 0; +} + +void wined3d_gl_limits_get_texture_unit_range(const struct wined3d_gl_limits *gl_limits, + enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) +{ + unsigned int i; + + if (shader_type == WINED3D_SHADER_TYPE_COMPUTE) + { + if (gl_limits->combined_samplers == gl_limits->graphics_samplers) + *base = 0; + else + *base = gl_limits->graphics_samplers; + *count = gl_limits->samplers[WINED3D_SHADER_TYPE_COMPUTE]; + return; + } + + *base = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + { + *count = gl_limits->samplers[i]; + if (i == shader_type) + return; + *base += *count; } + + ERR("Unrecognized shader type %#x.\n", shader_type); + *count = 0; } -/* Context activation is done by the caller (state handler). */ -void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) { - DWORD sampler = state_id - STATE_SAMPLER(0); - DWORD mapped_stage = context->tex_unit_map[sampler]; + SIZE_T max_capacity, new_capacity; + void *new_elements; - /* No need to enable / disable anything here for unused samplers. The - * tex_colorop handler takes care. Also no action is needed with pixel - * shaders, or if tex_colorop will take care of this business. */ - if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) - return; - if (sampler >= context->lowest_disabled_stage) - return; - if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP))) - return; + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(1, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = count; + + if (!*elements) + new_elements = heap_alloc_zero(new_capacity * size); + else + new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); + if (!new_elements) + return FALSE; - texture_activate_dimensions(state->textures[sampler], context->gl_info); + *elements = new_elements; + *capacity = new_capacity; + return TRUE; } -int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry) +static void swap_rows(float **a, float **b) { - const struct ffp_frag_settings *ka = key; - const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings; + float *tmp = *a; - return memcmp(ka, kb, sizeof(*ka)); + *a = *b; + *b = tmp; } -void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, - const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings) +BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) { - const struct wined3d_stream_info *si = &context->stream_info; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; - unsigned int coord_idx, i; + float wtmp[4][8]; + float m0, m1, m2, m3, s; + float *r0, *r1, *r2, *r3; - memset(settings, 0, sizeof(*settings)); + r0 = wtmp[0]; + r1 = wtmp[1]; + r2 = wtmp[2]; + r3 = wtmp[3]; - if (si->position_transformed) - { - settings->transformed = 1; - settings->point_size = state->gl_primitive_type == GL_POINTS; - settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); - if (!state->render_states[WINED3D_RS_FOGENABLE]) - settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; - else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) - settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; - else - settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; + r0[0] = m->_11; + r0[1] = m->_12; + r0[2] = m->_13; + r0[3] = m->_14; + r0[4] = 1.0f; + r0[5] = r0[6] = r0[7] = 0.0f; - for (i = 0; i < MAX_TEXTURES; ++i) - { - coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; - if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) - settings->texcoords |= 1u << i; - settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; - } - if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info)) - settings->texcoords = (1u << MAX_TEXTURES) - 1; + r1[0] = m->_21; + r1[1] = m->_22; + r1[2] = m->_23; + r1[3] = m->_24; + r1[5] = 1.0f; + r1[4] = r1[6] = r1[7] = 0.0f; - if (d3d_info->emulated_flatshading) - settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; - else - settings->flatshading = FALSE; + r2[0] = m->_31; + r2[1] = m->_32; + r2[2] = m->_33; + r2[3] = m->_34; + r2[6] = 1.0f; + r2[4] = r2[5] = r2[7] = 0.0f; - settings->swizzle_map = si->swizzle_map; + r3[0] = m->_41; + r3[1] = m->_42; + r3[2] = m->_43; + r3[3] = m->_44; + r3[7] = 1.0f; + r3[4] = r3[5] = r3[6] = 0.0f; - return; - } + /* Choose pivot - or die. */ + if (fabsf(r3[0]) > fabsf(r2[0])) + swap_rows(&r3, &r2); + if (fabsf(r2[0]) > fabsf(r1[0])) + swap_rows(&r2, &r1); + if (fabsf(r1[0]) > fabsf(r0[0])) + swap_rows(&r1, &r0); + if (r0[0] == 0.0f) + return FALSE; - switch (state->render_states[WINED3D_RS_VERTEXBLEND]) + /* Eliminate first variable. */ + m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0]; + s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; + s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; + s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0f) { - case WINED3D_VBF_DISABLE: - case WINED3D_VBF_1WEIGHTS: - case WINED3D_VBF_2WEIGHTS: - case WINED3D_VBF_3WEIGHTS: - settings->vertexblends = state->render_states[WINED3D_RS_VERTEXBLEND]; - break; - default: - FIXME("Unsupported vertex blending: %d\n", state->render_states[WINED3D_RS_VERTEXBLEND]); - break; + r1[4] -= m1 * s; + r2[4] -= m2 * s; + r3[4] -= m3 * s; } - - if (use_indexed_vertex_blending(state, si)) + s = r0[5]; + if (s != 0.0f) { - if (use_software_vertex_processing(context->device)) - settings->sw_blending = 1; - else - settings->vb_indices = 1; + r1[5] -= m1 * s; + r2[5] -= m2 * s; + r3[5] -= m3 * s; } - - settings->clipping = state->render_states[WINED3D_RS_CLIPPING] - && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; - settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL)); - settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS]; - settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING]; - settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; - settings->point_size = state->gl_primitive_type == GL_POINTS; - settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); - - if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1u << WINED3D_FFP_DIFFUSE))) + s = r0[6]; + if (s != 0.0f) { - settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]; - settings->emissive_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]; - settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]; - settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]; + r1[6] -= m1 * s; + r2[6] -= m2 * s; + r3[6] -= m3 * s; } - else + s = r0[7]; + if (s != 0.0f) { - settings->diffuse_source = WINED3D_MCS_MATERIAL; - settings->emissive_source = WINED3D_MCS_MATERIAL; - settings->ambient_source = WINED3D_MCS_MATERIAL; - settings->specular_source = WINED3D_MCS_MATERIAL; + r1[7] -= m1 * s; + r2[7] -= m2 * s; + r3[7] -= m3 * s; } - for (i = 0; i < MAX_TEXTURES; ++i) + /* Choose pivot - or die. */ + if (fabsf(r3[1]) > fabsf(r2[1])) + swap_rows(&r3, &r2); + if (fabsf(r2[1]) > fabsf(r1[1])) + swap_rows(&r2, &r1); + if (r1[1] == 0.0f) + return FALSE; + + /* Eliminate second variable. */ + m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1]; + r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; + s = r1[4]; + if (s != 0.0f) { - coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; - if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))) - settings->texcoords |= 1u << i; - settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; + r2[4] -= m2 * s; + r3[4] -= m3 * s; } - if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info)) - settings->texcoords = (1u << MAX_TEXTURES) - 1; - - for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) + s = r1[5]; + if (s != 0.0f) { - if (!state->lights[i]) - continue; - - switch (state->lights[i]->OriginalParms.type) - { - case WINED3D_LIGHT_POINT: - ++settings->point_light_count; - break; - case WINED3D_LIGHT_SPOT: - ++settings->spot_light_count; - break; - case WINED3D_LIGHT_DIRECTIONAL: - ++settings->directional_light_count; - break; - case WINED3D_LIGHT_PARALLELPOINT: - ++settings->parallel_point_light_count; - break; - default: - FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); - break; - } + r2[5] -= m2 * s; + r3[5] -= m3 * s; } - - if (!state->render_states[WINED3D_RS_FOGENABLE]) - settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; - else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) + s = r1[6]; + if (s != 0.0f) { - settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; - - if (state->transforms[WINED3D_TS_PROJECTION]._14 == 0.0f - && state->transforms[WINED3D_TS_PROJECTION]._24 == 0.0f - && state->transforms[WINED3D_TS_PROJECTION]._34 == 0.0f - && state->transforms[WINED3D_TS_PROJECTION]._44 == 1.0f) - settings->ortho_fog = 1; + r2[6] -= m2 * s; + r3[6] -= m3 * s; } - else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE) - settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; - else if (state->render_states[WINED3D_RS_RANGEFOGENABLE]) - settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE; - else - settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; - - if (d3d_info->emulated_flatshading) - settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; - else - settings->flatshading = FALSE; - - settings->swizzle_map = si->swizzle_map; -} - -int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) -{ - const struct wined3d_ffp_vs_settings *ka = key; - const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry, - const struct wined3d_ffp_vs_desc, entry)->settings; - - return memcmp(ka, kb, sizeof(*ka)); -} - -const char *wined3d_debug_location(DWORD location) -{ - struct debug_buffer buffer; - const char *prefix = ""; - const char *suffix = ""; - - if (wined3d_popcount(location) > 16) + s = r1[7]; + if (s != 0.0f) { - prefix = "~("; - location = ~location; - suffix = ")"; + r2[7] -= m2 * s; + r3[7] -= m3 * s; } - init_debug_buffer(&buffer, "0"); -#define LOCATION_TO_STR(x) if (location & x) { debug_append(&buffer, #x, " | "); location &= ~x; } - LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED); - LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM); - LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY); - LOCATION_TO_STR(WINED3D_LOCATION_BUFFER); - LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB); - LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB); - LOCATION_TO_STR(WINED3D_LOCATION_DRAWABLE); - LOCATION_TO_STR(WINED3D_LOCATION_RB_MULTISAMPLE); - LOCATION_TO_STR(WINED3D_LOCATION_RB_RESOLVED); -#undef LOCATION_TO_STR - if (location) - FIXME("Unrecognized location flag(s) %#x.\n", location); - - return wine_dbg_sprintf("%s%s%s", prefix, buffer.str, suffix); -} - -/* Print a floating point value with the %.8e format specifier, always using - * '.' as decimal separator. */ -void wined3d_ftoa(float value, char *s) -{ - int idx = 1; + /* Choose pivot - or die. */ + if (fabsf(r3[2]) > fabsf(r2[2])) + swap_rows(&r3, &r2); + if (r2[2] == 0.0f) + return FALSE; - if (copysignf(1.0f, value) < 0.0f) - ++idx; + /* Eliminate third variable. */ + m3 = r3[2] / r2[2]; + r3[3] -= m3 * r2[3]; + r3[4] -= m3 * r2[4]; + r3[5] -= m3 * r2[5]; + r3[6] -= m3 * r2[6]; + r3[7] -= m3 * r2[7]; - /* Be sure to allocate a buffer of at least 17 characters for the result - as sprintf may return a 3 digit exponent when using the MSVC runtime - instead of a 2 digit exponent. */ - sprintf(s, "%.8e", value); - if (isfinite(value)) - s[idx] = '.'; -} + /* Last check. */ + if (r3[3] == 0.0f) + return FALSE; -void wined3d_release_dc(HWND window, HDC dc) -{ - /* You'd figure ReleaseDC() would fail if the DC doesn't match the window. - * However, that's not what actually happens, and there are user32 tests - * that confirm ReleaseDC() with the wrong window is supposed to succeed. - * So explicitly check that the DC belongs to the window, since we want to - * avoid releasing a DC that belongs to some other window if the original - * window was already destroyed. */ - if (WindowFromDC(dc) != window) - WARN("DC %p does not belong to window %p.\n", dc, window); - else if (!ReleaseDC(window, dc)) - ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError()); -} + /* Back substitute row 3. */ + s = 1.0f / r3[3]; + r3[4] *= s; + r3[5] *= s; + r3[6] *= s; + r3[7] *= s; -BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) -{ - RECT orig = *clipped; - float scale_x = (float)(orig.right - orig.left) / (float)(other->right - other->left); - float scale_y = (float)(orig.bottom - orig.top) / (float)(other->bottom - other->top); + /* Back substitute row 2. */ + m2 = r2[3]; + s = 1.0f / r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2); + r2[5] = s * (r2[5] - r3[5] * m2); + r2[6] = s * (r2[6] - r3[6] * m2); + r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1; + r1[5] -= r3[5] * m1; + r1[6] -= r3[6] * m1; + r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0; + r0[5] -= r3[5] * m0; + r0[6] -= r3[6] * m0; + r0[7] -= r3[7] * m0; - IntersectRect(clipped, clipped, clip_rect); + /* Back substitute row 1. */ + m1 = r1[2]; + s = 1.0f / r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1); + r1[5] = s * (r1[5] - r2[5] * m1); + r1[6] = s * (r1[6] - r2[6] * m1); + r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0; + r0[5] -= r2[5] * m0; + r0[6] -= r2[6] * m0; + r0[7] -= r2[7] * m0; - if (IsRectEmpty(clipped)) - { - SetRectEmpty(other); - return FALSE; - } + /* Back substitute row 0. */ + m0 = r0[1]; + s = 1.0f / r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0); + r0[5] = s * (r0[5] - r1[5] * m0); + r0[6] = s * (r0[6] - r1[6] * m0); + r0[7] = s * (r0[7] - r1[7] * m0); - other->left += (LONG)((clipped->left - orig.left) / scale_x); - other->top += (LONG)((clipped->top - orig.top) / scale_y); - other->right -= (LONG)((orig.right - clipped->right) / scale_x); - other->bottom -= (LONG)((orig.bottom - clipped->bottom) / scale_y); + out->_11 = r0[4]; + out->_12 = r0[5]; + out->_13 = r0[6]; + out->_14 = r0[7]; + out->_21 = r1[4]; + out->_22 = r1[5]; + out->_23 = r1[6]; + out->_24 = r1[7]; + out->_31 = r2[4]; + out->_32 = r2[5]; + out->_33 = r2[6]; + out->_34 = r2[7]; + out->_41 = r3[4]; + out->_42 = r3[5]; + out->_43 = r3[6]; + out->_44 = r3[7]; return TRUE; } -void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *gl_limits, - enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) +/* Taken and adapted from Mesa. */ +BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in) { - unsigned int i; - - *base = 0; - for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) - { - *count = gl_limits->uniform_blocks[i]; - if (i == shader_type) - return; - *base += *count; - } + float pos, neg, t, det; + struct wined3d_matrix temp; - ERR("Unrecognized shader type %#x.\n", shader_type); - *count = 0; -} + /* Calculate the determinant of upper left 3x3 submatrix and + * determine if the matrix is singular. */ + pos = neg = 0.0f; + t = in->_11 * in->_22 * in->_33; + if (t >= 0.0f) + pos += t; + else + neg += t; -void wined3d_gl_limits_get_texture_unit_range(const struct wined3d_gl_limits *gl_limits, - enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) -{ - unsigned int i; + t = in->_21 * in->_32 * in->_13; + if (t >= 0.0f) + pos += t; + else + neg += t; + t = in->_31 * in->_12 * in->_23; + if (t >= 0.0f) + pos += t; + else + neg += t; - if (shader_type == WINED3D_SHADER_TYPE_COMPUTE) - { - if (gl_limits->combined_samplers == gl_limits->graphics_samplers) - *base = 0; - else - *base = gl_limits->graphics_samplers; - *count = gl_limits->samplers[WINED3D_SHADER_TYPE_COMPUTE]; - return; - } + t = -in->_31 * in->_22 * in->_13; + if (t >= 0.0f) + pos += t; + else + neg += t; + t = -in->_21 * in->_12 * in->_33; + if (t >= 0.0f) + pos += t; + else + neg += t; - *base = 0; - for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) - { - *count = gl_limits->samplers[i]; - if (i == shader_type) - return; - *base += *count; - } + t = -in->_11 * in->_32 * in->_23; + if (t >= 0.0f) + pos += t; + else + neg += t; - ERR("Unrecognized shader type %#x.\n", shader_type); - *count = 0; -} + det = pos + neg; -BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) -{ - SIZE_T max_capacity, new_capacity; - void *new_elements; + if (fabsf(det) < 1e-25f) + return FALSE; - if (count <= *capacity) - return TRUE; + det = 1.0f / det; + temp._11 = (in->_22 * in->_33 - in->_32 * in->_23) * det; + temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det; + temp._13 = (in->_12 * in->_23 - in->_22 * in->_13) * det; + temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det; + temp._22 = (in->_11 * in->_33 - in->_31 * in->_13) * det; + temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det; + temp._31 = (in->_21 * in->_32 - in->_31 * in->_22) * det; + temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det; + temp._33 = (in->_11 * in->_22 - in->_21 * in->_12) * det; - max_capacity = ~(SIZE_T)0 / size; - if (count > max_capacity) - return FALSE; + *out = temp; + return TRUE; +} - new_capacity = max(1, *capacity); - while (new_capacity < count && new_capacity <= max_capacity / 2) - new_capacity *= 2; - if (new_capacity < count) - new_capacity = count; +void compute_normal_matrix(float *normal_matrix, BOOL legacy_lighting, + const struct wined3d_matrix *modelview) +{ + struct wined3d_matrix mv; + unsigned int i, j; - if (!*elements) - new_elements = heap_alloc_zero(new_capacity * size); + mv = *modelview; + if (legacy_lighting) + invert_matrix_3d(&mv, &mv); else - new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); - if (!new_elements) - return FALSE; - - *elements = new_elements; - *capacity = new_capacity; - return TRUE; + invert_matrix(&mv, &mv); + /* Tests show that singular modelview matrices are used unchanged as normal + * matrices on D3D3 and older. There seems to be no clearly consistent + * behavior on newer D3D versions so always follow older ddraw behavior. */ + for (i = 0; i < 3; ++i) + for (j = 0; j < 3; ++j) + normal_matrix[i * 3 + j] = (&mv._11)[j * 4 + i]; } diff --git a/dll/directx/wine/wined3d/vertexdeclaration.c b/dll/directx/wine/wined3d/vertexdeclaration.c index 82348b40876..e91409f4522 100644 --- a/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/dll/directx/wine/wined3d/vertexdeclaration.c @@ -182,7 +182,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara struct wined3d_device *device, const struct wined3d_vertex_element *elements, UINT element_count, void *parent, const struct wined3d_parent_ops *parent_ops) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_adapter *adapter = device->adapter; unsigned int i; if (TRACE_ON(d3d_decl)) @@ -210,7 +210,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara { struct wined3d_vertex_declaration_element *e = &declaration->elements[i]; - e->format = wined3d_get_format(gl_info, elements[i].format, 0); + e->format = wined3d_get_format(adapter, elements[i].format, 0); e->ffp_valid = declaration_element_valid_ffp(&elements[i]); e->input_slot = elements[i].input_slot; e->offset = elements[i].offset; @@ -226,9 +226,10 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara /* Find the streams used in the declaration. The vertex buffers have * to be loaded when drawing, but filter tesselation pseudo streams. */ - if (e->input_slot >= MAX_STREAMS) continue; + if (e->input_slot >= WINED3D_MAX_STREAMS) + continue; - if (!e->format->gl_vtx_format) + if (!(e->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_VERTEX_ATTRIBUTE)) { FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n", debug_d3dformat(elements[i].format)); @@ -259,11 +260,6 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara heap_free(declaration->elements); return E_FAIL; } - - if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT) - { - if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE; - } } return WINED3D_OK; @@ -298,10 +294,10 @@ HRESULT CDECL wined3d_vertex_declaration_create(struct wined3d_device *device, struct wined3d_fvf_convert_state { - const struct wined3d_gl_info *gl_info; + const struct wined3d_adapter *adapter; struct wined3d_vertex_element *elements; - UINT offset; - UINT idx; + unsigned int offset; + unsigned int idx; }; static void append_decl_element(struct wined3d_fvf_convert_state *state, @@ -322,12 +318,12 @@ static void append_decl_element(struct wined3d_fvf_convert_state *state, elements[idx].usage = usage; elements[idx].usage_idx = usage_idx; - format = wined3d_get_format(state->gl_info, format_id, 0); - state->offset += format->attribute_size; + format = wined3d_get_format(state->adapter, format_id, 0); + state->offset += format->byte_count; ++state->idx; } -static unsigned int convert_fvf_to_declaration(const struct wined3d_gl_info *gl_info, +static unsigned int convert_fvf_to_declaration(const struct wined3d_adapter *adapter, DWORD fvf, struct wined3d_vertex_element **elements) { BOOL has_pos = !!(fvf & WINED3DFVF_POSITION_MASK); @@ -353,7 +349,7 @@ static unsigned int convert_fvf_to_declaration(const struct wined3d_gl_info *gl_ size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal + has_psize + has_diffuse + has_specular + num_textures; - state.gl_info = gl_info; + state.adapter = adapter; if (!(state.elements = heap_calloc(size, sizeof(*state.elements)))) return ~0u; state.offset = 0; @@ -449,8 +445,9 @@ HRESULT CDECL wined3d_vertex_declaration_create_from_fvf(struct wined3d_device * TRACE("device %p, fvf %#x, parent %p, parent_ops %p, declaration %p.\n", device, fvf, parent, parent_ops, declaration); - size = convert_fvf_to_declaration(&device->adapter->gl_info, fvf, &elements); - if (size == ~0U) return E_OUTOFMEMORY; + size = convert_fvf_to_declaration(device->adapter, fvf, &elements); + if (size == ~0u) + return E_OUTOFMEMORY; hr = wined3d_vertex_declaration_create(device, elements, size, parent, parent_ops, declaration); heap_free(elements); diff --git a/dll/directx/wine/wined3d/view.c b/dll/directx/wine/wined3d/view.c index bed39dbc5fc..ec106d2d5a3 100644 --- a/dll/directx/wine/wined3d/view.c +++ b/dll/directx/wine/wined3d/view.c @@ -33,7 +33,7 @@ static BOOL is_stencil_view_format(const struct wined3d_format *format) } static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, - const struct wined3d_view_desc *desc, const struct wined3d_texture *texture) + const struct wined3d_view_desc *desc, const struct wined3d_texture_gl *texture_gl) { static const struct { @@ -64,12 +64,17 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, {GL_TEXTURE_2D_MULTISAMPLE, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY}, {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_2D_MULTISAMPLE}, {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY}, + + {GL_TEXTURE_1D, 0, GL_TEXTURE_1D}, + {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, + {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D}, + {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, }; unsigned int i; for (i = 0; i < ARRAY_SIZE(view_types); ++i) { - if (view_types[i].texture_target != texture->target || view_types[i].view_flags != desc->flags) + if (view_types[i].texture_target != texture_gl->target || view_types[i].view_flags != desc->flags) continue; if (gl_info->supported[view_types[i].extension]) return view_types[i].view_target; @@ -77,17 +82,17 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, FIXME("Extension %#x not supported.\n", view_types[i].extension); } - FIXME("Unhandled view flags %#x for texture target %#x.\n", desc->flags, texture->target); - return texture->target; + FIXME("Unhandled view flags %#x for texture target %#x.\n", desc->flags, texture_gl->target); + return texture_gl->target; } static const struct wined3d_format *validate_resource_view(const struct wined3d_view_desc *desc, struct wined3d_resource *resource, BOOL mip_slice, BOOL allow_srgb_toggle) { - const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info; + const struct wined3d_adapter *adapter = resource->device->adapter; const struct wined3d_format *format; - format = wined3d_get_format(gl_info, desc->format_id, resource->usage); + format = wined3d_get_format(adapter, desc->format_id, resource->bind_flags); if (resource->type == WINED3D_RTYPE_BUFFER && (desc->flags & WINED3D_VIEW_BUFFER_RAW)) { if (format->id != WINED3DFMT_R32_TYPELESS) @@ -96,7 +101,7 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_ return NULL; } - format = wined3d_get_format(gl_info, WINED3DFMT_R32_UINT, resource->usage); + format = wined3d_get_format(adapter, WINED3DFMT_R32_UINT, resource->bind_flags); } if (wined3d_format_is_typeless(format)) @@ -110,7 +115,7 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_ struct wined3d_buffer *buffer = buffer_from_resource(resource); unsigned int buffer_size, element_size; - if (buffer->desc.structure_byte_stride) + if (buffer->structure_byte_stride) { if (desc->format_id != WINED3DFMT_UNKNOWN) { @@ -118,8 +123,8 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_ return NULL; } - format = wined3d_get_format(gl_info, WINED3DFMT_R32_UINT, resource->usage); - element_size = buffer->desc.structure_byte_stride; + format = wined3d_get_format(adapter, WINED3DFMT_R32_UINT, resource->bind_flags); + element_size = buffer->structure_byte_stride; } else { @@ -166,18 +171,22 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_ } static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target, - const struct wined3d_view_desc *desc, struct wined3d_texture *texture, + const struct wined3d_view_desc *desc, struct wined3d_texture_gl *texture_gl, const struct wined3d_format *view_format) { + const struct wined3d_format_gl *view_format_gl; + unsigned int level_idx, layer_idx, layer_count; const struct wined3d_gl_info *gl_info; - unsigned int layer_idx, layer_count; + struct wined3d_context_gl *context_gl; struct wined3d_context *context; GLuint texture_name; + view_format_gl = wined3d_format_gl(view_format); view->target = view_target; - context = context_acquire(texture->resource.device, NULL, 0); - gl_info = context->gl_info; + context = context_acquire(texture_gl->t.resource.device, NULL, 0); + context_gl = wined3d_context_gl(context); + gl_info = context_gl->gl_info; if (!gl_info->supported[ARB_TEXTURE_VIEW]) { @@ -186,23 +195,24 @@ static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target return; } - wined3d_texture_prepare_texture(texture, context, FALSE); - texture_name = wined3d_texture_get_texture_name(texture, context, FALSE); + wined3d_texture_gl_prepare_texture(texture_gl, context_gl, FALSE); + texture_name = wined3d_texture_gl_get_texture_name(texture_gl, context, FALSE); + level_idx = desc->u.texture.level_idx; layer_idx = desc->u.texture.layer_idx; layer_count = desc->u.texture.layer_count; - if (view_target == GL_TEXTURE_3D && (layer_idx || layer_count != 1)) + if (view_target == GL_TEXTURE_3D) { - FIXME("Depth slice (%u-%u) not supported.\n", layer_idx, layer_count); + if (layer_idx || layer_count != wined3d_texture_get_level_depth(&texture_gl->t, level_idx)) + FIXME("Depth slice (%u-%u) not supported.\n", layer_idx, layer_count); layer_idx = 0; layer_count = 1; } gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); - GL_EXTCALL(glTextureView(view->name, view->target, texture_name, view_format->glInternal, - desc->u.texture.level_idx, desc->u.texture.level_count, - layer_idx, layer_count)); - checkGLcall("Create texture view"); + GL_EXTCALL(glTextureView(view->name, view->target, texture_name, view_format_gl->internal, + level_idx, desc->u.texture.level_count, layer_idx, layer_count)); + checkGLcall("create texture view"); if (is_stencil_view_format(view_format)) { @@ -215,10 +225,22 @@ static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target return; } - context_bind_texture(context, view->target, view->name); + wined3d_context_gl_bind_texture(context_gl, view->target, view->name); gl_info->gl_ops.gl.p_glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); gl_info->gl_ops.gl.p_glTexParameteri(view->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); - checkGLcall("Initialize stencil view"); + checkGLcall("initialize stencil view"); + + context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + } + else if (!is_identity_fixup(view_format->color_fixup) && can_use_texture_swizzle(context->d3d_info, view_format)) + { + GLint swizzle[4]; + + wined3d_context_gl_bind_texture(context_gl, view->target, view->name); + wined3d_gl_texture_swizzle_from_color_fixup(swizzle, view_format->color_fixup); + gl_info->gl_ops.gl.p_glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + checkGLcall("set format swizzle"); context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); @@ -231,7 +253,9 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c struct wined3d_buffer *buffer, const struct wined3d_format *view_format, unsigned int offset, unsigned int size) { - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_format_gl *view_format_gl; if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) { @@ -246,22 +270,23 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c return; } + view_format_gl = wined3d_format_gl(view_format); wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); view->target = GL_TEXTURE_BUFFER; gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); - context_bind_texture(context, GL_TEXTURE_BUFFER, view->name); + wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name); if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) { - GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format->glInternal, + GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer->buffer_object, offset, size)); } else { if (offset || size != buffer->resource.size) FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n"); - GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format->glInternal, buffer->buffer_object)); + GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer->buffer_object)); } checkGLcall("Create buffer texture"); @@ -275,8 +300,8 @@ static void get_buffer_view_range(const struct wined3d_buffer *buffer, { if (desc->format_id == WINED3DFMT_UNKNOWN) { - *offset = desc->u.buffer.start_idx * buffer->desc.structure_byte_stride; - *size = desc->u.buffer.count * buffer->desc.structure_byte_stride; + *offset = desc->u.buffer.start_idx * buffer->structure_byte_stride; + *size = desc->u.buffer.count * buffer->structure_byte_stride; } else { @@ -324,25 +349,12 @@ ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *v return refcount; } -static void wined3d_rendertarget_view_destroy_object(void *object) +void wined3d_rendertarget_view_cleanup(struct wined3d_rendertarget_view *view) { - struct wined3d_rendertarget_view *view = object; - struct wined3d_device *device = view->resource->device; - - if (view->gl_view.name) - { - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - context = context_acquire(device, NULL, 0); - gl_info = context->gl_info; - context_gl_resource_released(device, view->gl_view.name, FALSE); - gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->gl_view.name); - checkGLcall("glDeleteTextures"); - context_release(context); - } - - heap_free(view); + /* Call wined3d_object_destroyed() before releasing the resource, + * since releasing the resource may end up destroying the parent. */ + view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_resource_decref(view->resource); } ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) @@ -352,16 +364,7 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v TRACE("%p decreasing refcount to %u.\n", view, refcount); if (!refcount) - { - struct wined3d_resource *resource = view->resource; - struct wined3d_device *device = resource->device; - - /* Call wined3d_object_destroyed() before releasing the resource, - * since releasing the resource may end up destroying the parent. */ - view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_cs_destroy_object(device->cs, wined3d_rendertarget_view_destroy_object, view); - wined3d_resource_decref(resource); - } + view->resource->device->adapter->adapter_ops->adapter_destroy_rendertarget_view(view); return refcount; } @@ -424,13 +427,13 @@ void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarg } else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { - const struct wined3d_swapchain *swapchain = context->swapchain; + const struct wined3d_swapchain_desc *desc = &context->swapchain->state.desc; /* The drawable size of a backbuffer / aux buffer offscreen target is * the size of the current context's drawable, which is the size of * the back buffer of the swapchain the active context belongs to. */ - *width = swapchain->desc.backbuffer_width; - *height = swapchain->desc.backbuffer_height; + *width = desc->backbuffer_width; + *height = desc->backbuffer_height; } else { @@ -507,11 +510,11 @@ void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_v wined3d_view_invalidate_location(view->resource, &view->desc, location); } -static void wined3d_render_target_view_cs_init(void *object) +static void wined3d_render_target_view_gl_cs_init(void *object) { - struct wined3d_rendertarget_view *view = object; - struct wined3d_resource *resource = view->resource; - const struct wined3d_view_desc *desc = &view->desc; + struct wined3d_rendertarget_view_gl *view_gl = object; + struct wined3d_resource *resource = view_gl->v.resource; + const struct wined3d_view_desc *desc = &view_gl->v.desc; if (resource->type == WINED3D_RTYPE_BUFFER) { @@ -519,30 +522,34 @@ static void wined3d_render_target_view_cs_init(void *object) } else { - struct wined3d_texture *texture = texture_from_resource(resource); + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource)); unsigned int depth_or_layer_count; if (resource->type == WINED3D_RTYPE_TEXTURE_3D) - depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); + depth_or_layer_count = wined3d_texture_get_level_depth(&texture_gl->t, desc->u.texture.level_idx); else - depth_or_layer_count = texture->layer_count; + depth_or_layer_count = texture_gl->t.layer_count; - if (resource->format->id != view->format->id - || (view->layer_count != 1 && view->layer_count != depth_or_layer_count)) + if (resource->format->id != view_gl->v.format->id + || (view_gl->v.layer_count != 1 && view_gl->v.layer_count != depth_or_layer_count)) { - if (resource->format->gl_view_class != view->format->gl_view_class) + GLenum resource_class, view_class; + + resource_class = wined3d_format_gl(resource->format)->view_class; + view_class = wined3d_format_gl(view_gl->v.format)->view_class; + if (resource_class != view_class) { FIXME("Render target view not supported, resource format %s, view format %s.\n", - debug_d3dformat(resource->format->id), debug_d3dformat(view->format->id)); + debug_d3dformat(resource->format->id), debug_d3dformat(view_gl->v.format->id)); return; } - if (texture->swapchain && texture->swapchain->desc.backbuffer_count > 1) + if (texture_gl->t.swapchain && texture_gl->t.swapchain->state.desc.backbuffer_count > 1) { FIXME("Swapchain views not supported.\n"); return; } - create_texture_view(&view->gl_view, texture->target, desc, texture, view->format); + create_texture_view(&view_gl->gl_view, texture_gl->target, desc, texture_gl, view_gl->v.format); } } } @@ -590,37 +597,59 @@ static HRESULT wined3d_rendertarget_view_init(struct wined3d_rendertarget_view * wined3d_resource_incref(view->resource = resource); - wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_cs_init, view); - return WINED3D_OK; } -HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc, - struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_rendertarget_view **view) +HRESULT wined3d_rendertarget_view_no3d_init(struct wined3d_rendertarget_view *view_no3d, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) { - struct wined3d_rendertarget_view *object; - HRESULT hr; + TRACE("view_no3d %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_no3d, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); + + return wined3d_rendertarget_view_init(view_no3d, desc, resource, parent, parent_ops); +} - TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", - desc, resource, parent, parent_ops, view); +HRESULT wined3d_rendertarget_view_gl_init(struct wined3d_rendertarget_view_gl *view_gl, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + HRESULT hr; - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; + TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); - if (FAILED(hr = wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops))) - { - heap_free(object); - WARN("Failed to initialise view, hr %#x.\n", hr); + if (FAILED(hr = wined3d_rendertarget_view_init(&view_gl->v, desc, resource, parent, parent_ops))) return hr; - } - TRACE("Created render target view %p.\n", object); - *view = object; + wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_gl_cs_init, view_gl); return hr; } +HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_view_vk *view_vk, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); + + return wined3d_rendertarget_view_init(&view_vk->v, desc, resource, parent, parent_ops); +} + +HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_rendertarget_view **view) +{ + const struct wined3d_adapter_ops *adapter_ops; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + adapter_ops = resource->device->adapter->adapter_ops; + return adapter_ops->adapter_create_rendertarget_view(desc, resource, parent, parent_ops, view); +} + HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture, unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view) @@ -649,23 +678,12 @@ ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_v return refcount; } -static void wined3d_shader_resource_view_destroy_object(void *object) +void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view) { - struct wined3d_shader_resource_view *view = object; - - if (view->gl_view.name) - { - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - context = context_acquire(view->resource->device, NULL, 0); - gl_info = context->gl_info; - gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->gl_view.name); - checkGLcall("glDeleteTextures"); - context_release(context); - } - - heap_free(view); + /* Call wined3d_object_destroyed() before releasing the resource, + * since releasing the resource may end up destroying the parent. */ + view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_resource_decref(view->resource); } ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view) @@ -675,16 +693,7 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v TRACE("%p decreasing refcount to %u.\n", view, refcount); if (!refcount) - { - struct wined3d_resource *resource = view->resource; - struct wined3d_device *device = resource->device; - - /* Call wined3d_object_destroyed() before releasing the resource, - * since releasing the resource may end up destroying the parent. */ - view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_cs_destroy_object(device->cs, wined3d_shader_resource_view_destroy_object, view); - wined3d_resource_decref(resource); - } + view->resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view); return refcount; } @@ -696,18 +705,18 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader return view->parent; } -static void wined3d_shader_resource_view_cs_init(void *object) +static void wined3d_shader_resource_view_gl_cs_init(void *object) { - struct wined3d_shader_resource_view *view = object; - struct wined3d_resource *resource = view->resource; + struct wined3d_shader_resource_view_gl *view_gl = object; + struct wined3d_resource *resource = view_gl->v.resource; const struct wined3d_format *view_format; const struct wined3d_gl_info *gl_info; const struct wined3d_view_desc *desc; GLenum view_target; - view_format = view->format; + view_format = view_gl->v.format; gl_info = &resource->device->adapter->gl_info; - desc = &view->desc; + desc = &view_gl->v.desc; if (resource->type == WINED3D_RTYPE_BUFFER) { @@ -715,34 +724,37 @@ static void wined3d_shader_resource_view_cs_init(void *object) struct wined3d_context *context; context = context_acquire(resource->device, NULL, 0); - create_buffer_view(&view->gl_view, context, desc, buffer, view_format); + create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format); context_release(context); } else { - struct wined3d_texture *texture = texture_from_resource(resource); + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource)); + GLenum resource_class, view_class; - view_target = get_texture_view_target(gl_info, desc, texture); + resource_class = wined3d_format_gl(resource->format)->view_class; + view_class = wined3d_format_gl(view_format)->view_class; + view_target = get_texture_view_target(gl_info, desc, texture_gl); - if (resource->format->id == view_format->id && texture->target == view_target - && !desc->u.texture.level_idx && desc->u.texture.level_count == texture->level_count - && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture->layer_count + if (resource->format->id == view_format->id && texture_gl->target == view_target + && !desc->u.texture.level_idx && desc->u.texture.level_count == texture_gl->t.level_count + && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture_gl->t.layer_count && !is_stencil_view_format(view_format)) { TRACE("Creating identity shader resource view.\n"); } - else if (texture->swapchain && texture->swapchain->desc.backbuffer_count > 1) + else if (texture_gl->t.swapchain && texture_gl->t.swapchain->state.desc.backbuffer_count > 1) { FIXME("Swapchain shader resource views not supported.\n"); } else if (resource->format->typeless_id == view_format->typeless_id - && resource->format->gl_view_class == view_format->gl_view_class) + && resource_class == view_class) { - create_texture_view(&view->gl_view, view_target, desc, texture, view_format); + create_texture_view(&view_gl->gl_view, view_target, desc, texture_gl, view_format); } else if (wined3d_format_is_depth_view(resource->format->id, view_format->id)) { - create_texture_view(&view->gl_view, view_target, desc, texture, resource->format); + create_texture_view(&view_gl->gl_view, view_target, desc, texture_gl, resource->format); } else { @@ -764,6 +776,8 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_ view->parent = parent; view->parent_ops = parent_ops; + if (!(resource->bind_flags & WINED3D_BIND_SHADER_RESOURCE)) + return E_INVALIDARG; if (!(view->format = validate_resource_view(desc, resource, FALSE, FALSE))) return E_INVALIDARG; view->desc = *desc; @@ -773,86 +787,101 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_ #if defined(STAGING_CSMT) wined3d_resource_acquire(resource); #endif /* STAGING_CSMT */ - wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view); return WINED3D_OK; } -HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc, - struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_shader_resource_view **view) +HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) { - struct wined3d_shader_resource_view *object; HRESULT hr; - TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", - desc, resource, parent, parent_ops, view); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; + TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); - if (FAILED(hr = wined3d_shader_resource_view_init(object, desc, resource, parent, parent_ops))) - { - heap_free(object); - WARN("Failed to initialise view, hr %#x.\n", hr); + if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops))) return hr; - } - TRACE("Created shader resource view %p.\n", object); - *view = object; + wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl); - return WINED3D_OK; + return hr; } -void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view, - unsigned int unit, struct wined3d_sampler *sampler, struct wined3d_context *context) +HRESULT wined3d_shader_resource_view_vk_init(struct wined3d_shader_resource_view_vk *view_vk, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) { - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_texture *texture; + TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); + + return wined3d_shader_resource_view_init(&view_vk->v, desc, resource, parent, parent_ops); +} + +HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view) +{ + const struct wined3d_adapter_ops *adapter_ops; - context_active_texture(context, gl_info, unit); + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); - if (view->gl_view.name) + adapter_ops = resource->device->adapter->adapter_ops; + return adapter_ops->adapter_create_shader_resource_view(desc, resource, parent, parent_ops, view); +} + +void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl *view_gl, + unsigned int unit, struct wined3d_sampler_gl *sampler_gl, struct wined3d_context_gl *context_gl) +{ + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + struct wined3d_texture_gl *texture_gl; + + wined3d_context_gl_active_texture(context_gl, gl_info, unit); + + if (view_gl->gl_view.name) { - context_bind_texture(context, view->gl_view.target, view->gl_view.name); - wined3d_sampler_bind(sampler, unit, NULL, context); + wined3d_context_gl_bind_texture(context_gl, view_gl->gl_view.target, view_gl->gl_view.name); + wined3d_sampler_gl_bind(sampler_gl, unit, NULL, context_gl); return; } - if (view->resource->type == WINED3D_RTYPE_BUFFER) + if (view_gl->v.resource->type == WINED3D_RTYPE_BUFFER) { FIXME("Buffer shader resources not supported.\n"); return; } - texture = wined3d_texture_from_resource(view->resource); - wined3d_texture_bind(texture, context, FALSE); - wined3d_sampler_bind(sampler, unit, texture, context); + texture_gl = wined3d_texture_gl(wined3d_texture_from_resource(view_gl->v.resource)); + wined3d_texture_gl_bind(texture_gl, context_gl, FALSE); + wined3d_sampler_gl_bind(sampler_gl, unit, texture_gl, context_gl); } /* Context activation is done by the caller. */ -static void shader_resource_view_bind_and_dirtify(struct wined3d_shader_resource_view *view, - struct wined3d_context *context) +static void shader_resource_view_gl_bind_and_dirtify(struct wined3d_shader_resource_view_gl *view_gl, + struct wined3d_context_gl *context_gl) { - if (context->active_texture < ARRAY_SIZE(context->rev_tex_unit_map)) + if (context_gl->active_texture < ARRAY_SIZE(context_gl->rev_tex_unit_map)) { - DWORD active_sampler = context->rev_tex_unit_map[context->active_texture]; + unsigned int active_sampler = context_gl->rev_tex_unit_map[context_gl->active_texture]; if (active_sampler != WINED3D_UNMAPPED_STAGE) - context_invalidate_state(context, STATE_SAMPLER(active_sampler)); + context_invalidate_state(&context_gl->c, STATE_SAMPLER(active_sampler)); } /* FIXME: Ideally we'd only do this when touching a binding that's used by * a shader. */ - context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); - context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + context_invalidate_compute_state(&context_gl->c, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); - context_bind_texture(context, view->gl_view.target, view->gl_view.name); + wined3d_context_gl_bind_texture(context_gl, view_gl->gl_view.target, view_gl->gl_view.name); } void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *view) { - struct wined3d_texture *texture = texture_from_resource(view->resource); + struct wined3d_shader_resource_view_gl *view_gl = wined3d_shader_resource_view_gl(view); unsigned int i, j, layer_count, level_count, base_level, max_level; const struct wined3d_gl_info *gl_info; + struct wined3d_texture_gl *texture_gl; + struct wined3d_context_gl *context_gl; struct wined3d_context *context; struct gl_texture *gl_tex; DWORD location; @@ -860,55 +889,58 @@ void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view * TRACE("view %p.\n", view); - context = context_acquire(view->resource->device, NULL, 0); - gl_info = context->gl_info; - layer_count = view->desc.u.texture.layer_count; - level_count = view->desc.u.texture.level_count; - base_level = view->desc.u.texture.level_idx; + context = context_acquire(view_gl->v.resource->device, NULL, 0); + context_gl = wined3d_context_gl(context); + gl_info = context_gl->gl_info; + layer_count = view_gl->v.desc.u.texture.layer_count; + level_count = view_gl->v.desc.u.texture.level_count; + base_level = view_gl->v.desc.u.texture.level_idx; max_level = base_level + level_count - 1; - srgb = !!(texture->flags & WINED3D_TEXTURE_IS_SRGB); + texture_gl = wined3d_texture_gl(texture_from_resource(view_gl->v.resource)); + srgb = !!(texture_gl->t.flags & WINED3D_TEXTURE_IS_SRGB); location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; for (i = 0; i < layer_count; ++i) - wined3d_texture_load_location(texture, i * level_count + base_level, context, location); + wined3d_texture_load_location(&texture_gl->t, i * level_count + base_level, context, location); - if (view->gl_view.name) + if (view_gl->gl_view.name) { - shader_resource_view_bind_and_dirtify(view, context); + shader_resource_view_gl_bind_and_dirtify(view_gl, context_gl); } else { - wined3d_texture_bind_and_dirtify(texture, context, srgb); - gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level); - gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, max_level); + wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, srgb); + gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_BASE_LEVEL, base_level); + gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_MAX_LEVEL, max_level); } if (gl_info->supported[ARB_SAMPLER_OBJECTS]) - GL_EXTCALL(glBindSampler(context->active_texture, 0)); - gl_tex = wined3d_texture_get_gl_texture(texture, srgb); + GL_EXTCALL(glBindSampler(context_gl->active_texture, 0)); + gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, srgb); if (context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) { - gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); + gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, + GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); gl_tex->sampler_desc.srgb_decode = FALSE; } - gl_info->fbo_ops.glGenerateMipmap(texture->target); + gl_info->fbo_ops.glGenerateMipmap(texture_gl->target); checkGLcall("glGenerateMipMap()"); for (i = 0; i < layer_count; ++i) { for (j = base_level + 1; j <= max_level; ++j) { - wined3d_texture_validate_location(texture, i * level_count + j, location); - wined3d_texture_invalidate_location(texture, i * level_count + j, ~location); + wined3d_texture_validate_location(&texture_gl->t, i * level_count + j, location); + wined3d_texture_invalidate_location(&texture_gl->t, i * level_count + j, ~location); } } - if (!view->gl_view.name) + if (!view_gl->gl_view.name) { gl_tex->base_level = base_level; - gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); + gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, + GL_TEXTURE_MAX_LEVEL, texture_gl->t.level_count - 1); } context_release(context); @@ -945,26 +977,12 @@ ULONG CDECL wined3d_unordered_access_view_incref(struct wined3d_unordered_access return refcount; } -static void wined3d_unordered_access_view_destroy_object(void *object) +void wined3d_unordered_access_view_cleanup(struct wined3d_unordered_access_view *view) { - struct wined3d_unordered_access_view *view = object; - - if (view->gl_view.name || view->counter_bo) - { - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - context = context_acquire(view->resource->device, NULL, 0); - gl_info = context->gl_info; - if (view->gl_view.name) - gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->gl_view.name); - if (view->counter_bo) - GL_EXTCALL(glDeleteBuffers(1, &view->counter_bo)); - checkGLcall("delete resources"); - context_release(context); - } - - heap_free(view); + /* Call wined3d_object_destroyed() before releasing the resource, + * since releasing the resource may end up destroying the parent. */ + view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_resource_decref(view->resource); } ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view) @@ -974,16 +992,7 @@ ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access TRACE("%p decreasing refcount to %u.\n", view, refcount); if (!refcount) - { - struct wined3d_resource *resource = view->resource; - struct wined3d_device *device = resource->device; - - /* Call wined3d_object_destroyed() before releasing the resource, - * since releasing the resource may end up destroying the parent. */ - view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_cs_destroy_object(device->cs, wined3d_unordered_access_view_destroy_object, view); - wined3d_resource_decref(resource); - } + view->resource->device->adapter->adapter_ops->adapter_destroy_unordered_access_view(view); return refcount; } @@ -1001,16 +1010,16 @@ void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_ wined3d_view_invalidate_location(view->resource, &view->desc, location); } -void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view, - const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) +void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access_view_gl *view_gl, + const struct wined3d_uvec4 *clear_value, struct wined3d_context_gl *context_gl) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_format *format; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + const struct wined3d_format_gl *format; + struct wined3d_buffer_gl *buffer_gl; struct wined3d_resource *resource; - struct wined3d_buffer *buffer; unsigned int offset, size; - resource = view->resource; + resource = view_gl->v.resource; if (resource->type != WINED3D_RTYPE_BUFFER) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); @@ -1023,38 +1032,39 @@ void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_vi return; } - format = view->format; - if (format->id != WINED3DFMT_R32_UINT && format->id != WINED3DFMT_R32_SINT - && format->id != WINED3DFMT_R32G32B32A32_UINT - && format->id != WINED3DFMT_R32G32B32A32_SINT) + format = wined3d_format_gl(view_gl->v.format); + if (format->f.id != WINED3DFMT_R32_UINT && format->f.id != WINED3DFMT_R32_SINT + && format->f.id != WINED3DFMT_R32G32B32A32_UINT + && format->f.id != WINED3DFMT_R32G32B32A32_SINT) { - FIXME("Not implemented for format %s.\n", debug_d3dformat(format->id)); + FIXME("Not implemented for format %s.\n", debug_d3dformat(format->f.id)); return; } - buffer = buffer_from_resource(resource); - wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); - wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER); + buffer_gl = wined3d_buffer_gl(buffer_from_resource(resource)); + wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER); + wined3d_unordered_access_view_invalidate_location(&view_gl->v, ~WINED3D_LOCATION_BUFFER); - get_buffer_view_range(buffer, &view->desc, format, &offset, &size); - context_bind_bo(context, buffer->buffer_type_hint, buffer->buffer_object); - GL_EXTCALL(glClearBufferSubData(buffer->buffer_type_hint, format->glInternal, - offset, size, format->glFormat, format->glType, clear_value)); + get_buffer_view_range(&buffer_gl->b, &view_gl->v.desc, &format->f, &offset, &size); + wined3d_context_gl_bind_bo(context_gl, buffer_gl->buffer_type_hint, buffer_gl->b.buffer_object); + GL_EXTCALL(glClearBufferSubData(buffer_gl->buffer_type_hint, format->internal, + offset, size, format->format, format->type, clear_value)); checkGLcall("clear unordered access view"); } void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view, unsigned int value) { + struct wined3d_unordered_access_view_gl *view_gl = wined3d_unordered_access_view_gl(view); const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - if (!view->counter_bo) + if (!view_gl->counter_bo) return; - context = context_acquire(view->resource->device, NULL, 0); - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view->counter_bo)); + context = context_acquire(view_gl->v.resource->device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; + GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view_gl->counter_bo)); GL_EXTCALL(glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(value), &value)); checkGLcall("set atomic counter"); context_release(context); @@ -1063,29 +1073,31 @@ void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_v void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view, struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context) { + struct wined3d_unordered_access_view_gl *view_gl = wined3d_unordered_access_view_gl(view); + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); struct wined3d_bo_address dst, src; DWORD dst_location; - if (!view->counter_bo) + if (!view_gl->counter_bo) return; dst_location = wined3d_buffer_get_memory(buffer, &dst, buffer->locations); dst.addr += offset; - src.buffer_object = view->counter_bo; + src.buffer_object = view_gl->counter_bo; src.addr = NULL; - context_copy_bo_address(context, &dst, buffer->buffer_type_hint, + wined3d_context_gl_copy_bo_address(context_gl, &dst, wined3d_buffer_gl(buffer)->buffer_type_hint, &src, GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint)); wined3d_buffer_invalidate_location(buffer, ~dst_location); } -static void wined3d_unordered_access_view_cs_init(void *object) +static void wined3d_unordered_access_view_gl_cs_init(void *object) { - struct wined3d_unordered_access_view *view = object; - struct wined3d_resource *resource = view->resource; - struct wined3d_view_desc *desc = &view->desc; + struct wined3d_unordered_access_view_gl *view_gl = object; + struct wined3d_resource *resource = view_gl->v.resource; + struct wined3d_view_desc *desc = &view_gl->v.desc; const struct wined3d_gl_info *gl_info; gl_info = &resource->device->adapter->gl_info; @@ -1096,13 +1108,13 @@ static void wined3d_unordered_access_view_cs_init(void *object) struct wined3d_context *context; context = context_acquire(resource->device, NULL, 0); - gl_info = context->gl_info; - create_buffer_view(&view->gl_view, context, desc, buffer, view->format); + gl_info = wined3d_context_gl(context)->gl_info; + create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_gl->v.format); if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND)) { static const GLuint initial_value = 0; - GL_EXTCALL(glGenBuffers(1, &view->counter_bo)); - GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view->counter_bo)); + GL_EXTCALL(glGenBuffers(1, &view_gl->counter_bo)); + GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view_gl->counter_bo)); GL_EXTCALL(glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(initial_value), &initial_value, GL_STATIC_DRAW)); checkGLcall("create atomic counter buffer"); @@ -1111,18 +1123,18 @@ static void wined3d_unordered_access_view_cs_init(void *object) } else { - struct wined3d_texture *texture = texture_from_resource(resource); + struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource)); unsigned int depth_or_layer_count; if (resource->type == WINED3D_RTYPE_TEXTURE_3D) - depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); + depth_or_layer_count = wined3d_texture_get_level_depth(&texture_gl->t, desc->u.texture.level_idx); else - depth_or_layer_count = texture->layer_count; + depth_or_layer_count = texture_gl->t.layer_count; if (desc->u.texture.layer_idx || desc->u.texture.layer_count != depth_or_layer_count) { - create_texture_view(&view->gl_view, get_texture_view_target(gl_info, desc, texture), - desc, texture, view->format); + create_texture_view(&view_gl->gl_view, get_texture_view_target(gl_info, desc, texture_gl), + desc, texture_gl, view_gl->v.format); } } #if defined(STAGING_CSMT) @@ -1139,6 +1151,8 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces view->parent = parent; view->parent_ops = parent_ops; + if (!(resource->bind_flags & WINED3D_BIND_UNORDERED_ACCESS)) + return E_INVALIDARG; if (!(view->format = validate_resource_view(desc, resource, TRUE, FALSE))) return E_INVALIDARG; view->desc = *desc; @@ -1148,33 +1162,46 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces #if defined(STAGING_CSMT) wined3d_resource_acquire(resource); #endif /* STAGING_CSMT */ - wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view); return WINED3D_OK; } -HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_view_desc *desc, - struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_unordered_access_view **view) +HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) { - struct wined3d_unordered_access_view *object; HRESULT hr; - TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", - desc, resource, parent, parent_ops, view); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; + TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); - if (FAILED(hr = wined3d_unordered_access_view_init(object, desc, resource, parent, parent_ops))) - { - heap_free(object); - WARN("Failed to initialise view, hr %#x.\n", hr); + if (FAILED(hr = wined3d_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops))) return hr; - } - TRACE("Created unordered access view %p.\n", object); - *view = object; + wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl); - return WINED3D_OK; + return hr; +} + +HRESULT wined3d_unordered_access_view_vk_init(struct wined3d_unordered_access_view_vk *view_vk, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n", + view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops); + + return wined3d_unordered_access_view_init(&view_vk->v, desc, resource, parent, parent_ops); +} + +HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view) +{ + const struct wined3d_adapter_ops *adapter_ops; + + TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", + wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); + + adapter_ops = resource->device->adapter->adapter_ops; + return adapter_ops->adapter_create_unordered_access_view(desc, resource, parent, parent_ops, view); } diff --git a/dll/directx/wine/wined3d/wined3d.spec b/dll/directx/wine/wined3d/wined3d.spec index 3022e20edbe..9becaef2d18 100644 --- a/dll/directx/wine/wined3d/wined3d.spec +++ b/dll/directx/wine/wined3d/wined3d.spec @@ -3,7 +3,7 @@ @ cdecl wined3d_calculate_format_pitch(ptr long long long) @ cdecl wined3d_check_depth_stencil_match(ptr long long long long long) -@ cdecl wined3d_check_device_format(ptr long long long long long long) +@ cdecl wined3d_check_device_format(ptr long long long long long long long) @ cdecl wined3d_check_device_format_conversion(ptr long long long long) @ cdecl wined3d_check_device_multisample_type(ptr long long long long long ptr) @ cdecl wined3d_check_device_type(ptr long long long long long) @@ -20,7 +20,9 @@ @ cdecl wined3d_get_output_desc(ptr long ptr) @ cdecl wined3d_incref(ptr) @ cdecl wined3d_register_software_device(ptr ptr) +@ cdecl wined3d_register_window(ptr ptr ptr long) @ cdecl wined3d_set_adapter_display_mode(ptr long ptr) +@ cdecl wined3d_unregister_windows(ptr) @ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_blend_state_decref(ptr) @@ -35,14 +37,14 @@ @ cdecl wined3d_device_acquire_focus_window(ptr ptr) @ cdecl wined3d_device_begin_scene(ptr) -@ cdecl wined3d_device_begin_stateblock(ptr) +@ cdecl wined3d_device_begin_stateblock(ptr ptr) @ cdecl wined3d_device_clear(ptr long ptr long ptr float long) @ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long) @ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr) @ cdecl wined3d_device_copy_resource(ptr ptr ptr) -@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr) +@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr long) @ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr) -@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr) +@ cdecl wined3d_device_create(ptr long long ptr long long ptr long ptr ptr) @ cdecl wined3d_device_decref(ptr) @ cdecl wined3d_device_dispatch_compute(ptr long long long) @ cdecl wined3d_device_dispatch_compute_indirect(ptr ptr long) @@ -53,16 +55,16 @@ @ cdecl wined3d_device_draw_primitive_instanced(ptr long long long long) @ cdecl wined3d_device_draw_primitive_instanced_indirect(ptr ptr long) @ cdecl wined3d_device_end_scene(ptr) -@ cdecl wined3d_device_end_stateblock(ptr ptr) +@ cdecl wined3d_device_end_stateblock(ptr) @ cdecl wined3d_device_evict_managed_resources(ptr) @ cdecl wined3d_device_get_available_texture_mem(ptr) @ cdecl wined3d_device_get_base_vertex_index(ptr) -@ cdecl wined3d_device_get_blend_state(ptr) +@ cdecl wined3d_device_get_blend_state(ptr ptr) @ cdecl wined3d_device_get_clip_plane(ptr long ptr) @ cdecl wined3d_device_get_clip_status(ptr ptr) @ cdecl wined3d_device_get_compute_shader(ptr) +@ cdecl wined3d_device_get_constant_buffer(ptr long long) @ cdecl wined3d_device_get_creation_parameters(ptr ptr) -@ cdecl wined3d_device_get_cs_cb(ptr long) @ cdecl wined3d_device_get_cs_resource_view(ptr long) @ cdecl wined3d_device_get_cs_sampler(ptr long) @ cdecl wined3d_device_get_cs_uav(ptr long) @@ -70,15 +72,13 @@ @ cdecl wined3d_device_get_device_caps(ptr ptr) @ cdecl wined3d_device_get_display_mode(ptr long ptr ptr) @ cdecl wined3d_device_get_domain_shader(ptr) -@ cdecl wined3d_device_get_ds_cb(ptr long) @ cdecl wined3d_device_get_ds_resource_view(ptr long) @ cdecl wined3d_device_get_ds_sampler(ptr long) +@ cdecl wined3d_device_get_feature_level(ptr) @ cdecl wined3d_device_get_gamma_ramp(ptr long ptr) @ cdecl wined3d_device_get_geometry_shader(ptr) -@ cdecl wined3d_device_get_gs_cb(ptr long) @ cdecl wined3d_device_get_gs_resource_view(ptr long) @ cdecl wined3d_device_get_gs_sampler(ptr long) -@ cdecl wined3d_device_get_hs_cb(ptr long) @ cdecl wined3d_device_get_hs_resource_view(ptr long) @ cdecl wined3d_device_get_hs_sampler(ptr long) @ cdecl wined3d_device_get_hull_shader(ptr) @@ -86,11 +86,11 @@ @ cdecl wined3d_device_get_light(ptr long ptr) @ cdecl wined3d_device_get_light_enable(ptr long ptr) @ cdecl wined3d_device_get_material(ptr ptr) +@ cdecl wined3d_device_get_max_frame_latency(ptr) @ cdecl wined3d_device_get_npatch_mode(ptr) @ cdecl wined3d_device_get_pixel_shader(ptr) @ cdecl wined3d_device_get_predication(ptr ptr) @ cdecl wined3d_device_get_primitive_type(ptr ptr ptr) -@ cdecl wined3d_device_get_ps_cb(ptr long) @ cdecl wined3d_device_get_ps_consts_b(ptr long long ptr) @ cdecl wined3d_device_get_ps_consts_f(ptr long long ptr) @ cdecl wined3d_device_get_ps_consts_i(ptr long long ptr) @@ -101,7 +101,7 @@ @ cdecl wined3d_device_get_render_state(ptr long) @ cdecl wined3d_device_get_rendertarget_view(ptr long) @ cdecl wined3d_device_get_sampler_state(ptr long long) -@ cdecl wined3d_device_get_scissor_rect(ptr ptr) +@ cdecl wined3d_device_get_scissor_rects(ptr ptr ptr) @ cdecl wined3d_device_get_software_vertex_processing(ptr) @ cdecl wined3d_device_get_stream_output(ptr long ptr) @ cdecl wined3d_device_get_stream_source(ptr long ptr ptr ptr) @@ -114,8 +114,7 @@ @ cdecl wined3d_device_get_unordered_access_view(ptr long) @ cdecl wined3d_device_get_vertex_declaration(ptr) @ cdecl wined3d_device_get_vertex_shader(ptr) -@ cdecl wined3d_device_get_viewport(ptr ptr) -@ cdecl wined3d_device_get_vs_cb(ptr long) +@ cdecl wined3d_device_get_viewports(ptr ptr ptr) @ cdecl wined3d_device_get_vs_consts_b(ptr long long ptr) @ cdecl wined3d_device_get_vs_consts_f(ptr long long ptr) @ cdecl wined3d_device_get_vs_consts_i(ptr long long ptr) @@ -123,20 +122,17 @@ @ cdecl wined3d_device_get_vs_sampler(ptr long) @ cdecl wined3d_device_get_wined3d(ptr) @ cdecl wined3d_device_incref(ptr) -@ cdecl wined3d_device_init_3d(ptr ptr) -@ cdecl wined3d_device_init_gdi(ptr ptr) @ cdecl wined3d_device_multiply_transform(ptr long ptr) @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long) @ cdecl wined3d_device_release_focus_window(ptr) @ cdecl wined3d_device_reset(ptr ptr ptr ptr long) @ cdecl wined3d_device_resolve_sub_resource(ptr ptr long ptr long long) -@ cdecl wined3d_device_restore_fullscreen_window(ptr ptr ptr) @ cdecl wined3d_device_set_base_vertex_index(ptr long) -@ cdecl wined3d_device_set_blend_state(ptr ptr) +@ cdecl wined3d_device_set_blend_state(ptr ptr ptr) @ cdecl wined3d_device_set_clip_plane(ptr long ptr) @ cdecl wined3d_device_set_clip_status(ptr ptr) @ cdecl wined3d_device_set_compute_shader(ptr ptr) -@ cdecl wined3d_device_set_cs_cb(ptr long ptr) +@ cdecl wined3d_device_set_constant_buffer(ptr long long ptr) @ cdecl wined3d_device_set_cs_resource_view(ptr long ptr) @ cdecl wined3d_device_set_cs_sampler(ptr long ptr) @ cdecl wined3d_device_set_cs_uav(ptr long ptr long) @@ -145,15 +141,12 @@ @ cdecl wined3d_device_set_depth_stencil_view(ptr ptr) @ cdecl wined3d_device_set_dialog_box_mode(ptr long) @ cdecl wined3d_device_set_domain_shader(ptr ptr) -@ cdecl wined3d_device_set_ds_cb(ptr long ptr) @ cdecl wined3d_device_set_ds_resource_view(ptr long ptr) @ cdecl wined3d_device_set_ds_sampler(ptr long ptr) @ cdecl wined3d_device_set_gamma_ramp(ptr long long ptr) @ cdecl wined3d_device_set_geometry_shader(ptr ptr) -@ cdecl wined3d_device_set_gs_cb(ptr long ptr) @ cdecl wined3d_device_set_gs_resource_view(ptr long ptr) @ cdecl wined3d_device_set_gs_sampler(ptr long ptr) -@ cdecl wined3d_device_set_hs_cb(ptr long ptr) @ cdecl wined3d_device_set_hs_resource_view(ptr long ptr) @ cdecl wined3d_device_set_hs_sampler(ptr long ptr) @ cdecl wined3d_device_set_hull_shader(ptr ptr) @@ -161,12 +154,12 @@ @ cdecl wined3d_device_set_light(ptr long ptr) @ cdecl wined3d_device_set_light_enable(ptr long long) @ cdecl wined3d_device_set_material(ptr ptr) +@ cdecl wined3d_device_set_max_frame_latency(ptr long) @ cdecl wined3d_device_set_multithreaded(ptr) @ cdecl wined3d_device_set_npatch_mode(ptr float) @ cdecl wined3d_device_set_pixel_shader(ptr ptr) @ cdecl wined3d_device_set_predication(ptr ptr long) @ cdecl wined3d_device_set_primitive_type(ptr long long) -@ cdecl wined3d_device_set_ps_cb(ptr long ptr) @ cdecl wined3d_device_set_ps_consts_b(ptr long long ptr) @ cdecl wined3d_device_set_ps_consts_f(ptr long long ptr) @ cdecl wined3d_device_set_ps_consts_i(ptr long long ptr) @@ -176,7 +169,7 @@ @ cdecl wined3d_device_set_render_state(ptr long long) @ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long) @ cdecl wined3d_device_set_sampler_state(ptr long long long) -@ cdecl wined3d_device_set_scissor_rect(ptr ptr) +@ cdecl wined3d_device_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_set_software_vertex_processing(ptr long) @ cdecl wined3d_device_set_stream_output(ptr long ptr long) @ cdecl wined3d_device_set_stream_source(ptr long ptr long long) @@ -187,18 +180,14 @@ @ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long) @ cdecl wined3d_device_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_set_vertex_shader(ptr ptr) -@ cdecl wined3d_device_set_viewport(ptr ptr) -@ cdecl wined3d_device_set_vs_cb(ptr long ptr) +@ cdecl wined3d_device_set_viewports(ptr long ptr) @ cdecl wined3d_device_set_vs_consts_b(ptr long long ptr) @ cdecl wined3d_device_set_vs_consts_f(ptr long long ptr) @ cdecl wined3d_device_set_vs_consts_i(ptr long long ptr) @ cdecl wined3d_device_set_vs_resource_view(ptr long ptr) @ cdecl wined3d_device_set_vs_sampler(ptr long ptr) -@ cdecl wined3d_device_setup_fullscreen_window(ptr ptr long long) @ cdecl wined3d_device_show_cursor(ptr long) -@ cdecl wined3d_device_uninit_3d(ptr) -@ cdecl wined3d_device_uninit_gdi(ptr) -@ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long) +@ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long long) @ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr) @@ -271,8 +260,17 @@ @ cdecl wined3d_stateblock_create(ptr long ptr) @ cdecl wined3d_stateblock_decref(ptr) @ cdecl wined3d_stateblock_incref(ptr) - -@ cdecl wined3d_strictdrawing_set(long) +@ cdecl wined3d_stateblock_set_blend_factor(ptr ptr) +@ cdecl wined3d_stateblock_set_pixel_shader(ptr ptr) +@ cdecl wined3d_stateblock_set_ps_consts_b(ptr long long ptr) +@ cdecl wined3d_stateblock_set_ps_consts_f(ptr long long ptr) +@ cdecl wined3d_stateblock_set_ps_consts_i(ptr long long ptr) +@ cdecl wined3d_stateblock_set_render_state(ptr long long) +@ cdecl wined3d_stateblock_set_vertex_declaration(ptr ptr) +@ cdecl wined3d_stateblock_set_vertex_shader(ptr ptr) +@ cdecl wined3d_stateblock_set_vs_consts_b(ptr long long ptr) +@ cdecl wined3d_stateblock_set_vs_consts_f(ptr long long ptr) +@ cdecl wined3d_stateblock_set_vs_consts_i(ptr long long ptr) @ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_swapchain_decref(ptr) @@ -284,15 +282,19 @@ @ cdecl wined3d_swapchain_get_parent(ptr) @ cdecl wined3d_swapchain_get_desc(ptr ptr) @ cdecl wined3d_swapchain_get_raster_status(ptr ptr) +@ cdecl wined3d_swapchain_get_state(ptr) @ cdecl wined3d_swapchain_incref(ptr) @ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long long) @ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long) -@ cdecl wined3d_swapchain_resize_target(ptr ptr) -@ cdecl wined3d_swapchain_set_fullscreen(ptr ptr ptr) @ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr) @ cdecl wined3d_swapchain_set_palette(ptr ptr) @ cdecl wined3d_swapchain_set_window(ptr ptr) +@ cdecl wined3d_swapchain_state_create(ptr ptr ptr long ptr) +@ cdecl wined3d_swapchain_state_destroy(ptr) +@ cdecl wined3d_swapchain_state_resize_target(ptr ptr long ptr) +@ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr long ptr) + @ cdecl wined3d_texture_add_dirty_region(ptr long ptr) @ cdecl wined3d_texture_blt(ptr long ptr ptr long ptr long ptr long) @ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr) @@ -327,6 +329,8 @@ @ cdecl wined3d_vertex_declaration_get_parent(ptr) @ cdecl wined3d_vertex_declaration_incref(ptr) +@ cdecl wined3d_extract_shader_input_signature_from_dxbc(ptr ptr long) + @ cdecl wined3d_dxtn_supported() @ cdecl wined3d_dxt1_decode(ptr ptr long long long long long) @ cdecl wined3d_dxt1_encode(ptr ptr long long long long long) diff --git a/dll/directx/wine/wined3d/wined3d_gl.h b/dll/directx/wine/wined3d/wined3d_gl.h index f9fd9c307fa..f3b3c1c3f94 100644 --- a/dll/directx/wine/wined3d/wined3d_gl.h +++ b/dll/directx/wine/wined3d/wined3d_gl.h @@ -28,9 +28,6 @@ #define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 /* not in the gl spec */ -extern void (WINE_GLAPI *glDisableWINE)(GLenum cap) DECLSPEC_HIDDEN; -extern void (WINE_GLAPI *glEnableWINE)(GLenum cap) DECLSPEC_HIDDEN; - /* OpenGL extensions. */ enum wined3d_gl_extension { @@ -44,6 +41,7 @@ enum wined3d_gl_extension /* ARB */ ARB_BASE_INSTANCE, ARB_BLEND_FUNC_EXTENDED, + ARB_BUFFER_STORAGE, ARB_CLEAR_BUFFER_OBJECT, ARB_CLEAR_TEXTURE, ARB_CLIP_CONTROL, @@ -88,14 +86,19 @@ enum wined3d_gl_extension ARB_PIXEL_BUFFER_OBJECT, ARB_POINT_PARAMETERS, ARB_POINT_SPRITE, + ARB_POLYGON_OFFSET_CLAMP, ARB_PROVOKING_VERTEX, + ARB_QUERY_BUFFER_OBJECT, + ARB_SAMPLE_SHADING, ARB_SAMPLER_OBJECTS, ARB_SEAMLESS_CUBE_MAP, ARB_SHADER_ATOMIC_COUNTERS, + ARB_SHADER_VIEWPORT_LAYER_ARRAY, ARB_SHADER_BIT_ENCODING, ARB_SHADER_IMAGE_LOAD_STORE, ARB_SHADER_IMAGE_SIZE, ARB_SHADER_STORAGE_BUFFER_OBJECT, + ARB_SHADER_TEXTURE_IMAGE_SAMPLES, ARB_SHADER_TEXTURE_LOD, ARB_SHADING_LANGUAGE_100, ARB_SHADING_LANGUAGE_420PACK, @@ -134,7 +137,6 @@ enum wined3d_gl_extension ARB_TRANSFORM_FEEDBACK3, ARB_UNIFORM_BUFFER_OBJECT, ARB_VERTEX_ARRAY_BGRA, - ARB_VERTEX_BLEND, ARB_VERTEX_BUFFER_OBJECT, ARB_VERTEX_PROGRAM, ARB_VERTEX_SHADER, @@ -152,14 +154,15 @@ enum wined3d_gl_extension EXT_BLEND_FUNC_SEPARATE, EXT_BLEND_MINMAX, EXT_BLEND_SUBTRACT, - EXT_DRAW_BUFFERS2, EXT_DEPTH_BOUNDS_TEST, + EXT_DRAW_BUFFERS2, EXT_FOG_COORD, EXT_FRAMEBUFFER_BLIT, EXT_FRAMEBUFFER_MULTISAMPLE, EXT_FRAMEBUFFER_OBJECT, EXT_GPU_PROGRAM_PARAMETERS, EXT_GPU_SHADER4, + EXT_MEMORY_OBJECT, EXT_PACKED_DEPTH_STENCIL, EXT_PACKED_FLOAT, EXT_POINT_PARAMETERS, @@ -177,11 +180,11 @@ enum wined3d_gl_extension EXT_TEXTURE_INTEGER, EXT_TEXTURE_LOD_BIAS, EXT_TEXTURE_MIRROR_CLAMP, + EXT_TEXTURE_SHADOW_LOD, EXT_TEXTURE_SHARED_EXPONENT, EXT_TEXTURE_SNORM, EXT_TEXTURE_SRGB, EXT_TEXTURE_SRGB_DECODE, - EXT_VERTEX_ARRAY_BGRA, /* NVIDIA */ NV_FENCE, NV_FOG_DISTANCE, diff --git a/dll/directx/wine/wined3d/wined3d_main.c b/dll/directx/wine/wined3d/wined3d_main.c index 28e6fe60cfe..35060d6b961 100644 --- a/dll/directx/wine/wined3d/wined3d_main.c +++ b/dll/directx/wine/wined3d/wined3d_main.c @@ -33,20 +33,48 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); struct wined3d_wndproc { + struct wined3d *wined3d; HWND window; BOOL unicode; + BOOL filter; WNDPROC proc; struct wined3d_device *device; + uint32_t flags; }; struct wined3d_wndproc_table { struct wined3d_wndproc *entries; - unsigned int count; + SIZE_T count; SIZE_T size; }; +struct wined3d_window_hook +{ + HHOOK hook; + DWORD thread_id; + unsigned int count; +}; + +struct wined3d_hooked_swapchain +{ + struct wined3d_swapchain *swapchain; + DWORD thread_id; +}; + +struct wined3d_hook_table +{ + struct wined3d_window_hook *hooks; + SIZE_T hooks_size; + SIZE_T hook_count; + + struct wined3d_hooked_swapchain *swapchains; + SIZE_T swapchains_size; + SIZE_T swapchain_count; +}; + static struct wined3d_wndproc_table wndproc_table; +static struct wined3d_hook_table hook_table; static CRITICAL_SECTION wined3d_cs; static CRITICAL_SECTION_DEBUG wined3d_cs_debug = @@ -73,9 +101,7 @@ static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0, struct wined3d_settings wined3d_settings = { TRUE, /* Multithreaded CS by default. */ - FALSE, /* explicit_gl_version */ - MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */ - TRUE, /* Use of GLSL enabled by default */ + MAKEDWORD_VERSION(4, 4), /* Default to OpenGL 4.4 */ ORM_FBO, /* Use FBOs to do offscreen rendering */ PCI_VENDOR_NONE,/* PCI Vendor ID */ PCI_DEVICE_NONE,/* PCI Device ID */ @@ -83,15 +109,17 @@ struct wined3d_settings wined3d_settings = NULL, /* No wine logo by default */ TRUE, /* Prefer multisample textures to multisample renderbuffers. */ ~0u, /* Don't force a specific sample count by default. */ - FALSE, /* No strict draw ordering. */ FALSE, /* Don't range check relative addressing indices in float constants. */ + FALSE, /* No strict shader math by default. */ + 0, /* IEEE 0 * inf result. */ ~0U, /* No VS shader model limit by default. */ ~0U, /* No HS shader model limit by default. */ ~0U, /* No DS shader model limit by default. */ ~0U, /* No GS shader model limit by default. */ ~0U, /* No PS shader model limit by default. */ ~0u, /* No CS shader model limit by default. */ - FALSE, /* 3D support enabled by default. */ + WINED3D_RENDERER_AUTO, + WINED3D_SHADER_BACKEND_AUTO, }; struct wined3d * CDECL wined3d_create(DWORD flags) @@ -105,11 +133,10 @@ struct wined3d * CDECL wined3d_create(DWORD flags) return NULL; } - if (wined3d_settings.no_3d) + if (wined3d_settings.renderer == WINED3D_RENDERER_NO3D) flags |= WINED3D_NO3D; - hr = wined3d_init(object, flags); - if (FAILED(hr)) + if (FAILED(hr = wined3d_init(object, flags))) { WARN("Failed to initialize wined3d object, hr %#x.\n", hr); heap_free(object); @@ -144,6 +171,30 @@ static DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char *name, DW return 0; } +BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size) +{ + char buffer[MAX_PATH]; + unsigned int len; + char *p, *name; + + len = GetModuleFileNameA(0, buffer, ARRAY_SIZE(buffer)); + if (!(len && len < MAX_PATH)) + return FALSE; + + name = buffer; + if ((p = strrchr(name, '/' ))) + name = p + 1; + if ((p = strrchr(name, '\\'))) + name = p + 1; + + len = strlen(name) + 1; + if (app_name_size < len) + return FALSE; + + memcpy(app_name, name, len); + return TRUE; +} + static BOOL wined3d_dll_init(HINSTANCE hInstDLL) { DWORD wined3d_context_tls_idx; @@ -151,7 +202,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) DWORD size = sizeof(buffer); HKEY hkey = 0; HKEY appkey = 0; - DWORD len, tmpvalue; + DWORD tmpvalue; WNDCLASSA wc; wined3d_context_tls_idx = TlsAlloc(); @@ -193,20 +244,16 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */ if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0; - len = GetModuleFileNameA( 0, buffer, MAX_PATH ); - if (len && len < MAX_PATH) + if (wined3d_get_app_name(buffer, ARRAY_SIZE(buffer))) { HKEY tmpkey; /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */ - if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey )) + if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey)) { - char *p, *appname = buffer; - if ((p = strrchr( appname, '/' ))) appname = p + 1; - if ((p = strrchr( appname, '\\' ))) appname = p + 1; - strcat( appname, "\\Direct3D" ); - TRACE("appname = [%s]\n", appname); - if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0; - RegCloseKey( tmpkey ); + strcat(buffer, "\\Direct3D"); + TRACE("Application name %s.\n", buffer); + if (RegOpenKeyA(tmpkey, buffer, &appkey)) appkey = 0; + RegCloseKey(tmpkey); } } @@ -218,18 +265,36 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) { ERR_(winediag)("Setting maximum allowed wined3d GL version to %u.%u.\n", tmpvalue >> 16, tmpvalue & 0xffff); - wined3d_settings.explicit_gl_version = TRUE; wined3d_settings.max_gl_version = tmpvalue; } - if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) ) + if (!get_config_key(hkey, appkey, "shader_backend", buffer, size)) { - if (!strcmp(buffer,"disabled")) + if (!_strnicmp(buffer, "glsl", -1)) + { + ERR_(winediag)("Using the GLSL shader backend.\n"); + wined3d_settings.shader_backend = WINED3D_SHADER_BACKEND_GLSL; + } + else if (!_strnicmp(buffer, "arb", -1)) + { + ERR_(winediag)("Using the ARB shader backend.\n"); + wined3d_settings.shader_backend = WINED3D_SHADER_BACKEND_ARB; + } + else if (!_strnicmp(buffer, "none", -1)) { - ERR_(winediag)("The GLSL shader backend has been disabled. You get to keep all the pieces if it breaks.\n"); - TRACE("Use of GL Shading Language disabled\n"); - wined3d_settings.glslRequested = FALSE; + ERR_(winediag)("Disabling shader backends.\n"); + wined3d_settings.shader_backend = WINED3D_SHADER_BACKEND_NONE; } } + else if (!get_config_key(hkey, appkey, "UseGLSL", buffer, size) && !strcmp(buffer, "disabled")) + { + wined3d_settings.shader_backend = WINED3D_SHADER_BACKEND_ARB; + } + if (wined3d_settings.shader_backend == WINED3D_SHADER_BACKEND_ARB + || wined3d_settings.shader_backend == WINED3D_SHADER_BACKEND_NONE) + { + ERR_(winediag)("The GLSL shader backend has been disabled. You get to keep all the pieces if it breaks.\n"); + TRACE("Use of GL Shading Language disabled.\n"); + } if (!get_config_key(hkey, appkey, "OffscreenRenderingMode", buffer, size) && !strcmp(buffer,"backbuffer")) wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; @@ -290,19 +355,16 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count)) ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n", wined3d_settings.sample_count); - if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size) - && !strcmp(buffer,"enabled")) - { - ERR_(winediag)("\"StrictDrawOrdering\" is deprecated, please use \"csmt\" instead.\n"); - TRACE("Enforcing strict draw ordering.\n"); - wined3d_settings.strict_draw_ordering = TRUE; - } if (!get_config_key(hkey, appkey, "CheckFloatConstants", buffer, size) && !strcmp(buffer, "enabled")) { TRACE("Checking relative addressing indices in float constants.\n"); wined3d_settings.check_float_constants = TRUE; } + if (!get_config_key_dword(hkey, appkey, "strict_shader_math", &wined3d_settings.strict_shader_math)) + ERR_(winediag)("Setting strict shader math to %#x.\n", wined3d_settings.strict_shader_math); + if (!get_config_key_dword(hkey, appkey, "multiply_special", &wined3d_settings.multiply_special)) + ERR_(winediag)("Setting multiply special to %#x.\n", wined3d_settings.multiply_special); if (!get_config_key_dword(hkey, appkey, "MaxShaderModelVS", &wined3d_settings.max_sm_vs)) TRACE("Limiting VS shader model to %u.\n", wined3d_settings.max_sm_vs); if (!get_config_key_dword(hkey, appkey, "MaxShaderModelHS", &wined3d_settings.max_sm_hs)) @@ -315,11 +377,24 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) TRACE("Limiting PS shader model to %u.\n", wined3d_settings.max_sm_ps); if (!get_config_key_dword(hkey, appkey, "MaxShaderModelCS", &wined3d_settings.max_sm_cs)) TRACE("Limiting CS shader model to %u.\n", wined3d_settings.max_sm_cs); - if (!get_config_key(hkey, appkey, "DirectDrawRenderer", buffer, size) - && !strcmp(buffer, "gdi")) + if (!get_config_key(hkey, appkey, "renderer", buffer, size) + || !get_config_key(hkey, appkey, "DirectDrawRenderer", buffer, size)) { - TRACE("Disabling 3D support.\n"); - wined3d_settings.no_3d = TRUE; + if (!strcmp(buffer, "vulkan")) + { + ERR_(winediag)("Using the Vulkan renderer.\n"); + wined3d_settings.renderer = WINED3D_RENDERER_VULKAN; + } + else if (!strcmp(buffer, "gl")) + { + ERR_(winediag)("Using the OpenGL renderer.\n"); + wined3d_settings.renderer = WINED3D_RENDERER_OPENGL; + } + else if (!strcmp(buffer, "gdi") || !strcmp(buffer, "no3d")) + { + ERR_(winediag)("Disabling 3D support.\n"); + wined3d_settings.renderer = WINED3D_RENDERER_NO3D; + } } } @@ -354,6 +429,14 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL) } heap_free(wndproc_table.entries); + heap_free(hook_table.swapchains); + for (i = 0; i < hook_table.hook_count; ++i) + { + WARN("Leftover hook table entry %p.\n", &hook_table.hooks[i]); + UnhookWindowsHookEx(hook_table.hooks[i].hook); + } + heap_free(hook_table.hooks); + heap_free(wined3d_settings.logo); UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL); @@ -385,32 +468,52 @@ static void wined3d_wndproc_mutex_unlock(void) LeaveCriticalSection(&wined3d_wndproc_cs); } -static struct wined3d_wndproc *wined3d_find_wndproc(HWND window) +static struct wined3d_wndproc *wined3d_find_wndproc(HWND window, struct wined3d *wined3d) { unsigned int i; for (i = 0; i < wndproc_table.count; ++i) { - if (wndproc_table.entries[i].window == window) - { - return &wndproc_table.entries[i]; - } + struct wined3d_wndproc *entry = &wndproc_table.entries[i]; + + if (entry->window == window && entry->wined3d == wined3d) + return entry; } return NULL; } +BOOL wined3d_filter_messages(HWND window, BOOL filter) +{ + struct wined3d_wndproc *entry; + BOOL ret; + + wined3d_wndproc_mutex_lock(); + + if (!(entry = wined3d_find_wndproc(window, NULL))) + { + wined3d_wndproc_mutex_unlock(); + return FALSE; + } + + ret = entry->filter; + entry->filter = filter; + + wined3d_wndproc_mutex_unlock(); + + return ret; +} + static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) { struct wined3d_wndproc *entry; struct wined3d_device *device; - BOOL unicode; + BOOL unicode, filter; WNDPROC proc; wined3d_wndproc_mutex_lock(); - entry = wined3d_find_wndproc(window); - if (!entry) + if (!(entry = wined3d_find_wndproc(window, NULL))) { wined3d_wndproc_mutex_unlock(); ERR("Window %p is not registered with wined3d.\n", window); @@ -419,26 +522,86 @@ static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam device = entry->device; unicode = entry->unicode; + filter = entry->filter; proc = entry->proc; wined3d_wndproc_mutex_unlock(); if (device) + { + if (filter && message != WM_DISPLAYCHANGE) + { + TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n", + window, message, wparam, lparam); + + if (unicode) + return DefWindowProcW(window, message, wparam, lparam); + return DefWindowProcA(window, message, wparam, lparam); + } + return device_process_message(device, window, unicode, message, wparam, lparam, proc); + } if (unicode) return CallWindowProcW(proc, window, message, wparam, lparam); return CallWindowProcA(proc, window, message, wparam, lparam); } -BOOL wined3d_register_window(HWND window, struct wined3d_device *device) +static LRESULT CALLBACK wined3d_hook_proc(int code, WPARAM wparam, LPARAM lparam) +{ + struct wined3d_swapchain_desc swapchain_desc; + struct wined3d_swapchain *swapchain; + struct wined3d_wndproc *entry; + MSG *msg = (MSG *)lparam; + unsigned int i; + + /* Handle Alt+Enter. */ + if (code == HC_ACTION && msg->message == WM_SYSKEYDOWN + && msg->wParam == VK_RETURN && (msg->lParam & (KF_ALTDOWN << 16))) + { + wined3d_wndproc_mutex_lock(); + + for (i = 0; i < hook_table.swapchain_count; ++i) + { + swapchain = hook_table.swapchains[i].swapchain; + + if (swapchain->state.device_window != msg->hwnd) + continue; + + if ((entry = wined3d_find_wndproc(msg->hwnd, swapchain->device->wined3d)) + && (entry->flags & (WINED3D_REGISTER_WINDOW_NO_WINDOW_CHANGES + | WINED3D_REGISTER_WINDOW_NO_ALT_ENTER))) + continue; + + wined3d_swapchain_get_desc(swapchain, &swapchain_desc); + swapchain_desc.windowed = !swapchain_desc.windowed; + wined3d_swapchain_state_set_fullscreen(&swapchain->state, &swapchain_desc, + swapchain->device->wined3d, swapchain->device->adapter->ordinal, NULL); + + wined3d_wndproc_mutex_unlock(); + + return 1; + } + + wined3d_wndproc_mutex_unlock(); + } + + return CallNextHookEx(0, code, wparam, lparam); +} + +BOOL CDECL wined3d_register_window(struct wined3d *wined3d, HWND window, + struct wined3d_device *device, unsigned int flags) { struct wined3d_wndproc *entry; + TRACE("wined3d %p, window %p, device %p, flags %#x.\n", wined3d, window, device, flags); + wined3d_wndproc_mutex_lock(); - if (wined3d_find_wndproc(window)) + if ((entry = wined3d_find_wndproc(window, wined3d))) { + if (!wined3d) + WARN("Window %p is already registered with wined3d.\n", window); + entry->flags = flags; wined3d_wndproc_mutex_unlock(); - WARN("Window %p is already registered with wined3d.\n", window); return TRUE; } @@ -453,72 +616,202 @@ BOOL wined3d_register_window(HWND window, struct wined3d_device *device) entry = &wndproc_table.entries[wndproc_table.count++]; entry->window = window; entry->unicode = IsWindowUnicode(window); - /* Set a window proc that matches the window. Some applications (e.g. NoX) - * replace the window proc after we've set ours, and expect to be able to - * call the previous one (ours) directly, without using CallWindowProc(). */ - if (entry->unicode) - entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc); + if (!wined3d) + { + /* Set a window proc that matches the window. Some applications (e.g. + * NoX) replace the window proc after we've set ours, and expect to be + * able to call the previous one (ours) directly, without using + * CallWindowProc(). */ + if (entry->unicode) + entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc); + else + entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc); + } else - entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc); + { + entry->proc = NULL; + } entry->device = device; + entry->wined3d = wined3d; + entry->flags = flags; wined3d_wndproc_mutex_unlock(); return TRUE; } +static BOOL restore_wndproc(struct wined3d_wndproc *entry) +{ + LONG_PTR proc; + + if (entry->unicode) + { + proc = GetWindowLongPtrW(entry->window, GWLP_WNDPROC); + if (proc != (LONG_PTR)wined3d_wndproc) + return FALSE; + SetWindowLongPtrW(entry->window, GWLP_WNDPROC, (LONG_PTR)entry->proc); + } + else + { + proc = GetWindowLongPtrA(entry->window, GWLP_WNDPROC); + if (proc != (LONG_PTR)wined3d_wndproc) + return FALSE; + SetWindowLongPtrA(entry->window, GWLP_WNDPROC, (LONG_PTR)entry->proc); + } + + return TRUE; +} + void wined3d_unregister_window(HWND window) { struct wined3d_wndproc *entry, *last; - LONG_PTR proc; wined3d_wndproc_mutex_lock(); - if (!(entry = wined3d_find_wndproc(window))) + if (!(entry = wined3d_find_wndproc(window, NULL))) { wined3d_wndproc_mutex_unlock(); ERR("Window %p is not registered with wined3d.\n", window); return; } - if (entry->unicode) + if (entry->proc && !restore_wndproc(entry)) { - proc = GetWindowLongPtrW(window, GWLP_WNDPROC); - if (proc != (LONG_PTR)wined3d_wndproc) + entry->device = NULL; + WARN("Not unregistering window %p, current window proc doesn't match wined3d window proc.\n", window); + wined3d_wndproc_mutex_unlock(); + return; + } + + last = &wndproc_table.entries[--wndproc_table.count]; + if (entry != last) *entry = *last; + + wined3d_wndproc_mutex_unlock(); +} + +void CDECL wined3d_unregister_windows(struct wined3d *wined3d) +{ + struct wined3d_wndproc *entry, *last; + unsigned int i = 0; + + TRACE("wined3d %p.\n", wined3d); + + wined3d_wndproc_mutex_lock(); + + while (i < wndproc_table.count) + { + entry = &wndproc_table.entries[i]; + + if (entry->wined3d != wined3d) { - entry->device = NULL; - wined3d_wndproc_mutex_unlock(); - WARN("Not unregistering window %p, window proc %#lx doesn't match wined3d window proc %p.\n", - window, proc, wined3d_wndproc); - return; + ++i; + continue; } - SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc); - } - else - { - proc = GetWindowLongPtrA(window, GWLP_WNDPROC); - if (proc != (LONG_PTR)wined3d_wndproc) + if (entry->proc && !restore_wndproc(entry)) { entry->device = NULL; - wined3d_wndproc_mutex_unlock(); - WARN("Not unregistering window %p, window proc %#lx doesn't match wined3d window proc %p.\n", - window, proc, wined3d_wndproc); - return; + WARN("Not unregistering window %p, current window proc doesn't match wined3d window proc.\n", + entry->window); + ++i; + continue; } - SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)entry->proc); + last = &wndproc_table.entries[--wndproc_table.count]; + if (entry != last) + *entry = *last; + else + ++i; } - last = &wndproc_table.entries[--wndproc_table.count]; - if (entry != last) *entry = *last; + wined3d_wndproc_mutex_unlock(); +} + +static struct wined3d_window_hook *wined3d_find_hook(DWORD thread_id) +{ + unsigned int i; + + for (i = 0; i < hook_table.hook_count; ++i) + { + if (hook_table.hooks[i].thread_id == thread_id) + return &hook_table.hooks[i]; + } + + return NULL; +} + +void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain) +{ + struct wined3d_hooked_swapchain *swapchain_entry; + struct wined3d_window_hook *hook; + + wined3d_wndproc_mutex_lock(); + + if (!wined3d_array_reserve((void **)&hook_table.swapchains, &hook_table.swapchains_size, + hook_table.swapchain_count + 1, sizeof(*swapchain_entry))) + { + wined3d_wndproc_mutex_unlock(); + return; + } + + swapchain_entry = &hook_table.swapchains[hook_table.swapchain_count++]; + swapchain_entry->swapchain = swapchain; + swapchain_entry->thread_id = GetWindowThreadProcessId(swapchain->state.device_window, NULL); + + if ((hook = wined3d_find_hook(swapchain_entry->thread_id))) + { + ++hook->count; + wined3d_wndproc_mutex_unlock(); + return; + } + + if (!wined3d_array_reserve((void **)&hook_table.hooks, &hook_table.hooks_size, + hook_table.hook_count + 1, sizeof(*hook))) + { + --hook_table.swapchain_count; + wined3d_wndproc_mutex_unlock(); + return; + } + + hook = &hook_table.hooks[hook_table.hook_count++]; + hook->thread_id = swapchain_entry->thread_id; + hook->hook = SetWindowsHookExW(WH_GETMESSAGE, wined3d_hook_proc, 0, hook->thread_id); + hook->count = 1; wined3d_wndproc_mutex_unlock(); } -void CDECL wined3d_strictdrawing_set(int value) +void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain) { - wined3d_settings.strict_draw_ordering = value; + struct wined3d_hooked_swapchain *swapchain_entry, *last_swapchain_entry; + struct wined3d_window_hook *hook, *last_hook; + unsigned int i; + + wined3d_wndproc_mutex_lock(); + + for (i = 0; i < hook_table.swapchain_count; ++i) + { + swapchain_entry = &hook_table.swapchains[i]; + + if (swapchain_entry->swapchain != swapchain) + continue; + + if ((hook = wined3d_find_hook(swapchain_entry->thread_id)) && !--hook->count) + { + UnhookWindowsHookEx(hook->hook); + last_hook = &hook_table.hooks[--hook_table.hook_count]; + if (hook != last_hook) + *hook = *last_hook; + } + + last_swapchain_entry = &hook_table.swapchains[--hook_table.swapchain_count]; + if (swapchain_entry != last_swapchain_entry) + *swapchain_entry = *last_swapchain_entry; + + break; + } + + wined3d_wndproc_mutex_unlock(); } /* At process attach */ @@ -535,7 +828,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) break; case DLL_THREAD_DETACH: - if (!context_set_current(NULL)) + if (!wined3d_context_gl_set_current(NULL)) { ERR("Failed to clear current context.\n"); } diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h index b127fa71faa..ee2e9501341 100644 --- a/dll/directx/wine/wined3d/wined3d_private.h +++ b/dll/directx/wine/wined3d/wined3d_private.h @@ -54,14 +54,11 @@ #include "objbase.h" #include "wine/wined3d.h" #include "wined3d_gl.h" +#include "wined3d_vk.h" #include "wine/list.h" #include "wine/rbtree.h" #include "wine/wgl_driver.h" -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -#endif - #define MAKEDWORD_VERSION(maj, min) (((maj & 0xffffu) << 16) | (min & 0xffffu)) /* Driver quirks */ @@ -75,6 +72,15 @@ #define WINED3D_QUIRK_INFO_LOG_SPAM 0x00000080 #define WINED3D_QUIRK_LIMITED_TEX_FILTERING 0x00000100 #define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200 +#define WINED3D_QUIRK_NO_INDEPENDENT_BIT_DEPTHS 0x00000400 + +struct wined3d_fragment_pipe_ops; +struct wined3d_adapter; +struct wined3d_context; +struct wined3d_state; +struct wined3d_swapchain_gl; +struct wined3d_texture_gl; +struct wined3d_vertex_pipe_ops; enum wined3d_ffp_idx { @@ -161,12 +167,19 @@ struct wined3d_d3d_limits { unsigned int vs_version, hs_version, ds_version, gs_version, ps_version, cs_version; DWORD vs_uniform_count; + DWORD vs_uniform_count_swvp; DWORD ps_uniform_count; unsigned int varying_count; unsigned int ffp_textures; unsigned int ffp_blend_stages; unsigned int ffp_vertex_blend_matrices; unsigned int active_light_count; + unsigned int ffp_max_vertex_blend_matrix_index; + + unsigned int max_rt_count; + unsigned int max_clip_distances; + unsigned int texture_size; + float pointsize_max; }; typedef void (WINE_GLAPI *wined3d_ffp_attrib_func)(const void *data); @@ -188,34 +201,34 @@ struct wined3d_d3d_info { struct wined3d_d3d_limits limits; struct wined3d_ffp_attrib_ops ffp_attrib_ops; - BOOL xyzrhw; - BOOL emulated_flatshading; - BOOL ffp_generic_attributes; - BOOL vs_clipping; - BOOL shader_color_key; - DWORD valid_rt_mask; DWORD valid_dual_rt_mask; - DWORD wined3d_creation_flags; - BOOL shader_double_precision; + uint32_t wined3d_creation_flags; + uint32_t xyzrhw : 1; + uint32_t emulated_flatshading : 1; + uint32_t ffp_generic_attributes : 1; + uint32_t ffp_alpha_test : 1; + uint32_t vs_clipping : 1; + uint32_t shader_color_key : 1; + uint32_t shader_double_precision : 1; + uint32_t shader_output_interpolation : 1; + uint32_t viewport_array_index_any_shader : 1; + uint32_t texture_npot : 1; + uint32_t texture_npot_conditional : 1; + uint32_t draw_base_vertex_offset : 1; + uint32_t vertex_bgra : 1; + uint32_t texture_swizzle : 1; + uint32_t srgb_read_control : 1; + uint32_t srgb_write_control : 1; + uint32_t clip_control : 1; + uint32_t full_ffp_varyings : 1; + enum wined3d_feature_level feature_level; + + DWORD multisample_draw_location; }; static const struct color_fixup_desc COLOR_FIXUP_IDENTITY = {0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W}; -static inline struct color_fixup_desc create_color_fixup_desc( - int sign0, enum fixup_channel_source src0, int sign1, enum fixup_channel_source src1, - int sign2, enum fixup_channel_source src2, int sign3, enum fixup_channel_source src3) -{ - struct color_fixup_desc fixup = - { - sign0, src0, - sign1, src1, - sign2, src2, - sign3, src3, - }; - return fixup; -} - static inline struct color_fixup_desc create_complex_fixup_desc(enum complex_fixup complex_fixup) { struct color_fixup_desc fixup = @@ -262,13 +275,15 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup } /* Device caps */ -#define MAX_STREAMS 16 -#define MAX_TEXTURES 8 -#define MAX_FRAGMENT_SAMPLERS 16 -#define MAX_VERTEX_SAMPLERS 4 -#define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS) -#define MAX_ACTIVE_LIGHTS 8 -#define MAX_CLIP_DISTANCES 8 +#define MAX_VERTEX_BLEND_UBO 256 +#define WINED3D_MAX_STREAMS 16 +#define WINED3D_MAX_TEXTURES 8 +#define WINED3D_MAX_FRAGMENT_SAMPLERS 16 +#define WINED3D_MAX_VERTEX_SAMPLERS 4 +#define WINED3D_MAX_COMBINED_SAMPLERS (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS) +#define WINED3D_MAX_ACTIVE_LIGHTS 8 +#define WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS 32 +#define WINED3D_MAX_CLIP_DISTANCES 8 #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16 #define MAX_SHADER_RESOURCE_VIEWS 128 @@ -277,7 +292,6 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define MAX_TGSM_REGISTERS 8192 #define MAX_VERTEX_BLENDS 4 #define MAX_VERTEX_INDEX_BLENDS 9 -#define MAX_MULTISAMPLE_TYPES 8 #define MAX_RENDER_TARGETS 8 struct min_lookup @@ -386,14 +400,28 @@ static inline void wined3d_pause(void) #define PCI_VENDOR_NONE 0xffff /* e.g. 0x8086 for Intel and 0x10de for Nvidia */ #define PCI_DEVICE_NONE 0xffff /* e.g. 0x14f for a Geforce6200 */ +enum wined3d_renderer +{ + WINED3D_RENDERER_AUTO, + WINED3D_RENDERER_VULKAN, + WINED3D_RENDERER_OPENGL, + WINED3D_RENDERER_NO3D, +}; + +enum wined3d_shader_backend +{ + WINED3D_SHADER_BACKEND_AUTO, + WINED3D_SHADER_BACKEND_GLSL, + WINED3D_SHADER_BACKEND_ARB, + WINED3D_SHADER_BACKEND_NONE, +}; + /* NOTE: When adding fields to this structure, make sure to update the default * values in wined3d_main.c as well. */ struct wined3d_settings { unsigned int cs_multithreaded; - BOOL explicit_gl_version; DWORD max_gl_version; - BOOL glslRequested; int offscreen_rendering_mode; unsigned short pci_vendor_id; unsigned short pci_device_id; @@ -402,19 +430,27 @@ struct wined3d_settings char *logo; unsigned int multisample_textures; unsigned int sample_count; - BOOL strict_draw_ordering; BOOL check_float_constants; + unsigned int strict_shader_math; + unsigned int multiply_special; unsigned int max_sm_vs; unsigned int max_sm_hs; unsigned int max_sm_ds; unsigned int max_sm_gs; unsigned int max_sm_ps; unsigned int max_sm_cs; - BOOL no_3d; + enum wined3d_renderer renderer; + enum wined3d_shader_backend shader_backend; }; extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; +enum wined3d_shader_byte_code_format +{ + WINED3D_SHADER_BYTE_CODE_FORMAT_SM1, + WINED3D_SHADER_BYTE_CODE_FORMAT_SM4, +}; + enum wined3d_shader_resource_type { WINED3D_SHADER_RESOURCE_NONE, @@ -451,6 +487,7 @@ enum wined3d_shader_resource_type #define WINED3D_SHADER_CONST_FFP_LIGHTS 0x00080000 #define WINED3D_SHADER_CONST_FFP_PS 0x00100000 #define WINED3D_SHADER_CONST_FFP_COLOR_KEY 0x00200000 +#define WINED3D_SHADER_CONST_BASE_VERTEX_ID 0x00400000 #define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0xff000000 #define WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i) (0x01000000 << ((i) - 1)) @@ -506,6 +543,7 @@ enum wined3d_shader_register_type WINED3DSPR_GSINSTID, WINED3DSPR_DEPTHOUTGE, WINED3DSPR_DEPTHOUTLE, + WINED3DSPR_RASTERIZER, }; enum wined3d_data_type @@ -627,6 +665,14 @@ enum wined3d_tessellator_partitioning #define WINED3DSI_SAMPLE_INFO_UINT 0x1 #define WINED3DSI_SAMPLER_COMPARISON_MODE 0x1 +#define WINED3DSI_PRECISE_X 0x100 +#define WINED3DSI_PRECISE_Y 0x200 +#define WINED3DSI_PRECISE_Z 0x400 +#define WINED3DSI_PRECISE_W 0x800 +#define WINED3DSI_PRECISE_XYZW (WINED3DSI_PRECISE_X | WINED3DSI_PRECISE_Y \ + | WINED3DSI_PRECISE_Z | WINED3DSI_PRECISE_W) +#define WINED3DSI_PRECISE_SHIFT 8 + enum wined3d_shader_rel_op { WINED3D_SHADER_REL_OP_GT = 1, @@ -668,6 +714,7 @@ enum wined3d_shader_conditional_op #define WINED3D_MAX_CONSTS_B 16 #define WINED3D_MAX_CONSTS_I 16 #define WINED3D_MAX_VS_CONSTS_F 256 +#define WINED3D_MAX_VS_CONSTS_F_SWVP 8192 #define WINED3D_MAX_PS_CONSTS_F 224 /* FIXME: This needs to go up to 2048 for @@ -772,7 +819,6 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_DSY, WINED3DSIH_DSY_COARSE, WINED3DSIH_DSY_FINE, - WINED3DSIH_EVAL_SAMPLE_INDEX, WINED3DSIH_ELSE, WINED3DSIH_EMIT, WINED3DSIH_EMIT_STREAM, @@ -781,6 +827,7 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_ENDREP, WINED3DSIH_ENDSWITCH, WINED3DSIH_EQ, + WINED3DSIH_EVAL_SAMPLE_INDEX, WINED3DSIH_EXP, WINED3DSIH_EXPP, WINED3DSIH_F16TOF32, @@ -927,19 +974,6 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_TABLE_SIZE }; -enum wined3d_shader_type -{ - WINED3D_SHADER_TYPE_PIXEL, - WINED3D_SHADER_TYPE_VERTEX, - WINED3D_SHADER_TYPE_GEOMETRY, - WINED3D_SHADER_TYPE_HULL, - WINED3D_SHADER_TYPE_DOMAIN, - WINED3D_SHADER_TYPE_GRAPHICS_COUNT, - - WINED3D_SHADER_TYPE_COMPUTE = WINED3D_SHADER_TYPE_GRAPHICS_COUNT, - WINED3D_SHADER_TYPE_COUNT, -}; - struct wined3d_shader_version { enum wined3d_shader_type type; @@ -1014,14 +1048,14 @@ struct wined3d_shader_reg_maps struct wined3d_shader_resource_info resource_info[MAX_SHADER_RESOURCE_VIEWS]; struct wined3d_shader_sampler_map sampler_map; DWORD sampler_comparison_mode; - BYTE bumpmat; /* MAX_TEXTURES, 8 */ - BYTE luminanceparams; /* MAX_TEXTURES, 8 */ + BYTE bumpmat; /* WINED3D_MAX_TEXTURES, 8 */ + BYTE luminanceparams; /* WINED3D_MAX_TEXTURES, 8 */ struct wined3d_shader_resource_info uav_resource_info[MAX_UNORDERED_ACCESS_VIEWS]; DWORD uav_read_mask : 8; /* MAX_UNORDERED_ACCESS_VIEWS, 8 */ DWORD uav_counter_mask : 8; /* MAX_UNORDERED_ACCESS_VIEWS, 8 */ - DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */ - DWORD cull_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */ + DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */ + DWORD cull_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */ DWORD usesnrm : 1; DWORD vpos : 1; DWORD usesdsx : 1; @@ -1038,7 +1072,9 @@ struct wined3d_shader_reg_maps DWORD point_size : 1; DWORD vocp : 1; DWORD input_rel_addressing : 1; - DWORD padding : 16; + DWORD viewport_array : 1; + DWORD sample_mask : 1; + DWORD padding : 14; DWORD rt_mask; /* Used render targets, 32 max. */ @@ -1049,6 +1085,7 @@ struct wined3d_shader_reg_maps struct wined3d_shader_tgsm *tgsm; SIZE_T tgsm_capacity; unsigned int tgsm_count; + UINT constant_float_count; }; /* Keeps track of details for TEX_M#x# instructions which need to maintain @@ -1274,11 +1311,19 @@ struct wined3d_shader_frontend extern const struct wined3d_shader_frontend sm1_shader_frontend DECLSPEC_HIDDEN; extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN; +HRESULT shader_extract_from_dxbc(struct wined3d_shader *shader, + unsigned int max_shader_version, enum wined3d_shader_byte_code_format *format) DECLSPEC_HIDDEN; +BOOL shader_get_stream_output_register_info(const struct wined3d_shader *shader, + const struct wined3d_stream_output_element *so_element, unsigned int *register_idx, + unsigned int *component_idx) DECLSPEC_HIDDEN; + typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *); -#define WINED3D_SHADER_CAP_VS_CLIPPING 0x00000001 -#define WINED3D_SHADER_CAP_SRGB_WRITE 0x00000002 -#define WINED3D_SHADER_CAP_DOUBLE_PRECISION 0x00000004 +#define WINED3D_SHADER_CAP_VS_CLIPPING 0x00000001u +#define WINED3D_SHADER_CAP_SRGB_WRITE 0x00000002u +#define WINED3D_SHADER_CAP_DOUBLE_PRECISION 0x00000004u +#define WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION 0x00000008u +#define WINED3D_SHADER_CAP_FULL_FFP_VARYINGS 0x00000010u struct shader_caps { @@ -1289,10 +1334,10 @@ struct shader_caps unsigned int ps_version; unsigned int cs_version; - DWORD vs_uniform_count; - DWORD ps_uniform_count; + unsigned int vs_uniform_count; + unsigned int ps_uniform_count; float ps_1x_max_value; - DWORD varying_count; + unsigned int varying_count; DWORD wined3d_caps; }; @@ -1309,10 +1354,11 @@ enum wined3d_gl_resource_type WINED3D_GL_RES_TYPE_COUNT = 7, }; -enum vertexprocessing_mode { - fixedfunction, - vertexshader, - pretransformed +enum wined3d_vertex_processing_mode +{ + WINED3D_VP_MODE_FF, + WINED3D_VP_MODE_SHADER, + WINED3D_VP_MODE_NONE, }; #define WINED3D_CONST_NUM_UNUSED ~0U @@ -1342,28 +1388,31 @@ enum wined3d_shader_tex_types WINED3D_SHADER_TEX_2D = 0, WINED3D_SHADER_TEX_3D = 1, WINED3D_SHADER_TEX_CUBE = 2, + WINED3D_SHADER_TEX_ERR = 3, }; struct ps_compile_args { - struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS]; - enum vertexprocessing_mode vp_mode; + struct color_fixup_desc color_fixup[WINED3D_MAX_FRAGMENT_SAMPLERS]; + enum wined3d_vertex_processing_mode vp_mode; enum wined3d_ffp_ps_fog_mode fog; + DWORD tex_types; /* ps 1 - 3, 16 textures */ WORD tex_transform; /* ps 1.0-1.3, 4 textures */ - WORD tex_types; /* ps 1.0 - 1.4, 6 textures */ WORD srgb_correction; /* Bitmap for NP2 texcoord fixups (16 samplers max currently). D3D9 has a limit of 16 samplers and the fixup is superfluous in D3D10 (unconditional NP2 support mandatory). */ WORD np2_fixup; - WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */ - WORD texcoords_initialized; /* MAX_TEXTURES, 8 */ + WORD shadow; /* WINED3D_MAX_FRAGMENT_SAMPLERS, 16 */ + WORD texcoords_initialized; /* WINED3D_MAX_TEXTURES, 8 */ + WORD padding_to_dword; DWORD pointsprite : 1; DWORD flatshading : 1; DWORD alpha_test_func : 3; DWORD render_offscreen : 1; + DWORD rt_alpha_swizzle : 8; /* MAX_RENDER_TARGET_VIEWS, 8 */ DWORD dual_source_blend : 1; - DWORD padding : 25; + DWORD padding : 17; }; enum fog_src_type @@ -1400,14 +1449,10 @@ struct ds_compile_args struct gs_compile_args { unsigned int output_count; + enum wined3d_primitive_type primitive_type; DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE]; }; -struct wined3d_context; -struct wined3d_state; -struct fragment_pipeline; -struct wined3d_vertex_pipe_ops; - struct wined3d_shader_backend_ops { void (*shader_handle_instruction)(const struct wined3d_shader_instruction *); @@ -1423,12 +1468,12 @@ struct wined3d_shader_backend_ops const struct wined3d_state *state); void (*shader_destroy)(struct wined3d_shader *shader); HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, - const struct fragment_pipeline *fragment_pipe); - void (*shader_free_private)(struct wined3d_device *device); + const struct wined3d_fragment_pipe_ops *fragment_pipe); + void (*shader_free_private)(struct wined3d_device *device, struct wined3d_context *context); BOOL (*shader_allocate_context_data)(struct wined3d_context *context); void (*shader_free_context_data)(struct wined3d_context *context); void (*shader_init_context_state)(struct wined3d_context *context); - void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps); + void (*shader_get_caps)(const struct wined3d_adapter *adapter, struct shader_caps *caps); BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup); BOOL (*shader_has_ffp_proj_control)(void *shader_priv); }; @@ -1452,7 +1497,29 @@ static inline void wined3d_color_from_d3dcolor(struct wined3d_color *wined3d_col wined3d_color->a = D3DCOLOR_B_A(d3d_color) / 255.0f; } -#define HIGHEST_TRANSFORMSTATE WINED3D_TS_WORLD_MATRIX(255) /* Highest value in wined3d_transform_state. */ +extern const struct wined3d_vec4 wined3d_srgb_const[] DECLSPEC_HIDDEN; + +static inline float wined3d_srgb_from_linear(float colour) +{ + if (colour < 0.0f) + return 0.0f; + if (colour < wined3d_srgb_const[1].x) + return colour * wined3d_srgb_const[0].w; + if (colour < 1.0f) + return wined3d_srgb_const[0].y * powf(colour, wined3d_srgb_const[0].x) - wined3d_srgb_const[0].z; + return 1.0f; +} + +static inline void wined3d_colour_srgb_from_linear(struct wined3d_color *colour_srgb, + const struct wined3d_color *colour) +{ + colour_srgb->r = wined3d_srgb_from_linear(colour->r); + colour_srgb->g = wined3d_srgb_from_linear(colour->g); + colour_srgb->b = wined3d_srgb_from_linear(colour->b); + colour_srgb->a = colour->a; +} + +#define WINED3D_HIGHEST_TRANSFORM_STATE WINED3D_TS_WORLD_MATRIX(255) /* Highest value in wined3d_transform_state. */ void wined3d_check_gl_call(const struct wined3d_gl_info *gl_info, const char *file, unsigned int line, const char *name) DECLSPEC_HIDDEN; @@ -1472,13 +1539,13 @@ do { \ struct wined3d_bo_address { - GLuint buffer_object; + UINT_PTR buffer_object; BYTE *addr; }; struct wined3d_const_bo_address { - GLuint buffer_object; + UINT_PTR buffer_object; const BYTE *addr; }; @@ -1506,8 +1573,7 @@ struct wined3d_stream_info }; void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, - const struct wined3d_state *state, const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; + const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; struct wined3d_direct_dispatch_parameters { @@ -1562,7 +1628,6 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s const struct wined3d_draw_parameters *draw_parameters) DECLSPEC_HIDDEN; void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state, const struct wined3d_dispatch_parameters *dispatch_parameters) DECLSPEC_HIDDEN; -DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define eps 1e-8f @@ -1584,13 +1649,13 @@ enum wined3d_pipeline #define STATE_TEXTURESTAGE(stage, num) \ (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + 1 + (stage) * (WINED3D_HIGHEST_TEXTURE_STATE + 1) + (num)) #define STATE_IS_TEXTURESTAGE(a) \ - ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE)) + ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(WINED3D_MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE)) /* + 1 because samplers start with 0 */ -#define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num)) -#define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1)) +#define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(WINED3D_MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num)) +#define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(WINED3D_MAX_COMBINED_SAMPLERS - 1)) -#define STATE_GRAPHICS_SHADER(a) (STATE_SAMPLER(MAX_COMBINED_SAMPLERS) + (a)) +#define STATE_GRAPHICS_SHADER(a) (STATE_SAMPLER(WINED3D_MAX_COMBINED_SAMPLERS) + (a)) #define STATE_IS_GRAPHICS_SHADER(a) \ ((a) >= STATE_GRAPHICS_SHADER(0) && (a) < STATE_GRAPHICS_SHADER(WINED3D_SHADER_TYPE_GRAPHICS_COUNT)) @@ -1622,21 +1687,21 @@ enum wined3d_pipeline #define STATE_LIGHT_TYPE (STATE_VIEWPORT + 1) #define STATE_IS_LIGHT_TYPE(a) ((a) == STATE_LIGHT_TYPE) #define STATE_ACTIVELIGHT(a) (STATE_LIGHT_TYPE + 1 + (a)) -#define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS)) +#define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_ACTIVELIGHT(WINED3D_MAX_ACTIVE_LIGHTS)) -#define STATE_SCISSORRECT (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1) + 1) +#define STATE_SCISSORRECT (STATE_ACTIVELIGHT(WINED3D_MAX_ACTIVE_LIGHTS - 1) + 1) #define STATE_IS_SCISSORRECT(a) ((a) == STATE_SCISSORRECT) #define STATE_CLIPPLANE(a) (STATE_SCISSORRECT + 1 + (a)) -#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIP_DISTANCES - 1)) +#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(WINED3D_MAX_CLIP_DISTANCES - 1)) -#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIP_DISTANCES)) +#define STATE_MATERIAL (STATE_CLIPPLANE(WINED3D_MAX_CLIP_DISTANCES)) #define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL) -#define STATE_FRONTFACE (STATE_MATERIAL + 1) -#define STATE_IS_FRONTFACE(a) ((a) == STATE_FRONTFACE) +#define STATE_RASTERIZER (STATE_MATERIAL + 1) +#define STATE_IS_RASTERIZER(a) ((a) == STATE_RASTERIZER) -#define STATE_POINTSPRITECOORDORIGIN (STATE_FRONTFACE + 1) +#define STATE_POINTSPRITECOORDORIGIN (STATE_RASTERIZER + 1) #define STATE_IS_POINTSPRITECOORDORIGIN(a) ((a) == STATE_POINTSPRITECOORDORIGIN) #define STATE_BASEVERTEXINDEX (STATE_POINTSPRITECOORDORIGIN + 1) @@ -1657,7 +1722,10 @@ enum wined3d_pipeline #define STATE_BLEND (STATE_STREAM_OUTPUT + 1) #define STATE_IS_BLEND(a) ((a) == STATE_BLEND) -#define STATE_COMPUTE_OFFSET (STATE_BLEND + 1) +#define STATE_BLEND_FACTOR (STATE_BLEND + 1) +#define STATE_IS_BLEND_FACTOR(a) ((a) == STATE_BLEND_FACTOR) + +#define STATE_COMPUTE_OFFSET (STATE_BLEND_FACTOR + 1) #define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET) #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER) @@ -1708,14 +1776,14 @@ struct wined3d_fence { struct list entry; union wined3d_gl_fence_object object; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; }; HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence) DECLSPEC_HIDDEN; void wined3d_fence_destroy(struct wined3d_fence *fence) DECLSPEC_HIDDEN; -void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_device *device) DECLSPEC_HIDDEN; +void wined3d_fence_issue(struct wined3d_fence *fence, struct wined3d_device *device) DECLSPEC_HIDDEN; enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, - const struct wined3d_device *device) DECLSPEC_HIDDEN; + struct wined3d_device *device) DECLSPEC_HIDDEN; /* Direct3D terminology with little modifications. We do not have an issued * state because only the driver knows about it, but we have a created state @@ -1749,8 +1817,16 @@ struct wined3d_query LONG counter_main, counter_retrieved; struct list poll_list_entry; + + GLuint buffer_object; + UINT64 *map_ptr; }; +HRESULT wined3d_query_gl_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) DECLSPEC_HIDDEN; +void wined3d_query_gl_destroy_buffer_object(struct wined3d_context_gl *context_gl, + struct wined3d_query *query) DECLSPEC_HIDDEN; + struct wined3d_event_query { struct wined3d_query query; @@ -1765,7 +1841,7 @@ struct wined3d_occlusion_query struct list entry; GLuint id; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; UINT64 samples; BOOL started; }; @@ -1776,13 +1852,10 @@ struct wined3d_timestamp_query struct list entry; GLuint id; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; UINT64 timestamp; }; -void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; - union wined3d_gl_so_statistics_query { GLuint id[2]; @@ -1799,16 +1872,12 @@ struct wined3d_so_statistics_query struct list entry; union wined3d_gl_so_statistics_query u; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; unsigned int stream_idx; struct wined3d_query_data_so_statistics statistics; BOOL started; }; -void context_alloc_so_statistics_query(struct wined3d_context *context, - struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN; -void context_free_so_statistics_query(struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN; - union wined3d_gl_pipeline_statistics_query { GLuint id[11]; @@ -1834,21 +1903,23 @@ struct wined3d_pipeline_statistics_query struct list entry; union wined3d_gl_pipeline_statistics_query u; - struct wined3d_context *context; + struct wined3d_context_gl *context_gl; struct wined3d_query_data_pipeline_statistics statistics; BOOL started; }; -void context_alloc_pipeline_statistics_query(struct wined3d_context *context, - struct wined3d_pipeline_statistics_query *query) DECLSPEC_HIDDEN; -void context_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query) DECLSPEC_HIDDEN; - struct wined3d_gl_view { GLenum target; GLuint name; }; +struct wined3d_map_range +{ + unsigned int offset; + unsigned int size; +}; + struct wined3d_rendertarget_info { struct wined3d_gl_view gl_view; @@ -1857,23 +1928,20 @@ struct wined3d_rendertarget_info unsigned int layer_count; }; +struct wined3d_fb_state +{ + struct wined3d_rendertarget_view *render_targets[MAX_RENDER_TARGET_VIEWS]; + struct wined3d_rendertarget_view *depth_stencil; +}; + #define MAX_GL_FRAGMENT_SAMPLERS 32 struct wined3d_context { - const struct wined3d_gl_info *gl_info; const struct wined3d_d3d_info *d3d_info; - const struct StateEntry *state_table; - /* State dirtification - * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices - * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed, - * but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states - * only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states. - */ - DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ - DWORD numDirtyEntries; - DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ - unsigned int dirty_compute_states[STATE_COMPUTE_COUNT / (sizeof(unsigned int) * CHAR_BIT) + 1]; + const struct wined3d_state_entry *state_table; + uint32_t dirty_graphics_states[STATE_HIGHEST / (sizeof(uint32_t) * CHAR_BIT) + 1]; + uint32_t dirty_compute_states[STATE_COMPUTE_COUNT / (sizeof(uint32_t) * CHAR_BIT) + 1]; struct wined3d_device *device; struct wined3d_swapchain *swapchain; @@ -1882,143 +1950,255 @@ struct wined3d_context struct wined3d_texture *texture; unsigned int sub_resource_idx; } current_rt; - DWORD tid; /* Thread ID which owns this context at the moment */ /* Stores some information about the context state for optimization */ - DWORD render_offscreen : 1; - DWORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */ + DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */ + DWORD update_shader_resource_bindings : 1; + DWORD update_compute_shader_resource_bindings : 1; + DWORD update_unordered_access_view_bindings : 1; + DWORD update_compute_unordered_access_view_bindings : 1; DWORD last_swizzle_map : 16; /* MAX_ATTRIBS, 16 */ + DWORD last_was_rhw : 1; /* True iff last draw_primitive was in xyzrhw mode. */ DWORD last_was_pshader : 1; DWORD last_was_vshader : 1; + DWORD last_was_diffuse : 1; + DWORD last_was_specular : 1; DWORD last_was_normal : 1; - DWORD namedArraysLoaded : 1; - DWORD numberedArraysLoaded : 1; + + DWORD last_was_ffp_blit : 1; DWORD last_was_blit : 1; DWORD last_was_ckey : 1; - DWORD fog_coord : 1; - DWORD fog_enabled : 1; - DWORD num_untracked_materials : 2; /* Max value 2 */ - DWORD current : 1; - DWORD destroyed : 1; - DWORD valid : 1; - DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */ - DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */ - DWORD fixed_function_usage_map : 8; /* MAX_TEXTURES, 8 */ - DWORD lowest_disabled_stage : 4; /* Max MAX_TEXTURES, 8 */ + DWORD namedArraysLoaded : 1; + DWORD texShaderBumpMap : 8; /* WINED3D_MAX_TEXTURES, 8 */ + DWORD lastWasPow2Texture : 8; /* WINED3D_MAX_TEXTURES, 8 */ + DWORD fixed_function_usage_map : 8; /* WINED3D_MAX_TEXTURES, 8 */ + DWORD lowest_disabled_stage : 4; /* Max WINED3D_MAX_TEXTURES, 8 */ + DWORD use_immediate_mode_draw : 1; - DWORD rebind_fbo : 1; - DWORD needs_set : 1; - DWORD hdc_is_private : 1; - DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */ - DWORD update_shader_resource_bindings : 1; - DWORD update_compute_shader_resource_bindings : 1; - DWORD update_unordered_access_view_bindings : 1; - DWORD update_compute_unordered_access_view_bindings : 1; DWORD uses_uavs : 1; - DWORD destroy_delayed : 1; DWORD transform_feedback_active : 1; DWORD transform_feedback_paused : 1; - DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */ - DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */ + DWORD fog_coord : 1; + DWORD render_offscreen : 1; + DWORD current : 1; + DWORD destroyed : 1; + DWORD destroy_delayed : 1; + DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */ DWORD last_was_dual_blend : 1; - DWORD padding : 8; + DWORD padding : 14; + DWORD constant_update_mask; - DWORD numbered_array_mask; - GLenum tracking_parm; /* Which source is tracking current colour */ - GLenum untracked_materials[2]; - UINT blit_w, blit_h; - enum fogsource fog_source; - DWORD active_texture; - DWORD *texture_type; + DWORD numbered_array_mask; + enum fogsource fog_source; UINT instance_count; - /* The actual opengl context */ - UINT level; + void *shader_backend_data; + void *fragment_pipe_data; + + struct wined3d_stream_info stream_info; + + /* Fences for GL_APPLE_flush_buffer_range */ + struct wined3d_fence *buffer_fences[MAX_ATTRIBS]; + unsigned int buffer_fence_count; + + unsigned int viewport_count; + unsigned int scissor_rect_count; +}; + +void wined3d_context_cleanup(struct wined3d_context *context) DECLSPEC_HIDDEN; + +HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + +struct wined3d_context_gl +{ + struct wined3d_context c; + + const struct wined3d_gl_info *gl_info; + + DWORD tid; /* Thread ID which owns this context at the moment. */ + + uint32_t dc_is_private : 1; + uint32_t dc_has_format : 1; /* Only meaningful for private DCs. */ + uint32_t fog_enabled : 1; + uint32_t diffuse_attrib_to_1 : 1; + uint32_t rebind_fbo : 1; + uint32_t untracked_material_count : 2; /* Max value 2 */ + uint32_t needs_set : 1; + uint32_t valid : 1; + uint32_t padding : 23; + + uint32_t default_attrib_value_set; + + GLenum tracking_parm; /* Which source is tracking current colour. */ + GLenum untracked_materials[2]; + SIZE blit_size; + unsigned int active_texture; + + GLenum *texture_type; + + /* The WGL context. */ + unsigned int level; HGLRC restore_ctx; HDC restore_dc; int restore_pf; HWND restore_pf_win; - HGLRC glCtx; - HWND win_handle; - HDC hdc; + HGLRC gl_ctx; + HDC dc; int pixel_format; - GLint aux_buffers; - - void *shader_backend_data; - void *fragment_pipe_data; - - /* FBOs */ - UINT fbo_entry_count; - struct list fbo_list; - struct list fbo_destroy_list; - struct fbo_entry *current_fbo; - GLuint fbo_read_binding; - GLuint fbo_draw_binding; + HWND window; + GLint aux_buffers; + + /* FBOs. */ + unsigned int fbo_entry_count; + struct list fbo_list; + struct list fbo_destroy_list; + struct fbo_entry *current_fbo; + GLuint fbo_read_binding; + GLuint fbo_draw_binding; struct wined3d_rendertarget_info blit_targets[MAX_RENDER_TARGET_VIEWS]; - DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */ + uint32_t draw_buffers_mask; /* Enabled draw buffers, 31 max. */ + + /* Queries. */ + struct list occlusion_queries; + struct list fences; + struct list timestamp_queries; + struct list so_statistics_queries; + struct list pipeline_statistics_queries; - /* Queries */ GLuint *free_occlusion_queries; SIZE_T free_occlusion_query_size; unsigned int free_occlusion_query_count; - struct list occlusion_queries; union wined3d_gl_fence_object *free_fences; SIZE_T free_fence_size; unsigned int free_fence_count; - struct list fences; GLuint *free_timestamp_queries; SIZE_T free_timestamp_query_size; unsigned int free_timestamp_query_count; - struct list timestamp_queries; union wined3d_gl_so_statistics_query *free_so_statistics_queries; SIZE_T free_so_statistics_query_size; unsigned int free_so_statistics_query_count; - struct list so_statistics_queries; union wined3d_gl_pipeline_statistics_query *free_pipeline_statistics_queries; SIZE_T free_pipeline_statistics_query_size; unsigned int free_pipeline_statistics_query_count; - struct list pipeline_statistics_queries; - struct wined3d_stream_info stream_info; + GLuint blit_vbo; - /* Fences for GL_APPLE_flush_buffer_range */ - struct wined3d_fence *buffer_fences[MAX_ATTRIBS]; - unsigned int buffer_fence_count; + unsigned int tex_unit_map[WINED3D_MAX_COMBINED_SAMPLERS]; + unsigned int rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS]; - DWORD tex_unit_map[MAX_COMBINED_SAMPLERS]; - DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS]; + /* Extension emulation. */ + GLint gl_fog_source; + GLfloat fog_coord_value; + GLfloat colour[4], fog_start, fog_end, fog_colour[4]; - /* Extension emulation */ - GLint gl_fog_source; - GLfloat fog_coord_value; - GLfloat color[4], fogstart, fogend, fogcolor[4]; - GLuint dummy_arbfp_prog; + GLuint dummy_arbfp_prog; }; -struct wined3d_fb_state +static inline struct wined3d_context_gl *wined3d_context_gl(struct wined3d_context *context) { - struct wined3d_rendertarget_view *render_targets[MAX_RENDER_TARGET_VIEWS]; - struct wined3d_rendertarget_view *depth_stencil; + return CONTAINING_RECORD(context, struct wined3d_context_gl, c); +} + +static inline const struct wined3d_context_gl *wined3d_context_gl_const(const struct wined3d_context *context) +{ + return CONTAINING_RECORD(context, struct wined3d_context_gl, c); +} + +struct wined3d_context *wined3d_context_gl_acquire(const struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN; +void wined3d_context_gl_active_texture(struct wined3d_context_gl *context_gl, + const struct wined3d_gl_info *gl_info, unsigned int unit) DECLSPEC_HIDDEN; +void wined3d_context_gl_alloc_fence(struct wined3d_context_gl *context_gl, + struct wined3d_fence *fence) DECLSPEC_HIDDEN; +void wined3d_context_gl_alloc_occlusion_query(struct wined3d_context_gl *context_gl, + struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_alloc_pipeline_statistics_query(struct wined3d_context_gl *context_gl, + struct wined3d_pipeline_statistics_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_alloc_so_statistics_query(struct wined3d_context_gl *context_gl, + struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_alloc_timestamp_query(struct wined3d_context_gl *context_gl, + struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, + const struct wined3d_device *device) DECLSPEC_HIDDEN; +BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, const struct wined3d_state *state, + unsigned int rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; +void wined3d_context_gl_apply_fbo_state_blit(struct wined3d_context_gl *context_gl, GLenum target, + struct wined3d_resource *rt, unsigned int rt_sub_resource_idx, + struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; +void wined3d_context_gl_apply_ffp_blit_state(struct wined3d_context_gl *context_gl, + const struct wined3d_device *device) DECLSPEC_HIDDEN; +void wined3d_context_gl_bind_bo(struct wined3d_context_gl *context_gl, GLenum binding, GLuint name) DECLSPEC_HIDDEN; +void wined3d_context_gl_bind_dummy_textures(const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl, + GLenum target, GLuint name) DECLSPEC_HIDDEN; +void wined3d_context_gl_check_fbo_status(const struct wined3d_context_gl *context_gl, GLenum target) DECLSPEC_HIDDEN; +void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl, + const struct wined3d_bo_address *dst, GLenum dst_binding, + const struct wined3d_bo_address *src, GLenum src_binding, size_t size) DECLSPEC_HIDDEN; +void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_draw_shaded_quad(struct wined3d_context_gl *context_gl, struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect, + enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +void wined3d_context_gl_draw_textured_quad(struct wined3d_context_gl *context_gl, + struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +void wined3d_context_gl_enable_clip_distances(struct wined3d_context_gl *context_gl, uint32_t mask) DECLSPEC_HIDDEN; +void wined3d_context_gl_end_transform_feedback(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN; +void wined3d_context_gl_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_free_so_statistics_query(struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN; +void wined3d_context_gl_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; +struct wined3d_context_gl *wined3d_context_gl_get_current(void) DECLSPEC_HIDDEN; +GLenum wined3d_context_gl_get_offscreen_gl_buffer(const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +const unsigned int *wined3d_context_gl_get_tex_unit_mapping(const struct wined3d_context_gl *context_gl, + const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count) DECLSPEC_HIDDEN; +HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, + struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_load_tex_coords(const struct wined3d_context_gl *context_gl, + const struct wined3d_stream_info *si, GLuint *current_bo, const struct wined3d_state *state) DECLSPEC_HIDDEN; +void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl, + const struct wined3d_bo_address *data, size_t size, GLenum binding, DWORD flags) DECLSPEC_HIDDEN; +struct wined3d_context_gl *wined3d_context_gl_reacquire(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_release(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +BOOL wined3d_context_gl_set_current(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_set_draw_buffer(struct wined3d_context_gl *context_gl, GLenum buffer) DECLSPEC_HIDDEN; +void wined3d_context_gl_texture_update(struct wined3d_context_gl *context_gl, + const struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_unload_tex_coords(const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *data, + GLenum binding, unsigned int range_count, const struct wined3d_map_range *ranges) DECLSPEC_HIDDEN; +void wined3d_context_gl_update_stream_sources(struct wined3d_context_gl *context_gl, + const struct wined3d_state *state) DECLSPEC_HIDDEN; + +struct wined3d_context_vk +{ + struct wined3d_context c; }; +void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; +HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); -struct StateEntry +struct wined3d_state_entry { - DWORD representative; + unsigned int representative; APPLYSTATEFUNC apply; }; -struct StateEntryTemplate +struct wined3d_state_entry_template { DWORD state; - struct StateEntry content; - enum wined3d_gl_extension extension; + struct wined3d_state_entry content; + unsigned int extension; }; #define WINED3D_FRAGMENT_CAP_PROJ_CONTROL 0x00000001 @@ -2037,17 +2217,17 @@ struct fragment_caps #define GL_EXT_EMUL_ARB_MULTITEXTURE 0x00000001 #define GL_EXT_EMUL_EXT_FOG_COORD 0x00000002 -struct fragment_pipeline +struct wined3d_fragment_pipe_ops { - void (*enable_extension)(const struct wined3d_gl_info *gl_info, BOOL enable); - void (*get_caps)(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps); + void (*fp_enable)(const struct wined3d_context *context, BOOL enable); + void (*get_caps)(const struct wined3d_adapter *adapter, struct fragment_caps *caps); DWORD (*get_emul_mask)(const struct wined3d_gl_info *gl_info); void *(*alloc_private)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv); - void (*free_private)(struct wined3d_device *device); + void (*free_private)(struct wined3d_device *device, struct wined3d_context *context); BOOL (*allocate_context_data)(struct wined3d_context *context); void (*free_context_data)(struct wined3d_context *context); BOOL (*color_fixup_supported)(struct color_fixup_desc fixup); - const struct StateEntryTemplate *states; + const struct wined3d_state_entry_template *states; }; struct wined3d_vertex_caps @@ -2066,42 +2246,38 @@ struct wined3d_vertex_caps struct wined3d_vertex_pipe_ops { - void (*vp_enable)(const struct wined3d_gl_info *gl_info, BOOL enable); - void (*vp_get_caps)(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps); + void (*vp_enable)(const struct wined3d_context *context, BOOL enable); + void (*vp_get_caps)(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps); DWORD (*vp_get_emul_mask)(const struct wined3d_gl_info *gl_info); void *(*vp_alloc)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv); - void (*vp_free)(struct wined3d_device *device); - const struct StateEntryTemplate *vp_states; + void (*vp_free)(struct wined3d_device *device, struct wined3d_context *context); + const struct wined3d_state_entry_template *vp_states; }; -extern const struct StateEntryTemplate misc_state_template[] DECLSPEC_HIDDEN; -extern const struct fragment_pipeline none_fragment_pipe DECLSPEC_HIDDEN; -extern const struct fragment_pipeline ffp_fragment_pipeline DECLSPEC_HIDDEN; -extern const struct fragment_pipeline atifs_fragment_pipeline DECLSPEC_HIDDEN; -extern const struct fragment_pipeline arbfp_fragment_pipeline DECLSPEC_HIDDEN; -extern const struct fragment_pipeline nvts_fragment_pipeline DECLSPEC_HIDDEN; -extern const struct fragment_pipeline nvrc_fragment_pipeline DECLSPEC_HIDDEN; -extern const struct fragment_pipeline glsl_fragment_pipe DECLSPEC_HIDDEN; +extern const struct wined3d_state_entry_template misc_state_template[] DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops none_fragment_pipe DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops ffp_fragment_pipeline DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops atifs_fragment_pipeline DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops arbfp_fragment_pipeline DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops nvts_fragment_pipeline DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops nvrc_fragment_pipeline DECLSPEC_HIDDEN; +extern const struct wined3d_fragment_pipe_ops glsl_fragment_pipe DECLSPEC_HIDDEN; extern const struct wined3d_vertex_pipe_ops none_vertex_pipe DECLSPEC_HIDDEN; extern const struct wined3d_vertex_pipe_ops ffp_vertex_pipe DECLSPEC_HIDDEN; extern const struct wined3d_vertex_pipe_ops glsl_vertex_pipe DECLSPEC_HIDDEN; /* "Base" state table */ -HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs, - const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, - const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment, - const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN; - -struct wined3d_surface; +HRESULT compile_state_table(struct wined3d_state_entry *state_table, APPLYSTATEFUNC **dev_multistate_funcs, + const struct wined3d_d3d_info *d3d_info, const BOOL *supported_extensions, + const struct wined3d_vertex_pipe_ops *vertex, const struct wined3d_fragment_pipe_ops *fragment, + const struct wined3d_state_entry_template *misc) DECLSPEC_HIDDEN; enum wined3d_blit_op { WINED3D_BLIT_OP_COLOR_BLIT, WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST, WINED3D_BLIT_OP_COLOR_BLIT_CKEY, - WINED3D_BLIT_OP_COLOR_FILL, - WINED3D_BLIT_OP_DEPTH_FILL, WINED3D_BLIT_OP_DEPTH_BLIT, WINED3D_BLIT_OP_RAW_BLIT, }; @@ -2119,9 +2295,10 @@ struct wined3d_blitter_ops unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil); DWORD (*blitter_blit)(struct wined3d_blitter *blitter, enum wined3d_blit_op op, struct wined3d_context *context, - struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, - struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, - const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter); + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, + const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + DWORD dst_location, const RECT *dst_rect, const struct wined3d_color_key *colour_key, + enum wined3d_texture_filter_type filter); }; void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, @@ -2131,66 +2308,31 @@ void wined3d_fbo_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; +struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next, + const struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_raw_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; +BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_gl_info *gl_info, + const struct wined3d_resource *src_resource, DWORD src_location, + const struct wined3d_resource *dst_resource, DWORD dst_location) DECLSPEC_HIDDEN; + BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) DECLSPEC_HIDDEN; -struct wined3d_context *context_acquire(const struct wined3d_device *device, - struct wined3d_texture *texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN; -void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *fence) DECLSPEC_HIDDEN; -void context_alloc_occlusion_query(struct wined3d_context *context, - struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; -void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; -BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state, - UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; -void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, - struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; -void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, - unsigned int unit) DECLSPEC_HIDDEN; -void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) DECLSPEC_HIDDEN; -void context_bind_dummy_textures(const struct wined3d_device *device, - const struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) DECLSPEC_HIDDEN; -void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN; -void context_copy_bo_address(struct wined3d_context *context, - const struct wined3d_bo_address *dst, GLenum dst_binding, - const struct wined3d_bo_address *src, GLenum src_binding, size_t size) DECLSPEC_HIDDEN; -struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_texture *target, - const struct wined3d_format *ds_format) DECLSPEC_HIDDEN; HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN; -void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN; -void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN; -void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; -struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN; -GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) DECLSPEC_HIDDEN; -const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, - const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count) DECLSPEC_HIDDEN; DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN; void context_gl_resource_released(struct wined3d_device *device, GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN; void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN; void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN; -void *context_map_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, - size_t size, GLenum binding, DWORD flags) DECLSPEC_HIDDEN; -struct wined3d_context *context_reacquire(const struct wined3d_device *device, - struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN; -void context_resource_released(const struct wined3d_device *device, - struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN; -void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN; -BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; -void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; +void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; +void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, + unsigned int sub_resource_idx) DECLSPEC_HIDDEN; void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN; void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void context_unmap_bo_address(struct wined3d_context *context, - const struct wined3d_bo_address *data, GLenum binding) DECLSPEC_HIDDEN; /***************************************************************************** * Internal representation of a light @@ -2232,6 +2374,7 @@ enum wined3d_pci_vendor HW_VENDOR_AMD = 0x1002, HW_VENDOR_NVIDIA = 0x10de, HW_VENDOR_VMWARE = 0x15ad, + HW_VENDOR_REDHAT = 0x1af4, HW_VENDOR_INTEL = 0x8086, }; @@ -2263,6 +2406,7 @@ enum wined3d_pci_device CARD_AMD_RADEON_HD5900 = 0x689c, CARD_AMD_RADEON_HD6300 = 0x9803, CARD_AMD_RADEON_HD6400 = 0x6770, + CARD_AMD_RADEON_HD6490M = 0x6760, CARD_AMD_RADEON_HD6410D = 0x9644, CARD_AMD_RADEON_HD6480G = 0x9648, CARD_AMD_RADEON_HD6550D = 0x9640, @@ -2274,6 +2418,7 @@ enum wined3d_pci_device CARD_AMD_RADEON_HD7660D = 0x9901, CARD_AMD_RADEON_HD7700 = 0x683d, CARD_AMD_RADEON_HD7800 = 0x6819, + CARD_AMD_RADEON_HD7870 = 0x6818, CARD_AMD_RADEON_HD7900 = 0x679a, CARD_AMD_RADEON_HD8600M = 0x6660, CARD_AMD_RADEON_HD8670 = 0x6610, @@ -2282,9 +2427,16 @@ enum wined3d_pci_device CARD_AMD_RADEON_R7 = 0x130f, CARD_AMD_RADEON_R9_285 = 0x6939, CARD_AMD_RADEON_R9_290 = 0x67b1, + CARD_AMD_RADEON_R9_290X = 0x67b0, CARD_AMD_RADEON_R9_FURY = 0x7300, + CARD_AMD_RADEON_R9_M370X = 0x6821, + CARD_AMD_RADEON_R9_M380 = 0x6647, + CARD_AMD_RADEON_R9_M395X = 0x6920, CARD_AMD_RADEON_RX_460 = 0x67ef, CARD_AMD_RADEON_RX_480 = 0x67df, + CARD_AMD_RADEON_RX_VEGA_10 = 0x687f, + CARD_AMD_RADEON_RX_VEGA_12 = 0x69af, + CARD_AMD_RADEON_RX_VEGA_20 = 0x66af, CARD_NVIDIA_RIVA_128 = 0x0018, CARD_NVIDIA_RIVA_TNT = 0x0020, @@ -2358,6 +2510,7 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GT610 = 0x104a, CARD_NVIDIA_GEFORCE_GT630 = 0x0f00, CARD_NVIDIA_GEFORCE_GT630M = 0x0de9, + CARD_NVIDIA_GEFORCE_GT640 = 0x0fc1, CARD_NVIDIA_GEFORCE_GT640M = 0x0fd2, CARD_NVIDIA_GEFORCE_GT650M = 0x0fd1, CARD_NVIDIA_GEFORCE_GTX650 = 0x0fc6, @@ -2367,13 +2520,16 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX660TI = 0x1183, CARD_NVIDIA_GEFORCE_GTX670 = 0x1189, CARD_NVIDIA_GEFORCE_GTX670MX = 0x11a1, - CARD_NVIDIA_GEFORCE_GTX675MX = 0x11a7, + CARD_NVIDIA_GEFORCE_GTX675MX_1 = 0x11a7, + CARD_NVIDIA_GEFORCE_GTX675MX_2 = 0x11a2, CARD_NVIDIA_GEFORCE_GTX680 = 0x1180, CARD_NVIDIA_GEFORCE_GTX690 = 0x1188, + CARD_NVIDIA_GEFORCE_GT720 = 0x128b, CARD_NVIDIA_GEFORCE_GT730 = 0x1287, CARD_NVIDIA_GEFORCE_GT730M = 0x0fe1, CARD_NVIDIA_GEFORCE_GT740M = 0x1292, CARD_NVIDIA_GEFORCE_GT750M = 0x0fe9, + CARD_NVIDIA_GEFORCE_GT755M = 0x0fcd, CARD_NVIDIA_GEFORCE_GTX750 = 0x1381, CARD_NVIDIA_GEFORCE_GTX750TI = 0x1380, CARD_NVIDIA_GEFORCE_GTX760 = 0x1187, @@ -2381,7 +2537,9 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX765M = 0x11e2, CARD_NVIDIA_GEFORCE_GTX770M = 0x11e0, CARD_NVIDIA_GEFORCE_GTX770 = 0x1184, + CARD_NVIDIA_GEFORCE_GTX775M = 0x119d, CARD_NVIDIA_GEFORCE_GTX780 = 0x1004, + CARD_NVIDIA_GEFORCE_GTX780M = 0x119e, CARD_NVIDIA_GEFORCE_GTX780TI = 0x100a, CARD_NVIDIA_GEFORCE_GTXTITAN = 0x1005, CARD_NVIDIA_GEFORCE_GTXTITANB = 0x100c, @@ -2405,11 +2563,20 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX980 = 0x13c0, CARD_NVIDIA_GEFORCE_GTX980TI = 0x17c8, CARD_NVIDIA_GEFORCE_GTX1050 = 0x1c81, + CARD_NVIDIA_GEFORCE_GTX1050TI = 0x1c82, CARD_NVIDIA_GEFORCE_GTX1060 = 0x1c03, CARD_NVIDIA_GEFORCE_GTX1070 = 0x1b81, CARD_NVIDIA_GEFORCE_GTX1080 = 0x1b80, CARD_NVIDIA_GEFORCE_GTX1080TI = 0x1b06, CARD_NVIDIA_TITANX_PASCAL = 0x1b00, + CARD_NVIDIA_TITANV = 0x1d81, + CARD_NVIDIA_GEFORCE_GTX1660TI = 0x2182, + CARD_NVIDIA_GEFORCE_RTX2060 = 0x1f08, + CARD_NVIDIA_GEFORCE_RTX2070 = 0x1f07, + CARD_NVIDIA_GEFORCE_RTX2080 = 0x1e87, + CARD_NVIDIA_GEFORCE_RTX2080TI = 0x1e07, + + CARD_REDHAT_VIRGL = 0x1010, CARD_VMWARE_SVGA3D = 0x0405, @@ -2449,7 +2616,8 @@ enum wined3d_pci_device CARD_INTEL_IVBS = 0x015a, CARD_INTEL_HWD = 0x0412, CARD_INTEL_HWM = 0x0416, - CARD_INTEL_HD5000 = 0x0a26, + CARD_INTEL_HD5000_1 = 0x0a26, + CARD_INTEL_HD5000_2 = 0x0422, CARD_INTEL_I5100_1 = 0x0a22, CARD_INTEL_I5100_2 = 0x0a2a, CARD_INTEL_I5100_3 = 0x0a2b, @@ -2459,6 +2627,7 @@ enum wined3d_pci_device CARD_INTEL_IP5200_3 = 0x0d2a, CARD_INTEL_IP5200_4 = 0x0d2b, CARD_INTEL_IP5200_5 = 0x0d2e, + CARD_INTEL_IP5200_6 = 0x0c22, CARD_INTEL_HD5300 = 0x161e, CARD_INTEL_HD5500 = 0x1616, CARD_INTEL_HD5600 = 0x1612, @@ -2483,6 +2652,11 @@ enum wined3d_pci_device CARD_INTEL_IP580_2 = 0x193b, CARD_INTEL_IPP580_1 = 0x193a, CARD_INTEL_IPP580_2 = 0x193d, + CARD_INTEL_UHD617 = 0x87c0, + CARD_INTEL_UHD620 = 0x3ea0, + CARD_INTEL_HD620 = 0x5916, + CARD_INTEL_HD630_1 = 0x5912, + CARD_INTEL_HD630_2 = 0x591b, }; struct wined3d_fbo_ops @@ -2533,11 +2707,8 @@ struct wined3d_gl_limits unsigned int combined_samplers; UINT general_combiners; UINT user_clip_distances; - UINT texture_size; + unsigned int texture_size; UINT texture3d_size; - float pointsize_max; - float pointsize_min; - UINT blends; UINT anisotropy; float shininess; UINT samples; @@ -2551,6 +2722,7 @@ struct wined3d_gl_limits UINT glsl_varyings; UINT glsl_vs_float_constants; UINT glsl_ps_float_constants; + UINT glsl_max_uniform_block_size; UINT arb_vs_float_constants; UINT arb_vs_native_constants; @@ -2582,43 +2754,198 @@ struct wined3d_gl_info struct opengl_funcs gl_ops; struct wined3d_fbo_ops fbo_ops; - struct wined3d_format *formats; - unsigned int format_count; + void (WINE_GLAPI *p_glDisableWINE)(GLenum cap); + void (WINE_GLAPI *p_glEnableWINE)(GLenum cap); +}; + +/* The driver names reflect the lowest GPU supported + * by a certain driver, so DRIVER_AMD_R300 supports + * R3xx, R4xx and R5xx GPUs. */ +enum wined3d_display_driver +{ + DRIVER_AMD_RAGE_128PRO, + DRIVER_AMD_R100, + DRIVER_AMD_R300, + DRIVER_AMD_R600, + DRIVER_AMD_RX, + DRIVER_INTEL_GMA800, + DRIVER_INTEL_GMA900, + DRIVER_INTEL_GMA950, + DRIVER_INTEL_GMA3000, + DRIVER_INTEL_HD4000, + DRIVER_NVIDIA_TNT, + DRIVER_NVIDIA_GEFORCE2MX, + DRIVER_NVIDIA_GEFORCEFX, + DRIVER_NVIDIA_GEFORCE6, + DRIVER_NVIDIA_GEFORCE8, + DRIVER_REDHAT_VIRGL, + DRIVER_VMWARE, + DRIVER_WINE, + DRIVER_UNKNOWN, +}; + +struct wined3d_gpu_description +{ + enum wined3d_pci_vendor vendor; + enum wined3d_pci_device device; + const char *description; + enum wined3d_display_driver driver; + unsigned int vidmem; }; +const struct wined3d_gpu_description *wined3d_get_gpu_description(enum wined3d_pci_vendor vendor, + enum wined3d_pci_device device) DECLSPEC_HIDDEN; +const struct wined3d_gpu_description *wined3d_get_user_override_gpu_description(enum wined3d_pci_vendor vendor, + enum wined3d_pci_device device) DECLSPEC_HIDDEN; +enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *vendor, + enum wined3d_feature_level feature_level) DECLSPEC_HIDDEN; + +/* 512 in Direct3D 8/9, 128 in DXGI. */ +#define WINED3D_MAX_DEVICE_IDENTIFIER_LENGTH 512 + struct wined3d_driver_info { enum wined3d_pci_vendor vendor; enum wined3d_pci_device device; const char *name; - const char *description; + char description[WINED3D_MAX_DEVICE_IDENTIFIER_LENGTH]; UINT64 vram_bytes; + UINT64 sysmem_bytes; DWORD version_high; DWORD version_low; }; +void wined3d_driver_info_init(struct wined3d_driver_info *driver_info, + const struct wined3d_gpu_description *gpu_description, + UINT64 vram_bytes, UINT64 sysmem_bytes) DECLSPEC_HIDDEN; + +struct wined3d_adapter_ops +{ + void (*adapter_destroy)(struct wined3d_adapter *adapter); + HRESULT (*adapter_create_device)(struct wined3d *wined3d, const struct wined3d_adapter *adapter, + enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, + BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, + struct wined3d_device_parent *device_parent, struct wined3d_device **device); + void (*adapter_destroy_device)(struct wined3d_device *device); + struct wined3d_context *(*adapter_acquire_context)(struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx); + void (*adapter_release_context)(struct wined3d_context *context); + void (*adapter_get_wined3d_caps)(const struct wined3d_adapter *adapter, struct wined3d_caps *caps); + BOOL (*adapter_check_format)(const struct wined3d_adapter *adapter, + const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format, + const struct wined3d_format *ds_format); + HRESULT (*adapter_init_3d)(struct wined3d_device *device); + void (*adapter_uninit_3d)(struct wined3d_device *device); + void *(*adapter_map_bo_address)(struct wined3d_context *context, + const struct wined3d_bo_address *data, size_t size, uint32_t bind_flags, uint32_t map_flags); + void (*adapter_unmap_bo_address)(struct wined3d_context *context, const struct wined3d_bo_address *data, + uint32_t bind_flags, unsigned int range_count, const struct wined3d_map_range *ranges); + void (*adapter_copy_bo_address)(struct wined3d_context *context, + const struct wined3d_bo_address *dst, uint32_t dst_bind_flags, + const struct wined3d_bo_address *src, uint32_t src_bind_flags, size_t size); + HRESULT (*adapter_create_swapchain)(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain); + void (*adapter_destroy_swapchain)(struct wined3d_swapchain *swapchain); + HRESULT (*adapter_create_buffer)(struct wined3d_device *device, const struct wined3d_buffer_desc *desc, + const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_buffer **buffer); + void (*adapter_destroy_buffer)(struct wined3d_buffer *buffer); + HRESULT (*adapter_create_texture)(struct wined3d_device *device, const struct wined3d_resource_desc *desc, + unsigned int layer_count, unsigned int level_count, uint32_t flags, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); + void (*adapter_destroy_texture)(struct wined3d_texture *texture); + HRESULT (*adapter_create_rendertarget_view)(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_rendertarget_view **view); + void (*adapter_destroy_rendertarget_view)(struct wined3d_rendertarget_view *view); + HRESULT (*adapter_create_shader_resource_view)(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view); + void (*adapter_destroy_shader_resource_view)(struct wined3d_shader_resource_view *view); + HRESULT (*adapter_create_unordered_access_view)(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view); + void (*adapter_destroy_unordered_access_view)(struct wined3d_unordered_access_view *view); + HRESULT (*adapter_create_sampler)(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler); + void (*adapter_destroy_sampler)(struct wined3d_sampler *sampler); + HRESULT (*adapter_create_query)(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query); + void (*adapter_destroy_query)(struct wined3d_query *query); + void (*adapter_flush_context)(struct wined3d_context *context); + void (*adapter_clear_uav)(struct wined3d_context *context, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value); +}; + /* The adapter structure */ struct wined3d_adapter { - UINT ordinal; + unsigned int ordinal; POINT monitor_position; enum wined3d_format_id screen_format; struct wined3d_gl_info gl_info; struct wined3d_d3d_info d3d_info; struct wined3d_driver_info driver_info; - WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */ - unsigned int cfg_count; - struct wined3d_pixel_format *cfgs; - UINT64 vram_bytes; UINT64 vram_bytes_used; + GUID driver_uuid; + GUID device_uuid; LUID luid; + WCHAR device_name[CCHDEVICENAME]; /* for use with e.g. ChangeDisplaySettings() */ + + void *formats; + size_t format_size; + const struct wined3d_vertex_pipe_ops *vertex_pipe; - const struct fragment_pipeline *fragment_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; const struct wined3d_shader_backend_ops *shader_backend; + const struct wined3d_adapter_ops *adapter_ops; }; +BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal, + const struct wined3d_adapter_ops *adapter_ops) DECLSPEC_HIDDEN; +void wined3d_adapter_cleanup(struct wined3d_adapter *adapter) DECLSPEC_HIDDEN; + +struct wined3d_adapter_gl +{ + struct wined3d_adapter a; + + struct wined3d_pixel_format *pixel_formats; + unsigned int pixel_format_count; +}; + +static inline struct wined3d_adapter_gl *wined3d_adapter_gl(struct wined3d_adapter *adapter) +{ + return CONTAINING_RECORD(adapter, struct wined3d_adapter_gl, a); +} + +static inline const struct wined3d_adapter_gl *wined3d_adapter_gl_const(const struct wined3d_adapter *adapter) +{ + return CONTAINING_RECORD(adapter, struct wined3d_adapter_gl, a); +} + +struct wined3d_adapter *wined3d_adapter_gl_create(unsigned int ordinal, + unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN; + +struct wined3d_adapter_vk +{ + struct wined3d_adapter a; + + struct wined3d_vk_info vk_info; + VkPhysicalDevice physical_device; + + VkPhysicalDeviceLimits device_limits; +}; + +static inline struct wined3d_adapter_vk *wined3d_adapter_vk(struct wined3d_adapter *adapter) +{ + return CONTAINING_RECORD(adapter, struct wined3d_adapter_vk, a); +} + +struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal, + unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN; + struct wined3d_caps_gl_ctx { HDC dc; @@ -2632,25 +2959,22 @@ struct wined3d_caps_gl_ctx GLuint test_program_id; }; -BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, +BOOL wined3d_adapter_gl_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN; +BOOL wined3d_adapter_no3d_init_format_info(struct wined3d_adapter *adapter) DECLSPEC_HIDDEN; +BOOL wined3d_adapter_vk_init_format_info(struct wined3d_adapter_vk *adapter_vk, + const struct wined3d_vk_info *vk_info) DECLSPEC_HIDDEN; UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) DECLSPEC_HIDDEN; BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN; void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext) DECLSPEC_HIDDEN; -enum projection_types -{ - proj_none = 0, - proj_count3 = 1, - proj_count4 = 2 -}; - -enum dst_arg +enum wined3d_projection_type { - resultreg = 0, - tempreg = 1 + WINED3D_PROJECTION_NONE = 0, + WINED3D_PROJECTION_COUNT3 = 1, + WINED3D_PROJECTION_COUNT4 = 2 }; /***************************************************************************** @@ -2671,14 +2995,14 @@ struct texture_stage_op struct color_fixup_desc color_fixup; unsigned tex_type : 3; - unsigned dst : 1; + unsigned tmp_dst : 1; unsigned projected : 2; unsigned padding : 10; }; struct ffp_frag_settings { - struct texture_stage_op op[MAX_TEXTURES]; + struct texture_stage_op op[WINED3D_MAX_TEXTURES]; enum wined3d_ffp_ps_fog_mode fog; unsigned char sRGB_write; unsigned char emul_clipplanes; @@ -2701,7 +3025,6 @@ int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb extern const struct wined3d_parent_ops wined3d_null_parent_ops DECLSPEC_HIDDEN; -unsigned int wined3d_max_compat_varyings(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state, struct ffp_frag_settings *settings, BOOL ignore_textype) DECLSPEC_HIDDEN; const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, @@ -2709,9 +3032,6 @@ const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *frag void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN; void wined3d_ftoa(float value, char *s) DECLSPEC_HIDDEN; -extern const float wined3d_srgb_const0[] DECLSPEC_HIDDEN; -extern const float wined3d_srgb_const1[] DECLSPEC_HIDDEN; - enum wined3d_ffp_vs_fog_mode { WINED3D_FFP_VS_FOG_OFF = 0, @@ -2754,7 +3074,7 @@ struct wined3d_ffp_vs_settings DWORD vb_indices : 1; DWORD sw_blending : 1; - DWORD texgen[MAX_TEXTURES]; + DWORD texgen[WINED3D_MAX_TEXTURES]; }; struct wined3d_ffp_vs_desc @@ -2769,15 +3089,19 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, struct wined3d { LONG ref; - DWORD flags; - UINT adapter_count; - struct wined3d_adapter adapters[1]; + unsigned int flags; + unsigned int adapter_count; + struct wined3d_adapter *adapters[1]; }; +BOOL wined3d_filter_messages(HWND window, BOOL filter) DECLSPEC_HIDDEN; +void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN; -BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN; +void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN; +BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size) DECLSPEC_HIDDEN; + struct wined3d_blend_state { LONG refcount; @@ -2815,6 +3139,16 @@ struct wined3d_stream_state UINT flags; }; +#define LIGHTMAP_SIZE 43 +#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) + +struct wined3d_light_state +{ + /* Light hashmap. Collisions are handled using linked lists. */ + struct list light_map[LIGHTMAP_SIZE]; + const struct wined3d_light_info *lights[WINED3D_MAX_ACTIVE_LIGHTS]; +}; + #define WINED3D_STATE_NO_REF 0x00000001 #define WINED3D_STATE_INIT_DEFAULT 0x00000002 @@ -2825,7 +3159,7 @@ struct wined3d_state struct wined3d_vertex_declaration *vertex_declaration; struct wined3d_stream_output stream_output[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; - struct wined3d_stream_state streams[MAX_STREAMS + 1 /* tesselated pseudo-stream */]; + struct wined3d_stream_state streams[WINED3D_MAX_STREAMS + 1 /* tesselated pseudo-stream */]; struct wined3d_buffer *index_buffer; enum wined3d_format_id index_format; unsigned int index_offset; @@ -2844,30 +3178,29 @@ struct wined3d_state BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; - struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; + struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; BOOL ps_consts_b[WINED3D_MAX_CONSTS_B]; struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I]; struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; - struct wined3d_texture *textures[MAX_COMBINED_SAMPLERS]; - DWORD sampler_states[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; - DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; + struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS]; + DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; + DWORD texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; - struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1]; - struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES]; + struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1]; + struct wined3d_vec4 clip_planes[WINED3D_MAX_CLIP_DISTANCES]; struct wined3d_material material; - struct wined3d_viewport viewport; - RECT scissor_rect; + struct wined3d_viewport viewports[WINED3D_MAX_VIEWPORTS]; + unsigned int viewport_count; + RECT scissor_rects[WINED3D_MAX_VIEWPORTS]; + unsigned int scissor_rect_count; - /* Light hashmap. Collisions are handled using linked lists. */ -#define LIGHTMAP_SIZE 43 -#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) - struct list light_map[LIGHTMAP_SIZE]; - const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; + struct wined3d_light_state light_state; DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; struct wined3d_blend_state *blend_state; + struct wined3d_color blend_factor; struct wined3d_rasterizer_state *rasterizer_state; }; @@ -2918,6 +3251,40 @@ struct wined3d_gl_bo * wined3d_device_create() ignores it. */ #define WINED3DCREATE_MULTITHREADED 0x00000004 +struct wined3d_stateblock_state +{ + struct wined3d_vertex_declaration *vertex_declaration; + struct wined3d_stream_state streams[WINED3D_MAX_STREAMS + 1]; + struct wined3d_buffer *index_buffer; + enum wined3d_format_id index_format; + int base_vertex_index; + + struct wined3d_shader *vs; + struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; + struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; + BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; + + struct wined3d_shader *ps; + struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; + struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I]; + BOOL ps_consts_b[WINED3D_MAX_CONSTS_B]; + + DWORD rs[WINEHIGHEST_RENDER_STATE + 1]; + struct wined3d_color blend_factor; + + struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS]; + DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; + DWORD texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; + + struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1]; + struct wined3d_vec4 clip_planes[WINED3D_MAX_CLIP_DISTANCES]; + struct wined3d_material material; + struct wined3d_viewport viewport; + RECT scissor_rect; + + struct wined3d_light_state light_state; +}; + struct wined3d_device { LONG ref; @@ -2927,34 +3294,32 @@ struct wined3d_device struct wined3d *wined3d; struct wined3d_adapter *adapter; - /* Window styles to restore when switching fullscreen mode */ - LONG style; - LONG exStyle; - const struct wined3d_shader_backend_ops *shader_backend; void *shader_priv; void *fragment_priv; void *vertex_priv; - struct StateEntry StateTable[STATE_HIGHEST + 1]; + struct wined3d_state_entry state_table[STATE_HIGHEST + 1]; /* Array of functions for states which are handled by more than one pipeline part */ APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1]; struct wined3d_blitter *blitter; - BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */ BYTE bCursorVisible : 1; BYTE d3d_initialized : 1; BYTE inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */ BYTE softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */ - BYTE filter_messages : 1; - BYTE padding : 2; + BYTE restore_screensaver : 1; + BYTE padding : 3; unsigned char surface_alignment; /* Line Alignment of surfaces */ WORD padding2 : 16; + enum wined3d_feature_level feature_level; + struct wined3d_state state; - struct wined3d_state *update_state; struct wined3d_stateblock *recording; + struct wined3d_stateblock_state stateblock_state; + struct wined3d_stateblock_state *update_stateblock_state; /* Internal use fields */ struct wined3d_device_creation_parameters create_parms; @@ -2963,6 +3328,7 @@ struct wined3d_device struct wined3d_rendertarget_view *back_buffer_view; struct wined3d_swapchain **swapchains; UINT swapchain_count; + unsigned int max_frame_latency; struct list resources; /* a linked list to track resources created by the device */ struct list shaders; /* a linked list to track shaders (pixel and vertex) */ @@ -2984,9 +3350,6 @@ struct wined3d_device /* The Wine logo texture */ struct wined3d_texture *logo_texture; - /* Textures for when no other textures are mapped */ - struct wined3d_dummy_textures dummy_textures; - /* Default sampler used to emulate the direct resource access without using wined3d_sampler */ struct wined3d_sampler *default_sampler; struct wined3d_sampler *null_sampler; @@ -2999,34 +3362,91 @@ struct wined3d_device UINT context_count; }; +void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN; void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb, UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; void device_context_remove(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; -HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, - UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags, - BYTE surface_alignment, struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN; +void wined3d_device_create_default_samplers(struct wined3d_device *device, + struct wined3d_context *context) DECLSPEC_HIDDEN; +void wined3d_device_create_primary_opengl_context_cs(void *object) DECLSPEC_HIDDEN; +void wined3d_device_delete_opengl_contexts_cs(void *object) DECLSPEC_HIDDEN; +void wined3d_device_destroy_default_samplers(struct wined3d_device *device, + struct wined3d_context *context) DECLSPEC_HIDDEN; +HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined3d, + unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, + BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, + struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN; LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode, UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, - GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; -void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, - const struct wined3d_context *context) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ +HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +void wined3d_device_uninit_3d(struct wined3d_device *device) DECLSPEC_HIDDEN; + +struct wined3d_device_no3d +{ + struct wined3d_device d; + + struct wined3d_context context_no3d; +}; -static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) +static inline struct wined3d_device_no3d *wined3d_device_no3d(struct wined3d_device *device) { - DWORD idx = state / (sizeof(*context->isStateDirty) * CHAR_BIT); - BYTE shift = state & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - return context->isStateDirty[idx] & (1u << shift); + return CONTAINING_RECORD(device, struct wined3d_device_no3d, d); +} + + +struct wined3d_device_gl +{ + struct wined3d_device d; + + /* Textures for when no other textures are bound. */ + struct wined3d_dummy_textures dummy_textures; +}; + +static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device) +{ + return CONTAINING_RECORD(device, struct wined3d_device_gl, d); +} + +struct wined3d_device_vk +{ + struct wined3d_device d; + + struct wined3d_context_vk context_vk; + + VkDevice vk_device; + VkQueue vk_queue; + + struct wined3d_vk_info vk_info; +}; + +static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device *device) +{ + return CONTAINING_RECORD(device, struct wined3d_device_vk, d); +} + +static inline BOOL isStateDirty(const struct wined3d_context *context, unsigned int state_id) +{ + unsigned int idx = state_id / (sizeof(*context->dirty_graphics_states) * CHAR_BIT); + unsigned int shift = state_id & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1); + return context->dirty_graphics_states[idx] & (1u << shift); +} + +static inline float wined3d_alpha_ref(const struct wined3d_state *state) +{ + return (state->render_states[WINED3D_RS_ALPHAREF] & 0xff) / 255.0f; } const char *wined3d_debug_resource_access(DWORD access) DECLSPEC_HIDDEN; +const char *wined3d_debug_bind_flags(DWORD bind_flags) DECLSPEC_HIDDEN; +const char *wined3d_debug_view_desc(const struct wined3d_view_desc *d, + const struct wined3d_resource *resource) DECLSPEC_HIDDEN; +const char *wined3d_debug_vkresult(VkResult vr) DECLSPEC_HIDDEN; static inline BOOL wined3d_resource_access_is_managed(unsigned int access) { @@ -3060,6 +3480,7 @@ struct wined3d_resource enum wined3d_multisample_type multisample_type; UINT multisample_quality; DWORD usage; + unsigned int bind_flags; unsigned int access; WORD draw_binding; WORD map_binding; @@ -3100,39 +3521,58 @@ static inline void wined3d_resource_release(struct wined3d_resource *resource) void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN; HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, - enum wined3d_multisample_type multisample_type, unsigned int multisample_quality, - unsigned int usage, unsigned int access, unsigned int width, unsigned int height, unsigned int depth, + enum wined3d_multisample_type multisample_type, unsigned int multisample_quality, unsigned int usage, + unsigned int bind_flags, unsigned int access, unsigned int width, unsigned int height, unsigned int depth, unsigned int size, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +const struct wined3d_format *wined3d_resource_get_decompress_format( + const struct wined3d_resource *resource) DECLSPEC_HIDDEN; +unsigned int wined3d_resource_get_sample_count(const struct wined3d_resource *resource) DECLSPEC_HIDDEN; GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16 #define WINED3D_CONSTANT_BUFFER_ALIGNMENT 16 -struct gl_texture +#define WINED3D_LOCATION_DISCARDED 0x00000001 +#define WINED3D_LOCATION_SYSMEM 0x00000002 +#define WINED3D_LOCATION_USER_MEMORY 0x00000004 +#define WINED3D_LOCATION_BUFFER 0x00000008 +#define WINED3D_LOCATION_TEXTURE_RGB 0x00000010 +#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000020 +#define WINED3D_LOCATION_DRAWABLE 0x00000040 +#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000080 +#define WINED3D_LOCATION_RB_RESOLVED 0x00000100 + +const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; + +struct wined3d_blt_info { - struct wined3d_sampler_desc sampler_desc; - unsigned int base_level; - GLuint name; + GLenum bind_target; + struct wined3d_vec3 texcoords[4]; }; struct wined3d_texture_ops { - void (*texture_upload_data)(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_box *box, - const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch); + BOOL (*texture_prepare_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, unsigned int location); BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, DWORD location); - void (*texture_prepare_texture)(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb); - void (*texture_cleanup_sub_resources)(struct wined3d_texture *texture); + struct wined3d_context *context, unsigned int location); + void (*texture_upload_data)(struct wined3d_context *context, const struct wined3d_const_bo_address *src_bo_addr, + const struct wined3d_format *src_format, const struct wined3d_box *src_box, unsigned int src_row_pitch, + unsigned int src_slice_pitch, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + unsigned int dst_location, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z); + void (*texture_download_data)(struct wined3d_context *context, struct wined3d_texture *src_texture, + unsigned int src_sub_resource_idx, unsigned int src_location, const struct wined3d_box *src_box, + const struct wined3d_bo_address *dst_bo_addr, const struct wined3d_format *dst_format, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch); }; #define WINED3D_TEXTURE_COND_NP2 0x00000001 @@ -3151,6 +3591,7 @@ struct wined3d_texture_ops #define WINED3D_TEXTURE_DISCARD 0x00002000 #define WINED3D_TEXTURE_GET_DC 0x00004000 #define WINED3D_TEXTURE_GENERATE_MIPMAPS 0x00008000 +#define WINED3D_TEXTURE_DOWNLOADABLE 0x00010000 #define WINED3D_TEXTURE_ASYNC_COLOR_KEY 0x00000001 @@ -3158,7 +3599,6 @@ struct wined3d_texture { struct wined3d_resource resource; const struct wined3d_texture_ops *texture_ops; - struct gl_texture texture_rgb, texture_srgb; struct wined3d_swapchain *swapchain; unsigned int pow2_width; unsigned int pow2_height; @@ -3170,12 +3610,8 @@ struct wined3d_texture UINT lod; DWORD sampler; DWORD flags; - GLenum target; DWORD update_map_binding; - GLuint rb_multisample; - GLuint rb_resolved; - void *user_memory; unsigned int row_pitch; unsigned int slice_pitch; @@ -3198,59 +3634,50 @@ struct wined3d_texture { struct list entry; struct list overlays; - struct wined3d_surface *dst; + struct wined3d_texture *dst_texture; + unsigned int dst_sub_resource_idx; RECT src_rect; RECT dst_rect; } *overlay_info; + struct wined3d_dc_info + { + HBITMAP bitmap; + HDC dc; + } *dc_info; + struct wined3d_texture_sub_resource { void *parent; const struct wined3d_parent_ops *parent_ops; - union - { - struct wined3d_surface *surface; - } u; unsigned int offset; unsigned int size; unsigned int map_count; + uint32_t map_flags; DWORD locations; #if !defined(STAGING_CSMT) GLuint buffer_object; #else /* STAGING_CSMT */ struct wined3d_gl_bo *buffer; #endif /* STAGING_CSMT */ - } sub_resources[1]; + } *sub_resources; }; -static inline struct wined3d_texture *texture_from_resource(struct wined3d_resource *resource) +static inline void *wined3d_texture_allocate_object_memory(SIZE_T s, SIZE_T level_count, SIZE_T layer_count) { - return CONTAINING_RECORD(resource, struct wined3d_texture, resource); -} + struct wined3d_texture *t; -static inline GLenum wined3d_texture_get_sub_resource_target(const struct wined3d_texture *texture, - unsigned int sub_resource_idx) -{ - static const GLenum cube_targets[] = - { - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, - }; + if (level_count > ((~(SIZE_T)0 - s) / sizeof(*t->sub_resources)) / layer_count) + return NULL; - return texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP - ? cube_targets[sub_resource_idx / texture->level_count] : texture->target; + return heap_alloc_zero(s + level_count * layer_count * sizeof(*t->sub_resources)); } -static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_texture *texture, - BOOL srgb) +static inline struct wined3d_texture *texture_from_resource(struct wined3d_resource *resource) { - return srgb ? &texture->texture_srgb : &texture->texture_rgb; + return CONTAINING_RECORD(resource, struct wined3d_texture, resource); } static inline unsigned int wined3d_texture_get_level_width(const struct wined3d_texture *texture, @@ -3283,14 +3710,36 @@ static inline unsigned int wined3d_texture_get_level_pow2_height(const struct wi return max(1, texture->pow2_height >> level); } -void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, - const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context) DECLSPEC_HIDDEN; -void wined3d_texture_bind(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +static inline void wined3d_texture_get_level_box(const struct wined3d_texture *texture, + unsigned int level, struct wined3d_box *box) +{ + wined3d_box_set(box, 0, 0, + wined3d_texture_get_level_width(texture, level), + wined3d_texture_get_level_height(texture, level), + 0, wined3d_texture_get_level_depth(texture, level)); +} + +HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, + const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *context, + enum wined3d_texture_filter_type filter, struct wined3d_texture *src_texture, + unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, DWORD dst_location, + const RECT *dst_rect) DECLSPEC_HIDDEN; +void texture2d_get_blt_info(const struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, + const RECT *rect, struct wined3d_blt_info *info) DECLSPEC_HIDDEN; +void texture2d_load_fb_texture(struct wined3d_texture_gl *texture_gl, unsigned int sub_resource_idx, + BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; +void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD src_location, DWORD dst_location) DECLSPEC_HIDDEN; + HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture, unsigned int level, const struct wined3d_box *box) DECLSPEC_HIDDEN; +void wined3d_texture_cleanup(struct wined3d_texture *texture) DECLSPEC_HIDDEN; +void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx) DECLSPEC_HIDDEN; GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN; @@ -3302,28 +3751,113 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -void wined3d_texture_prepare_texture(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN; void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, - const struct wined3d_context *context, const struct wined3d_box *box, - const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) DECLSPEC_HIDDEN; +void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) DECLSPEC_HIDDEN; +void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, + HWND window, RECT *rect) DECLSPEC_HIDDEN; +void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture, + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN; void wined3d_texture_validate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; -#define WINED3D_LOCATION_DISCARDED 0x00000001 -#define WINED3D_LOCATION_SYSMEM 0x00000002 -#define WINED3D_LOCATION_USER_MEMORY 0x00000004 -#define WINED3D_LOCATION_BUFFER 0x00000008 -#define WINED3D_LOCATION_TEXTURE_RGB 0x00000010 -#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000020 -#define WINED3D_LOCATION_DRAWABLE 0x00000040 -#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000080 -#define WINED3D_LOCATION_RB_RESOLVED 0x00000100 +HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; -const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; +void wined3d_gl_texture_swizzle_from_color_fixup(GLint swizzle[4], struct color_fixup_desc fixup) DECLSPEC_HIDDEN; + +struct gl_texture +{ + struct wined3d_sampler_desc sampler_desc; + unsigned int base_level; + GLuint name; +}; + +struct wined3d_texture_gl +{ + struct wined3d_texture t; + + struct gl_texture texture_rgb, texture_srgb; + + GLenum target; + + GLuint rb_multisample; + GLuint rb_resolved; + + struct list renderbuffers; + const struct wined3d_renderbuffer_entry *current_renderbuffer; +}; + +static inline struct wined3d_texture_gl *wined3d_texture_gl(struct wined3d_texture *texture) +{ + return CONTAINING_RECORD(texture, struct wined3d_texture_gl, t); +} + +static inline struct gl_texture *wined3d_texture_gl_get_gl_texture(struct wined3d_texture_gl *texture_gl, + BOOL srgb) +{ + return srgb ? &texture_gl->texture_srgb : &texture_gl->texture_rgb; +} + +static inline GLenum wined3d_texture_gl_get_sub_resource_target(const struct wined3d_texture_gl *texture_gl, + unsigned int sub_resource_idx) +{ + static const GLenum cube_targets[] = + { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, + }; + + return texture_gl->t.resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP + ? cube_targets[sub_resource_idx / texture_gl->t.level_count] : texture_gl->target; +} + +static inline BOOL wined3d_texture_gl_is_multisample_location(const struct wined3d_texture_gl *texture_gl, + DWORD location) +{ + if (location == WINED3D_LOCATION_RB_MULTISAMPLE) + return TRUE; + if (location != WINED3D_LOCATION_TEXTURE_RGB && location != WINED3D_LOCATION_TEXTURE_SRGB) + return FALSE; + return texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE || texture_gl->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY; +} + +void wined3d_texture_gl_apply_sampler_desc(struct wined3d_texture_gl *texture_gl, + const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, BOOL srgb) DECLSPEC_HIDDEN; +void wined3d_texture_gl_bind_and_dirtify(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, BOOL srgb) DECLSPEC_HIDDEN; +HRESULT wined3d_texture_gl_init(struct wined3d_texture_gl *texture_gl, struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, BOOL srgb) DECLSPEC_HIDDEN; +void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl, + struct wined3d_context_gl *context_gl, unsigned int level, + const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN; +void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN; + +struct wined3d_texture_vk +{ + struct wined3d_texture t; +}; + +static inline struct wined3d_texture_vk *wined3d_texture_vk(struct wined3d_texture *texture) +{ + return CONTAINING_RECORD(texture, struct wined3d_texture_vk, t); +} + +HRESULT wined3d_texture_vk_init(struct wined3d_texture_vk *texture_vk, struct wined3d_device *device, + const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count, + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; struct wined3d_renderbuffer_entry { @@ -3357,62 +3891,37 @@ struct fbo_entry } key; }; -struct wined3d_surface -{ - struct wined3d_texture *container; - - unsigned int texture_level; - unsigned int texture_layer; - - /* For GetDC */ - HBITMAP bitmap; - HDC dc; - - struct list renderbuffers; - const struct wined3d_renderbuffer_entry *current_renderbuffer; -}; - -static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface) -{ - return surface->texture_layer * surface->container->level_count + surface->texture_level; -} - -static inline struct wined3d_texture_sub_resource *surface_get_sub_resource(struct wined3d_surface *surface) -{ - return &surface->container->sub_resources[surface_get_sub_resource_idx(surface)]; -} - -HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, - struct wined3d_context *context) DECLSPEC_HIDDEN; -BOOL surface_load_location(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, - const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN; -void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; -void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, - BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; - -void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - struct wined3d_sampler { struct wine_rb_entry entry; LONG refcount; - GLuint name; struct wined3d_device *device; void *parent; const struct wined3d_parent_ops *parent_ops; struct wined3d_sampler_desc desc; }; -void wined3d_sampler_bind(struct wined3d_sampler *sampler, unsigned int unit, - struct wined3d_texture *texture, const struct wined3d_context *context) DECLSPEC_HIDDEN; +struct wined3d_sampler_gl +{ + struct wined3d_sampler s; + + GLuint name; +}; + +static inline struct wined3d_sampler_gl *wined3d_sampler_gl(struct wined3d_sampler *sampler) +{ + return CONTAINING_RECORD(sampler, struct wined3d_sampler_gl, s); +} + +void wined3d_sampler_gl_bind(struct wined3d_sampler_gl *sampler_gl, unsigned int unit, + struct wined3d_texture_gl *texture_gl, const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +void wined3d_sampler_gl_init(struct wined3d_sampler_gl *sampler_gl, + struct wined3d_device *device, const struct wined3d_sampler_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +void wined3d_sampler_vk_init(struct wined3d_sampler *sampler_vk, + struct wined3d_device *device, const struct wined3d_sampler_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; struct wined3d_vertex_declaration_element { @@ -3436,28 +3945,27 @@ struct wined3d_vertex_declaration struct wined3d_device *device; struct wined3d_vertex_declaration_element *elements; - UINT element_count; + unsigned int element_count; BOOL position_transformed; - BOOL half_float_conv_needed; }; struct wined3d_saved_states { - DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; - WORD streamSource; /* MAX_STREAMS, 16 */ - WORD streamFreq; /* MAX_STREAMS, 16 */ + DWORD transform[(WINED3D_HIGHEST_TRANSFORM_STATE >> 5) + 1]; + WORD streamSource; /* WINED3D_MAX_STREAMS, 16 */ + WORD streamFreq; /* WINED3D_MAX_STREAMS, 16 */ DWORD renderState[(WINEHIGHEST_RENDER_STATE >> 5) + 1]; - DWORD textureState[MAX_TEXTURES]; /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */ - WORD samplerState[MAX_COMBINED_SAMPLERS]; /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */ + DWORD textureState[WINED3D_MAX_TEXTURES]; /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */ + WORD samplerState[WINED3D_MAX_COMBINED_SAMPLERS]; /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */ DWORD clipplane; /* WINED3D_MAX_USER_CLIP_PLANES, 32 */ WORD pixelShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ WORD pixelShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; WORD vertexShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ WORD vertexShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ - BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; - DWORD textures : 20; /* MAX_COMBINED_SAMPLERS, 20 */ + BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; + DWORD textures : 20; /* WINED3D_MAX_COMBINED_SAMPLERS, 20 */ DWORD indices : 1; DWORD material : 1; DWORD viewport : 1; @@ -3465,7 +3973,9 @@ struct wined3d_saved_states DWORD pixelShader : 1; DWORD vertexShader : 1; DWORD scissorRect : 1; - DWORD padding : 5; + DWORD blend_state : 1; + DWORD store_stream_offset : 1; + DWORD padding : 3; }; struct StageState { @@ -3480,18 +3990,18 @@ struct wined3d_stateblock /* Array indicating whether things have been set or changed */ struct wined3d_saved_states changed; - struct wined3d_state state; + struct wined3d_stateblock_state stateblock_state; /* Contained state management */ DWORD contained_render_states[WINEHIGHEST_RENDER_STATE + 1]; unsigned int num_contained_render_states; - DWORD contained_transform_states[HIGHEST_TRANSFORMSTATE + 1]; + DWORD contained_transform_states[WINED3D_HIGHEST_TRANSFORM_STATE + 1]; unsigned int num_contained_transform_states; DWORD contained_vs_consts_i[WINED3D_MAX_CONSTS_I]; unsigned int num_contained_vs_consts_i; DWORD contained_vs_consts_b[WINED3D_MAX_CONSTS_B]; unsigned int num_contained_vs_consts_b; - DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; + DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; unsigned int num_contained_vs_consts_f; DWORD contained_ps_consts_i[WINED3D_MAX_CONSTS_I]; unsigned int num_contained_ps_consts_i; @@ -3499,22 +4009,28 @@ struct wined3d_stateblock unsigned int num_contained_ps_consts_b; DWORD contained_ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; unsigned int num_contained_ps_consts_f; - struct StageState contained_tss_states[MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)]; + struct StageState contained_tss_states[WINED3D_MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)]; unsigned int num_contained_tss_states; - struct StageState contained_sampler_states[MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE]; + struct StageState contained_sampler_states[WINED3D_MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE]; unsigned int num_contained_sampler_states; }; void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; -void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; -void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, +void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state, + const struct wined3d_device *device, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) DECLSPEC_HIDDEN; + +void wined3d_light_state_enable_light(struct wined3d_light_state *state, const struct wined3d_d3d_info *d3d_info, struct wined3d_light_info *light_info, BOOL enable) DECLSPEC_HIDDEN; -struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *state, +struct wined3d_light_info *wined3d_light_state_get_light(const struct wined3d_light_state *state, unsigned int idx) DECLSPEC_HIDDEN; +HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, DWORD light_idx, + const struct wined3d_light *params, struct wined3d_light_info **light_info) DECLSPEC_HIDDEN; + +void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, - DWORD flags) DECLSPEC_HIDDEN; + const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; enum wined3d_cs_queue_id @@ -3612,10 +4128,11 @@ void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, - const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags) DECLSPEC_HIDDEN; + const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state, + const struct wined3d_color *blend_factor) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, @@ -3643,7 +4160,7 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type UINT sampler_idx, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, @@ -3662,7 +4179,7 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined unsigned int initial_count) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count, const struct wined3d_viewport *viewports) DECLSPEC_HIDDEN; void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, @@ -3674,6 +4191,11 @@ HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx) DECLSPEC_HIDDEN; +static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) +{ + cs->ops->finish(cs, queue_id); +} + static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p, unsigned int start_idx, unsigned int count, const void *constants) { @@ -3700,25 +4222,26 @@ enum wined3d_buffer_conversion_type CONV_POSITIONT, }; -struct wined3d_map_range +struct wined3d_buffer_ops { - UINT offset; - UINT size; + BOOL (*buffer_prepare_location)(struct wined3d_buffer *buffer, + struct wined3d_context *context, unsigned int location); + void (*buffer_upload_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, const void *data, + unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges); + void (*buffer_download_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, void *data, + unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges); }; struct wined3d_buffer { struct wined3d_resource resource; + const struct wined3d_buffer_ops *buffer_ops; - struct wined3d_buffer_desc desc; - - GLuint buffer_object; - GLenum buffer_object_usage; - GLenum buffer_type_hint; - unsigned int bind_flags; + unsigned int structure_byte_stride; DWORD flags; DWORD locations; void *map_ptr; + uintptr_t buffer_object; struct wined3d_map_range *maps; SIZE_T maps_size, modified_areas; @@ -3737,6 +4260,7 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc return CONTAINING_RECORD(resource, struct wined3d_buffer, resource); } +void wined3d_buffer_cleanup(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN; void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) DECLSPEC_HIDDEN; @@ -3750,6 +4274,45 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off void wined3d_buffer_upload_data(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; +HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_buffer_gl +{ + struct wined3d_buffer b; + + GLenum buffer_object_usage; + GLenum buffer_type_hint; +}; + +static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer *buffer) +{ + return CONTAINING_RECORD(buffer, struct wined3d_buffer_gl, b); +} + +GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info, + uint32_t bind_flags) DECLSPEC_HIDDEN; +void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl, + struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_buffer_vk +{ + struct wined3d_buffer b; +}; + +static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer *buffer) +{ + return CONTAINING_RECORD(buffer, struct wined3d_buffer_vk, b); +} + +HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device, + const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + struct wined3d_rendertarget_view { LONG refcount; @@ -3758,7 +4321,6 @@ struct wined3d_rendertarget_view void *parent; const struct wined3d_parent_ops *parent_ops; - struct wined3d_gl_view gl_view; const struct wined3d_format *format; unsigned int format_flags; unsigned int sub_resource_idx; @@ -3770,19 +4332,7 @@ struct wined3d_rendertarget_view struct wined3d_view_desc desc; }; -static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( - const struct wined3d_rendertarget_view *view) -{ - struct wined3d_texture *texture; - - if (!view || view->resource->type != WINED3D_RTYPE_TEXTURE_2D) - return NULL; - - texture = texture_from_resource(view->resource); - - return texture->sub_resources[view->sub_resource_idx].u.surface; -} - +void wined3d_rendertarget_view_cleanup(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view, const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view, @@ -3794,6 +4344,41 @@ void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view, DWORD location) DECLSPEC_HIDDEN; +HRESULT wined3d_rendertarget_view_no3d_init(struct wined3d_rendertarget_view *view_no3d, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_rendertarget_view_gl +{ + struct wined3d_rendertarget_view v; + struct wined3d_gl_view gl_view; +}; + +static inline struct wined3d_rendertarget_view_gl *wined3d_rendertarget_view_gl( + struct wined3d_rendertarget_view *view) +{ + return CONTAINING_RECORD(view, struct wined3d_rendertarget_view_gl, v); +} + +HRESULT wined3d_rendertarget_view_gl_init(struct wined3d_rendertarget_view_gl *view_gl, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_rendertarget_view_vk +{ + struct wined3d_rendertarget_view v; +}; + +static inline struct wined3d_rendertarget_view_vk *wined3d_rendertarget_view_vk( + struct wined3d_rendertarget_view *view) +{ + return CONTAINING_RECORD(view, struct wined3d_rendertarget_view_vk, v); +} + +HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_view_vk *view_vk, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + struct wined3d_shader_resource_view { LONG refcount; @@ -3802,15 +4387,46 @@ struct wined3d_shader_resource_view void *parent; const struct wined3d_parent_ops *parent_ops; - struct wined3d_gl_view gl_view; const struct wined3d_format *format; struct wined3d_view_desc desc; }; +void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; -void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view, unsigned int unit, - struct wined3d_sampler *sampler, struct wined3d_context *context) DECLSPEC_HIDDEN; + +struct wined3d_shader_resource_view_gl +{ + struct wined3d_shader_resource_view v; + struct wined3d_gl_view gl_view; +}; + +static inline struct wined3d_shader_resource_view_gl *wined3d_shader_resource_view_gl( + struct wined3d_shader_resource_view *view) +{ + return CONTAINING_RECORD(view, struct wined3d_shader_resource_view_gl, v); +} + +void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl *view_gl, unsigned int unit, + struct wined3d_sampler_gl *sampler_gl, struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_shader_resource_view_vk +{ + struct wined3d_shader_resource_view v; +}; + +static inline struct wined3d_shader_resource_view_vk *wined3d_shader_resource_view_vk( + struct wined3d_shader_resource_view *view) +{ + return CONTAINING_RECORD(view, struct wined3d_shader_resource_view_vk, v); +} + +HRESULT wined3d_shader_resource_view_vk_init(struct wined3d_shader_resource_view_vk *view_vk, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; struct wined3d_unordered_access_view { @@ -3820,15 +4436,12 @@ struct wined3d_unordered_access_view void *parent; const struct wined3d_parent_ops *parent_ops; - struct wined3d_gl_view gl_view; const struct wined3d_format *format; - GLuint counter_bo; struct wined3d_view_desc desc; }; -void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view, - const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) DECLSPEC_HIDDEN; +void wined3d_unordered_access_view_cleanup(struct wined3d_unordered_access_view *view) DECLSPEC_HIDDEN; void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view, struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context) DECLSPEC_HIDDEN; void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view, @@ -3836,10 +4449,62 @@ void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_ void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view, unsigned int value) DECLSPEC_HIDDEN; +struct wined3d_unordered_access_view_gl +{ + struct wined3d_unordered_access_view v; + struct wined3d_gl_view gl_view; + GLuint counter_bo; +}; + +static inline struct wined3d_unordered_access_view_gl *wined3d_unordered_access_view_gl( + struct wined3d_unordered_access_view *view) +{ + return CONTAINING_RECORD(view, struct wined3d_unordered_access_view_gl, v); +} + +void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access_view_gl *view_gl, + const struct wined3d_uvec4 *clear_value, struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; +HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_unordered_access_view_vk +{ + struct wined3d_unordered_access_view v; +}; + +static inline struct wined3d_unordered_access_view_vk *wined3d_unordered_access_view_vk( + struct wined3d_unordered_access_view *view) +{ + return CONTAINING_RECORD(view, struct wined3d_unordered_access_view_vk, v); +} + +HRESULT wined3d_unordered_access_view_vk_init(struct wined3d_unordered_access_view_vk *view_vk, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_swapchain_state +{ + struct wined3d_swapchain_desc desc; + + struct wined3d_display_mode original_mode, d3d_mode; + RECT original_window_rect; + + /* Window styles to restore when switching fullscreen mode. */ + LONG style; + LONG exstyle; + HWND device_window; +}; + +void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_state *state, + HWND window, const RECT *window_rect) DECLSPEC_HIDDEN; +HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state, + HWND window, unsigned int w, unsigned int h) DECLSPEC_HIDDEN; + struct wined3d_swapchain_ops { void (*swapchain_present)(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, DWORD flags); + const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, DWORD flags); void (*swapchain_frontbuffer_updated)(struct wined3d_swapchain *swapchain); }; @@ -3853,41 +4518,68 @@ struct wined3d_swapchain struct wined3d_texture **back_buffers; struct wined3d_texture *front_buffer; - struct wined3d_swapchain_desc desc; - struct wined3d_display_mode original_mode, d3d_mode; - RECT original_window_rect; struct wined3d_gamma_ramp orig_gamma; BOOL render_to_fbo, reapply_mode; const struct wined3d_format *ds_format; struct wined3d_palette *palette; RECT front_buffer_update; + unsigned int swap_interval; + unsigned int max_frame_latency; LONG prev_time, frames; /* Performance tracking */ - struct wined3d_context **context; - unsigned int num_contexts; - + struct wined3d_swapchain_state state; HWND win_handle; - HWND device_window; +}; + +void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN; +void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, + const struct wined3d_device *device) DECLSPEC_HIDDEN; + +HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, + struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +struct wined3d_swapchain_gl +{ + struct wined3d_swapchain s; + + struct wined3d_context_gl **contexts; + SIZE_T contexts_size; + SIZE_T context_count; HDC backup_dc; HWND backup_wnd; }; -void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN; -struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_swapchain *swapchain) +{ + return CONTAINING_RECORD(swapchain, struct wined3d_swapchain_gl, s); +} + +void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, + struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain *swapchain_vk, + struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; /***************************************************************************** * Utility function prototypes */ /* Trace routines */ +const char *debug_bo_address(const struct wined3d_bo_address *address) DECLSPEC_HIDDEN; const char *debug_box(const struct wined3d_box *box) DECLSPEC_HIDDEN; const char *debug_color(const struct wined3d_color *color) DECLSPEC_HIDDEN; +const char *debug_const_bo_address(const struct wined3d_const_bo_address *address) DECLSPEC_HIDDEN; const char *debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx) DECLSPEC_HIDDEN; const char *debug_d3dformat(enum wined3d_format_id format_id) DECLSPEC_HIDDEN; const char *debug_d3ddevicetype(enum wined3d_device_type device_type) DECLSPEC_HIDDEN; @@ -3912,6 +4604,7 @@ const char *debug_ivec4(const struct wined3d_ivec4 *v) DECLSPEC_HIDDEN; const char *debug_uvec4(const struct wined3d_uvec4 *v) DECLSPEC_HIDDEN; const char *debug_shader_type(enum wined3d_shader_type shader_type) DECLSPEC_HIDDEN; const char *debug_vec4(const struct wined3d_vec4 *v) DECLSPEC_HIDDEN; +const char *wined3d_debug_feature_level(enum wined3d_feature_level level) DECLSPEC_HIDDEN; void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN; BOOL is_invalid_op(const struct wined3d_state *state, int stage, @@ -3919,7 +4612,7 @@ BOOL is_invalid_op(const struct wined3d_state *state, int stage, void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, BOOL is_alpha, int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) DECLSPEC_HIDDEN; -void texture_activate_dimensions(const struct wined3d_texture *texture, +void texture_activate_dimensions(struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; @@ -3954,6 +4647,7 @@ void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN; +enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) DECLSPEC_HIDDEN; /* Math utils */ void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1, @@ -4072,8 +4766,10 @@ struct wined3d_shader { LONG ref; const struct wined3d_shader_limits *limits; - DWORD *function; - UINT functionLength; + const DWORD *function; + unsigned int functionLength; + void *byte_code; + unsigned int byte_code_size; BOOL load_local_constsF; const struct wined3d_shader_frontend *frontend; void *frontend_data; @@ -4095,7 +4791,6 @@ struct wined3d_shader struct wined3d_shader_signature input_signature; struct wined3d_shader_signature output_signature; struct wined3d_shader_signature patch_constant_signature; - char *signature_strings; /* Pointer to the parent device */ struct wined3d_device *device; @@ -4112,7 +4807,8 @@ struct wined3d_shader } u; }; -void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN; +enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps, + unsigned int resource_idx, DWORD tex_types) DECLSPEC_HIDDEN; void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN; @@ -4150,13 +4846,16 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) /* oPos */ return FALSE; + case WINED3DSPR_CONSTBOOL: /* b# */ case WINED3DSPR_DEPTHOUT: /* oDepth */ case WINED3DSPR_DEPTHOUTGE: case WINED3DSPR_DEPTHOUTLE: - case WINED3DSPR_CONSTBOOL: /* b# */ case WINED3DSPR_LOOP: /* aL */ + case WINED3DSPR_OUTPOINTID: case WINED3DSPR_PREDICATE: /* p0 */ case WINED3DSPR_PRIMID: /* primID */ + case WINED3DSPR_COVERAGE: /* vCoverage */ + case WINED3DSPR_SAMPLEMASK: /* oMask */ return TRUE; case WINED3DSPR_MISCTYPE: @@ -4179,24 +4878,28 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) } static inline void shader_get_position_fixup(const struct wined3d_context *context, - const struct wined3d_state *state, float *position_fixup) + const struct wined3d_state *state, unsigned int fixup_count, float *position_fixup) { float center_offset; + unsigned int i; if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; - position_fixup[0] = 1.0f; - position_fixup[1] = 1.0f; - position_fixup[2] = center_offset / state->viewport.width; - position_fixup[3] = -center_offset / state->viewport.height; - - if (context->render_offscreen) + for (i = 0; i < fixup_count; ++i) { - position_fixup[1] *= -1.0f; - position_fixup[3] *= -1.0f; + position_fixup[4 * i ] = 1.0f; + position_fixup[4 * i + 1] = 1.0f; + position_fixup[4 * i + 2] = center_offset / state->viewports[i].width; + position_fixup[4 * i + 3] = -center_offset / state->viewports[i].height; + + if (context->render_offscreen) + { + position_fixup[4 * i + 1] *= -1.0f; + position_fixup[4 * i + 3] *= -1.0f; + } } } @@ -4216,6 +4919,13 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, return FALSE; } +static inline BOOL device_is_swvp(const struct wined3d_device *device) +{ + return (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) + && device->softwareVertexProcessing); +} + void get_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN; void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN; @@ -4242,7 +4952,7 @@ void get_fog_start_end(const struct wined3d_context *context, const struct wined * * This structure is shared between the GLSL and the ARB backend.*/ struct ps_np2fixup_info { - unsigned char idx[MAX_FRAGMENT_SAMPLERS]; /* indices to the real constant */ + unsigned char idx[WINED3D_MAX_FRAGMENT_SAMPLERS]; /* indices to the real constant */ WORD active; /* bitfield indicating if we can apply the fixup */ WORD num_consts; }; @@ -4276,6 +4986,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_EXTENSION 0x00000020 #define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040 #define WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB 0x00000080 +#define WINED3DFMT_FLAG_DECOMPRESS 0x00000100 #define WINED3DFMT_FLAG_FLOAT 0x00000200 #define WINED3DFMT_FLAG_BUMPMAP 0x00000400 #define WINED3DFMT_FLAG_SRGB_READ 0x00000800 @@ -4290,6 +5001,10 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY 0x00100000 #define WINED3DFMT_FLAG_INTEGER 0x00200000 #define WINED3DFMT_FLAG_GEN_MIPMAP 0x00400000 +#define WINED3DFMT_FLAG_NORMALISED 0x00800000 +#define WINED3DFMT_FLAG_VERTEX_ATTRIBUTE 0x01000000 +#define WINED3DFMT_FLAG_BLIT 0x02000000 +#define WINED3DFMT_FLAG_MAPPABLE 0x04000000 struct wined3d_rational { @@ -4300,8 +5015,8 @@ struct wined3d_rational struct wined3d_color_key_conversion { enum wined3d_format_id dst_format; - void (*convert)(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width, - unsigned int height, const struct wined3d_palette *palette, const struct wined3d_color_key *color_key); + void (*convert)(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, + unsigned int width, unsigned int height, const struct wined3d_color_key *colour_key); }; struct wined3d_format @@ -4309,6 +5024,7 @@ struct wined3d_format enum wined3d_format_id id; D3DDDIFORMAT ddi_format; + unsigned int component_count; DWORD red_size; DWORD green_size; DWORD blue_size; @@ -4326,17 +5042,7 @@ struct wined3d_format UINT block_byte_count; enum wined3d_ffp_emit_idx emit_idx; - GLint component_count; - GLenum gl_vtx_type; - GLint gl_vtx_format; - GLboolean gl_normalized; - unsigned int attribute_size; - - GLint glInternal; - GLint glGammaInternal; - GLint rtInternal; - GLint glFormat; - GLint glType; + UINT conv_byte_count; DWORD multisample_types; unsigned int flags[WINED3D_GL_RES_TYPE_COUNT]; @@ -4349,13 +5055,15 @@ struct wined3d_format void (*download)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned dst_slice_pitch, unsigned int width, unsigned int height, unsigned int depth); + void (*decompress)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, + unsigned int dst_row_pitch, unsigned dst_slice_pitch, + unsigned int width, unsigned int height, unsigned int depth); enum wined3d_format_id typeless_id; - GLenum gl_view_class; }; -const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, - enum wined3d_format_id format_id, unsigned int resource_usage) DECLSPEC_HIDDEN; +const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *adapter, + enum wined3d_format_id format_id, unsigned int bind_flags) DECLSPEC_HIDDEN; void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) DECLSPEC_HIDDEN; UINT wined3d_format_calculate_size(const struct wined3d_format *format, @@ -4371,6 +5079,39 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers BOOL wined3d_formats_are_srgb_variants(enum wined3d_format_id format1, enum wined3d_format_id format2) DECLSPEC_HIDDEN; +struct wined3d_format_gl +{ + struct wined3d_format f; + + GLenum vtx_type; + GLint vtx_format; + + GLint internal; + GLint srgb_internal; + GLint rt_internal; + GLint format; + GLint type; + + GLenum view_class; +}; + +static inline const struct wined3d_format_gl *wined3d_format_gl(const struct wined3d_format *format) +{ + return CONTAINING_RECORD(format, struct wined3d_format_gl, f); +} + +struct wined3d_format_vk +{ + struct wined3d_format f; + + VkFormat vk_format; +}; + +static inline const struct wined3d_format_vk *wined3d_format_vk(const struct wined3d_format *format) +{ + return CONTAINING_RECORD(format, struct wined3d_format_vk, f); +} + BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) DECLSPEC_HIDDEN; static inline BOOL wined3d_format_is_typeless(const struct wined3d_format *format) @@ -4422,20 +5163,40 @@ static inline BOOL use_ps(const struct wined3d_state *state) static inline void context_apply_state(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct StateEntry *state_table = context->state_table; - DWORD rep = state_table[state_id].representative; + const struct wined3d_state_entry *state_table = context->state_table; + unsigned int rep = state_table[state_id].representative; state_table[rep].apply(context, state, rep); } +static inline BOOL is_srgb_enabled(const DWORD *sampler_states) +{ + /* Only use the LSB of the WINED3D_SAMP_SRGB_TEXTURE value. This matches + * the behaviour of the AMD Windows driver. + * + * Might & Magic: Heroes VI - Shades of Darkness sets + * WINED3D_SAMP_SRGB_TEXTURE to a large value that looks like a + * pointer—presumably by accident—and expects sRGB decoding to be + * disabled. */ + return sampler_states[WINED3D_SAMP_SRGB_TEXTURE] & 0x1; +} + static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context, const struct wined3d_texture *texture) { - unsigned int flags = texture->resource.format_flags - & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); + if (!(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) + return FALSE; + + if (!context->d3d_info->srgb_read_control + && (texture->resource.bind_flags & WINED3D_BIND_SHADER_RESOURCE) + && (texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_READ)) + return TRUE; + + if (!context->d3d_info->srgb_write_control + && (texture->resource.bind_flags & WINED3D_BIND_RENDER_TARGET) + && (texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)) + return TRUE; - return (!context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE] - || (flags && flags != (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE))) - && context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL; + return FALSE; } static inline BOOL needs_srgb_write(const struct wined3d_context *context, @@ -4446,26 +5207,16 @@ static inline BOOL needs_srgb_write(const struct wined3d_context *context, && fb->render_targets[0] && fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; } -static inline GLuint wined3d_texture_get_texture_name(const struct wined3d_texture *texture, +static inline GLuint wined3d_texture_gl_get_texture_name(const struct wined3d_texture_gl *texture_gl, const struct wined3d_context *context, BOOL srgb) { - return srgb && needs_separate_srgb_gl_texture(context, texture) - ? texture->texture_srgb.name : texture->texture_rgb.name; -} - -static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info, const struct wined3d_format *format) -{ - return gl_info->supported[ARB_TEXTURE_SWIZZLE] && !is_complex_fixup(format->color_fixup) - && !is_scaling_fixup(format->color_fixup); + return srgb && needs_separate_srgb_gl_texture(context, &texture_gl->t) + ? texture_gl->texture_srgb.name : texture_gl->texture_rgb.name; } -static inline BOOL needs_interpolation_qualifiers_for_shader_outputs(const struct wined3d_gl_info *gl_info) +static inline BOOL can_use_texture_swizzle(const struct wined3d_d3d_info *d3d_info, const struct wined3d_format *format) { - /* In GLSL 4.40+ it is fine to specify interpolation qualifiers only in - * fragment shaders. In older GLSL versions interpolation qualifiers must - * match between shader stages. - */ - return gl_info->glsl_version < MAKEDWORD_VERSION(4, 40); + return d3d_info->texture_swizzle && !is_complex_fixup(format->color_fixup) && !is_scaling_fixup(format->color_fixup); } static inline BOOL is_rasterization_disabled(const struct wined3d_shader *geometry_shader) @@ -4474,13 +5225,6 @@ static inline BOOL is_rasterization_disabled(const struct wined3d_shader *geomet && geometry_shader->u.gs.so_desc.rasterizer_stream_idx == WINED3D_NO_RASTERIZER_STREAM; } -static inline int wined3d_bit_scan(unsigned int *x) -{ - int bit_offset = ffs(*x) - 1; - *x ^= 1u << bit_offset; - return bit_offset; -} - static inline DWORD wined3d_extract_bits(const DWORD *bitstream, unsigned int offset, unsigned int count) { @@ -4519,15 +5263,6 @@ static inline void wined3d_insert_bits(DWORD *bitstream, } } -static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context) -{ - struct wined3d_texture *texture = context->current_rt.texture; - - if (!texture) - return NULL; - return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface; -} - static inline void wined3d_from_cs(const struct wined3d_cs *cs) { if (cs->thread) @@ -4542,6 +5277,115 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN; void wined3d_dxtn_free(void) DECLSPEC_HIDDEN; +static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, + const struct wined3d_state *state) +{ + return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] + && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); +} + +static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, + enum wined3d_material_color_source source) +{ + if (source == WINED3D_MCS_COLOR1 && use_map & (1u << WINED3D_FFP_DIFFUSE)) + return source; + if (source == WINED3D_MCS_COLOR2 && use_map & (1u << WINED3D_FFP_SPECULAR)) + return source; + return WINED3D_MCS_MATERIAL; +} + +static inline void wined3d_get_material_colour_source(enum wined3d_material_color_source *diffuse, + enum wined3d_material_color_source *emissive, enum wined3d_material_color_source *ambient, + enum wined3d_material_color_source *specular, const struct wined3d_state *state, + const struct wined3d_stream_info *si) +{ + if (!state->render_states[WINED3D_RS_LIGHTING]) + { + *diffuse = WINED3D_MCS_COLOR1; + *specular = WINED3D_MCS_COLOR2; + *emissive = *ambient = WINED3D_MCS_MATERIAL; + + return; + } + + if (!state->render_states[WINED3D_RS_COLORVERTEX]) + { + *diffuse = *emissive = *ambient = *specular = WINED3D_MCS_MATERIAL; + + return; + } + + *diffuse = validate_material_colour_source(si->use_map, state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]); + *emissive = validate_material_colour_source(si->use_map, state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]); + *ambient = validate_material_colour_source(si->use_map, state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]); + *specular = validate_material_colour_source(si->use_map, state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]); +} + +static inline void wined3d_vec4_transform(struct wined3d_vec4 *dst, + const struct wined3d_vec4 *v, const struct wined3d_matrix *m) +{ + struct wined3d_vec4 tmp; + + tmp.x = v->x * m->_11 + v->y * m->_21 + v->z * m->_31 + v->w * m->_41; + tmp.y = v->x * m->_12 + v->y * m->_22 + v->z * m->_32 + v->w * m->_42; + tmp.z = v->x * m->_13 + v->y * m->_23 + v->z * m->_33 + v->w * m->_43; + tmp.w = v->x * m->_14 + v->y * m->_24 + v->z * m->_34 + v->w * m->_44; + + *dst = tmp; +} + +BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN; + +void compute_normal_matrix(float *normal_matrix, BOOL legacy_lighting, + const struct wined3d_matrix *modelview) DECLSPEC_HIDDEN; + +static inline struct wined3d_context *context_acquire(struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx) +{ + wined3d_from_cs(device->cs); + + return device->adapter->adapter_ops->adapter_acquire_context(device, texture, sub_resource_idx); +} + +static inline void context_release(struct wined3d_context *context) +{ + context->device->adapter->adapter_ops->adapter_release_context(context); +} + +static inline float wined3d_get_float_state(const struct wined3d_state *state, enum wined3d_render_state rs) +{ + union + { + DWORD d; + float f; + } + tmpvalue; + + tmpvalue.d = state->render_states[rs]; + return tmpvalue.f; +} + +static inline void *wined3d_context_map_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, size_t size, uint32_t bind_flags, uint32_t map_flags) +{ + return context->device->adapter->adapter_ops->adapter_map_bo_address(context, data, size, bind_flags, map_flags); +} + +static inline void wined3d_context_unmap_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, uint32_t bind_flags, + unsigned int range_count, const struct wined3d_map_range *ranges) +{ + context->device->adapter->adapter_ops->adapter_unmap_bo_address(context, data, bind_flags, range_count, ranges); +} + +static inline void wined3d_context_copy_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *dst, uint32_t dst_bind_flags, + const struct wined3d_bo_address *src, uint32_t src_bind_flags, size_t size) +{ + context->device->adapter->adapter_ops->adapter_copy_bo_address(context, + dst, dst_bind_flags, src, src_bind_flags, size); +} + /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */ #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL" diff --git a/dll/directx/wine/wined3d/wined3d_vk.h b/dll/directx/wine/wined3d/wined3d_vk.h new file mode 100644 index 00000000000..13e07ab3db4 --- /dev/null +++ b/dll/directx/wine/wined3d/wined3d_vk.h @@ -0,0 +1,198 @@ +/* + * Copyright 2018 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINED3D_VK_H +#define __WINE_WINED3D_VK_H + +#define VK_NO_PROTOTYPES +#ifndef USE_WIN32_VULKAN +#define WINE_VK_HOST +#endif +#include "wine/vulkan.h" + +#define VK_INSTANCE_FUNCS() \ + VK_INSTANCE_PFN(vkCreateDevice) \ + VK_INSTANCE_PFN(vkDestroyInstance) \ + VK_INSTANCE_PFN(vkEnumerateDeviceExtensionProperties) \ + VK_INSTANCE_PFN(vkEnumerateDeviceLayerProperties) \ + VK_INSTANCE_PFN(vkEnumeratePhysicalDevices) \ + VK_INSTANCE_PFN(vkGetDeviceProcAddr) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceFormatProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceImageFormatProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceMemoryProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceQueueFamilyProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties) \ + /* Vulkan 1.1 */ \ + VK_INSTANCE_EXT_PFN(vkGetPhysicalDeviceProperties2) + +#define VK_DEVICE_FUNCS() \ + VK_DEVICE_PFN(vkAllocateCommandBuffers) \ + VK_DEVICE_PFN(vkAllocateDescriptorSets) \ + VK_DEVICE_PFN(vkAllocateMemory) \ + VK_DEVICE_PFN(vkBeginCommandBuffer) \ + VK_DEVICE_PFN(vkBindBufferMemory) \ + VK_DEVICE_PFN(vkBindImageMemory) \ + VK_DEVICE_PFN(vkCmdBeginQuery) \ + VK_DEVICE_PFN(vkCmdBeginRenderPass) \ + VK_DEVICE_PFN(vkCmdBindDescriptorSets) \ + VK_DEVICE_PFN(vkCmdBindIndexBuffer) \ + VK_DEVICE_PFN(vkCmdBindPipeline) \ + VK_DEVICE_PFN(vkCmdBindVertexBuffers) \ + VK_DEVICE_PFN(vkCmdBlitImage) \ + VK_DEVICE_PFN(vkCmdClearAttachments) \ + VK_DEVICE_PFN(vkCmdClearColorImage) \ + VK_DEVICE_PFN(vkCmdClearDepthStencilImage) \ + VK_DEVICE_PFN(vkCmdCopyBuffer) \ + VK_DEVICE_PFN(vkCmdCopyBufferToImage) \ + VK_DEVICE_PFN(vkCmdCopyImage) \ + VK_DEVICE_PFN(vkCmdCopyImageToBuffer) \ + VK_DEVICE_PFN(vkCmdCopyQueryPoolResults) \ + VK_DEVICE_PFN(vkCmdDispatch) \ + VK_DEVICE_PFN(vkCmdDispatchIndirect) \ + VK_DEVICE_PFN(vkCmdDraw) \ + VK_DEVICE_PFN(vkCmdDrawIndexed) \ + VK_DEVICE_PFN(vkCmdDrawIndexedIndirect) \ + VK_DEVICE_PFN(vkCmdDrawIndirect) \ + VK_DEVICE_PFN(vkCmdEndQuery) \ + VK_DEVICE_PFN(vkCmdEndRenderPass) \ + VK_DEVICE_PFN(vkCmdExecuteCommands) \ + VK_DEVICE_PFN(vkCmdFillBuffer) \ + VK_DEVICE_PFN(vkCmdNextSubpass) \ + VK_DEVICE_PFN(vkCmdPipelineBarrier) \ + VK_DEVICE_PFN(vkCmdPushConstants) \ + VK_DEVICE_PFN(vkCmdResetEvent) \ + VK_DEVICE_PFN(vkCmdResetQueryPool) \ + VK_DEVICE_PFN(vkCmdResolveImage) \ + VK_DEVICE_PFN(vkCmdSetBlendConstants) \ + VK_DEVICE_PFN(vkCmdSetDepthBias) \ + VK_DEVICE_PFN(vkCmdSetDepthBounds) \ + VK_DEVICE_PFN(vkCmdSetEvent) \ + VK_DEVICE_PFN(vkCmdSetLineWidth) \ + VK_DEVICE_PFN(vkCmdSetScissor) \ + VK_DEVICE_PFN(vkCmdSetStencilCompareMask) \ + VK_DEVICE_PFN(vkCmdSetStencilReference) \ + VK_DEVICE_PFN(vkCmdSetStencilWriteMask) \ + VK_DEVICE_PFN(vkCmdSetViewport) \ + VK_DEVICE_PFN(vkCmdUpdateBuffer) \ + VK_DEVICE_PFN(vkCmdWaitEvents) \ + VK_DEVICE_PFN(vkCmdWriteTimestamp) \ + VK_DEVICE_PFN(vkCreateBuffer) \ + VK_DEVICE_PFN(vkCreateBufferView) \ + VK_DEVICE_PFN(vkCreateCommandPool) \ + VK_DEVICE_PFN(vkCreateComputePipelines) \ + VK_DEVICE_PFN(vkCreateDescriptorPool) \ + VK_DEVICE_PFN(vkCreateDescriptorSetLayout) \ + VK_DEVICE_PFN(vkCreateEvent) \ + VK_DEVICE_PFN(vkCreateFence) \ + VK_DEVICE_PFN(vkCreateFramebuffer) \ + VK_DEVICE_PFN(vkCreateGraphicsPipelines) \ + VK_DEVICE_PFN(vkCreateImage) \ + VK_DEVICE_PFN(vkCreateImageView) \ + VK_DEVICE_PFN(vkCreatePipelineCache) \ + VK_DEVICE_PFN(vkCreatePipelineLayout) \ + VK_DEVICE_PFN(vkCreateQueryPool) \ + VK_DEVICE_PFN(vkCreateRenderPass) \ + VK_DEVICE_PFN(vkCreateSampler) \ + VK_DEVICE_PFN(vkCreateSemaphore) \ + VK_DEVICE_PFN(vkCreateShaderModule) \ + VK_DEVICE_PFN(vkDestroyBuffer) \ + VK_DEVICE_PFN(vkDestroyBufferView) \ + VK_DEVICE_PFN(vkDestroyCommandPool) \ + VK_DEVICE_PFN(vkDestroyDescriptorPool) \ + VK_DEVICE_PFN(vkDestroyDescriptorSetLayout) \ + VK_DEVICE_PFN(vkDestroyDevice) \ + VK_DEVICE_PFN(vkDestroyEvent) \ + VK_DEVICE_PFN(vkDestroyFence) \ + VK_DEVICE_PFN(vkDestroyFramebuffer) \ + VK_DEVICE_PFN(vkDestroyImage) \ + VK_DEVICE_PFN(vkDestroyImageView) \ + VK_DEVICE_PFN(vkDestroyPipeline) \ + VK_DEVICE_PFN(vkDestroyPipelineCache) \ + VK_DEVICE_PFN(vkDestroyPipelineLayout) \ + VK_DEVICE_PFN(vkDestroyQueryPool) \ + VK_DEVICE_PFN(vkDestroyRenderPass) \ + VK_DEVICE_PFN(vkDestroySampler) \ + VK_DEVICE_PFN(vkDestroySemaphore) \ + VK_DEVICE_PFN(vkDestroyShaderModule) \ + VK_DEVICE_PFN(vkDeviceWaitIdle) \ + VK_DEVICE_PFN(vkEndCommandBuffer) \ + VK_DEVICE_PFN(vkFlushMappedMemoryRanges) \ + VK_DEVICE_PFN(vkFreeCommandBuffers) \ + VK_DEVICE_PFN(vkFreeDescriptorSets) \ + VK_DEVICE_PFN(vkFreeMemory) \ + VK_DEVICE_PFN(vkGetBufferMemoryRequirements) \ + VK_DEVICE_PFN(vkGetDeviceMemoryCommitment) \ + VK_DEVICE_PFN(vkGetDeviceQueue) \ + VK_DEVICE_PFN(vkGetEventStatus) \ + VK_DEVICE_PFN(vkGetFenceStatus) \ + VK_DEVICE_PFN(vkGetImageMemoryRequirements) \ + VK_DEVICE_PFN(vkGetImageSparseMemoryRequirements) \ + VK_DEVICE_PFN(vkGetImageSubresourceLayout) \ + VK_DEVICE_PFN(vkGetPipelineCacheData) \ + VK_DEVICE_PFN(vkGetQueryPoolResults) \ + VK_DEVICE_PFN(vkGetRenderAreaGranularity) \ + VK_DEVICE_PFN(vkInvalidateMappedMemoryRanges) \ + VK_DEVICE_PFN(vkMapMemory) \ + VK_DEVICE_PFN(vkMergePipelineCaches) \ + VK_DEVICE_PFN(vkQueueBindSparse) \ + VK_DEVICE_PFN(vkQueueSubmit) \ + VK_DEVICE_PFN(vkQueueWaitIdle) \ + VK_DEVICE_PFN(vkResetCommandBuffer) \ + VK_DEVICE_PFN(vkResetCommandPool) \ + VK_DEVICE_PFN(vkResetDescriptorPool) \ + VK_DEVICE_PFN(vkResetEvent) \ + VK_DEVICE_PFN(vkResetFences) \ + VK_DEVICE_PFN(vkSetEvent) \ + VK_DEVICE_PFN(vkUnmapMemory) \ + VK_DEVICE_PFN(vkUpdateDescriptorSets) \ + VK_DEVICE_PFN(vkWaitForFences) + +#define DECLARE_VK_PFN(name) PFN_##name name; + +struct vulkan_ops +{ +#define VK_INSTANCE_PFN DECLARE_VK_PFN +#define VK_INSTANCE_EXT_PFN DECLARE_VK_PFN +#define VK_DEVICE_PFN DECLARE_VK_PFN + VK_DEVICE_FUNCS() + VK_INSTANCE_FUNCS() +#undef VK_INSTANCE_PFN +#undef VK_INSTANCE_EXT_PFN +#undef VK_DEVICE_PFN + + PFN_vkCreateInstance vkCreateInstance; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; +}; + +struct wined3d_vk_info +{ + struct vulkan_ops vk_ops; + + VkInstance instance; + unsigned int api_version; + +#ifdef USE_WIN32_VULKAN + HMODULE vulkan_lib; +#endif +}; + +#define VK_CALL(f) (vk_info->vk_ops.f) + +#endif /* __WINE_WINED3D_VK */ diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt index 228295cedb1..8f2f98bc498 100644 --- a/media/doc/WINESYNC.txt +++ b/media/doc/WINESYNC.txt @@ -22,13 +22,13 @@ sdk/tools/wpp # Synced to WineStaging-2.9 The following libraries are shared with Wine. dll/directx/wine/amstream # Synced to WineStaging-3.9 -dll/directx/wine/d3d8 # Synced to WineStaging-3.3 -dll/directx/wine/d3d9 # Synced to WineStaging-3.3 +dll/directx/wine/d3d8 # Synced to WineStaging-4.18 +dll/directx/wine/d3d9 # Synced to WineStaging-4.18 dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-4.18 dll/directx/wine/d3drm # Synced to WineStaging-4.18 dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-6.0-rc5 dll/directx/wine/d3dxof # Synced to WineStaging-4.18 -dll/directx/wine/ddraw # Synced to WineStaging-3.3 +dll/directx/wine/ddraw # Synced to WineStaging-4.18 dll/directx/wine/devenum # Synced to WineStaging-4.18 dll/directx/wine/dinput # Synced to WineStaging-4.18 dll/directx/wine/dinput8 # Synced to WineStaging-4.18 @@ -42,7 +42,7 @@ dll/directx/wine/msdmo # Synced to WineStaging-4.18 dll/directx/wine/qcap # Synced to WineStaging-3.3 dll/directx/wine/qedit # Synced to WineStaging-3.17 dll/directx/wine/quartz # Synced to WineStaging-3.9 -dll/directx/wine/wined3d # Synced to WineStaging-3.3 +dll/directx/wine/wined3d # Synced to WineStaging-4.18 dll/win32/activeds # Synced to WineStaging-4.18 dll/win32/actxprxy # Synced to WineStaging-3.3 diff --git a/sdk/include/ddk/d3dhal.h b/sdk/include/ddk/d3dhal.h index 81f8d11e42e..6b093ead339 100644 --- a/sdk/include/ddk/d3dhal.h +++ b/sdk/include/ddk/d3dhal.h @@ -16,11 +16,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef _D3DHAL_H_ -#define _D3DHAL_H_ +#ifndef __WINE_D3DHAL_H +#define __WINE_D3DHAL_H #ifdef __cplusplus extern "C" { @@ -52,6 +52,23 @@ typedef struct _DDRAWI_DDRAWSURFACE_LCL FAR *LPDDRAWI_DDRAWSURFACE_LCL; * device info structures */ typedef struct _D3DDeviceDesc_V1 { + DWORD dwSize; + DWORD dwFlags; + D3DCOLORMODEL dcmColorModel; + DWORD dwDevCaps; + D3DTRANSFORMCAPS dtcTransformCaps; + BOOL bClipping; + D3DLIGHTINGCAPS dlcLightingCaps; + D3DPRIMCAPS dpcLineCaps; + D3DPRIMCAPS dpcTriCaps; + DWORD dwDeviceRenderBitDepth; + DWORD dwDeviceZBufferBitDepth; + DWORD dwMaxBufferSize; + DWORD dwMaxVertexCount; +} D3DDEVICEDESC_V1,*LPD3DDEVICEDESC_V1; + +typedef struct _D3DDeviceDesc_V2 +{ DWORD dwSize; DWORD dwFlags; D3DCOLORMODEL dcmColorModel; @@ -65,32 +82,44 @@ typedef struct _D3DDeviceDesc_V1 { DWORD dwDeviceZBufferBitDepth; DWORD dwMaxBufferSize; DWORD dwMaxVertexCount; -} D3DDEVICEDESC_V1, *LPD3DDEVICEDESC_V1; -/* this is to allow keeping the bulk of our OpenGL code out of x11drv */ -#define D3DDD_WINE_OPENGL_DEVICE 0x00008000 - -typedef struct _D3DHAL_GLOBALDRIVERDATA { + /* DirectX 5 */ + DWORD dwMinTextureWidth; + DWORD dwMinTextureHeight; + DWORD dwMaxTextureWidth; + DWORD dwMaxTextureHeight; + DWORD dwMinStippleWidth; + DWORD dwMaxStippleWidth; + DWORD dwMinStippleHeight; + DWORD dwMaxStippleHeight; +} D3DDEVICEDESC_V2, *LPD3DDEVICEDESC_V2; + +typedef struct _D3DDeviceDesc_V3 +{ DWORD dwSize; - D3DDEVICEDESC_V1 hwCaps; - DWORD dwNumVertices; - DWORD dwNumClipVertices; - DWORD dwNumTextureFormats; - LPDDSURFACEDESC lpTextureFormats; -} D3DHAL_GLOBALDRIVERDATA; - -#ifndef D3DHAL_GLOBALDRIVERDATA_DEFINED -typedef D3DHAL_GLOBALDRIVERDATA *LPD3DHAL_GLOBALDRIVERDATA; -#define D3DHAL_GLOBALDRIVERDATA_DEFINED -#endif + DWORD dwFlags; + D3DCOLORMODEL dcmColorModel; + DWORD dwDevCaps; + D3DTRANSFORMCAPS dtcTransformCaps; + BOOL bClipping; + D3DLIGHTINGCAPS dlcLightingCaps; + D3DPRIMCAPS dpcLineCaps; + D3DPRIMCAPS dpcTriCaps; + DWORD dwDeviceRenderBitDepth; + DWORD dwDeviceZBufferBitDepth; + DWORD dwMaxBufferSize; + DWORD dwMaxVertexCount; -typedef struct _D3DHAL_D3DEXTENDEDCAPS { - DWORD dwSize; /* DirectX 5 */ - DWORD dwMinTextureWidth, dwMaxTextureWidth; - DWORD dwMinTextureHeight, dwMaxTextureHeight; - DWORD dwMinStippleWidth, dwMaxStippleWidth; - DWORD dwMinStippleHeight, dwMaxStippleHeight; + DWORD dwMinTextureWidth; + DWORD dwMinTextureHeight; + DWORD dwMaxTextureWidth; + DWORD dwMaxTextureHeight; + DWORD dwMinStippleWidth; + DWORD dwMaxStippleWidth; + DWORD dwMinStippleHeight; + DWORD dwMaxStippleHeight; + /* DirectX 6 */ DWORD dwMaxTextureRepeat; DWORD dwMaxTextureAspectRatio; @@ -105,216 +134,243 @@ typedef struct _D3DHAL_D3DEXTENDEDCAPS { DWORD dwTextureOpCaps; WORD wMaxTextureBlendStages; WORD wMaxSimultaneousTextures; +} D3DDEVICEDESC_V3, *LPD3DDEVICEDESC_V3; + +typedef struct _D3DHAL_GLOBALDRIVERDATA { + DWORD dwSize; + D3DDEVICEDESC_V1 hwCaps; + DWORD dwNumVertices; + DWORD dwNumClipVertices; + DWORD dwNumTextureFormats; + LPDDSURFACEDESC lpTextureFormats; +} D3DHAL_GLOBALDRIVERDATA,*LPD3DHAL_GLOBALDRIVERDATA; + +typedef struct _D3DHAL_D3DEXTENDEDCAPS { + DWORD dwSize; + /* DirectX 5 */ + DWORD dwMinTextureWidth, dwMaxTextureWidth; + DWORD dwMinTextureHeight, dwMaxTextureHeight; + DWORD dwMinStippleWidth, dwMaxStippleWidth; + DWORD dwMinStippleHeight, dwMaxStippleHeight; + /* DirectX 6 */ + DWORD dwMaxTextureRepeat; + DWORD dwMaxTextureAspectRatio; + DWORD dwMaxAnisotropy; + D3DVALUE dvGuardBandLeft; + D3DVALUE dvGuardBandTop; + D3DVALUE dvGuardBandRight; + D3DVALUE dvGuardBandBottom; + D3DVALUE dvExtentsAdjust; + DWORD dwStencilCaps; + DWORD dwFVFCaps; + DWORD dwTextureOpCaps; + WORD wMaxTextureBlendStages; + WORD wMaxSimultaneousTextures; /* DirectX 7 */ - DWORD dwMaxActiveLights; - D3DVALUE dvMaxVertexW; - WORD wMaxUserClipPlanes; - WORD wMaxVertexBlendMatrices; - DWORD dwVertexProcessingCaps; - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; - DWORD dwReserved4; -} D3DHAL_D3DEXTENDEDCAPS, *LPD3DHAL_D3DEXTENDEDCAPS; + DWORD dwMaxActiveLights; + D3DVALUE dvMaxVertexW; + WORD wMaxUserClipPlanes; + WORD wMaxVertexBlendMatrices; + DWORD dwVertexProcessingCaps; + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwReserved4; +} D3DHAL_D3DEXTENDEDCAPS,*LPD3DHAL_D3DEXTENDEDCAPS; /***************************************************************************** * d3d->driver callbacks */ -typedef struct _D3DHAL_CONTEXTCREATEDATA *LPD3DHAL_CONTEXTCREATEDATA; -typedef struct _D3DHAL_CONTEXTDESTROYDATA *LPD3DHAL_CONTEXTDESTROYDATA; -typedef struct _D3DHAL_CONTEXTDESTROYALLDATA *LPD3DHAL_CONTEXTDESTROYALLDATA; -typedef struct _D3DHAL_SCENECAPTUREDATA *LPD3DHAL_SCENECAPTUREDATA; -typedef struct _D3DHAL_RENDERSTATEDATA *LPD3DHAL_RENDERSTATEDATA; -typedef struct _D3DHAL_RENDERPRIMITIVEDATA *LPD3DHAL_RENDERPRIMITIVEDATA; -typedef struct _D3DHAL_TEXTURECREATEDATA *LPD3DHAL_TEXTURECREATEDATA; -typedef struct _D3DHAL_TEXTUREDESTROYDATA *LPD3DHAL_TEXTUREDESTROYDATA; -typedef struct _D3DHAL_TEXTURESWAPDATA *LPD3DHAL_TEXTURESWAPDATA; -typedef struct _D3DHAL_TEXTUREGETSURFDATA *LPD3DHAL_TEXTUREGETSURFDATA; -typedef struct _D3DHAL_GETSTATEDATA *LPD3DHAL_GETSTATEDATA; +typedef struct _D3DHAL_CONTEXTCREATEDATA *LPD3DHAL_CONTEXTCREATEDATA; +typedef struct _D3DHAL_CONTEXTDESTROYDATA *LPD3DHAL_CONTEXTDESTROYDATA; +typedef struct _D3DHAL_CONTEXTDESTROYALLDATA *LPD3DHAL_CONTEXTDESTROYALLDATA; +typedef struct _D3DHAL_SCENECAPTUREDATA *LPD3DHAL_SCENECAPTUREDATA; +typedef struct _D3DHAL_RENDERSTATEDATA *LPD3DHAL_RENDERSTATEDATA; +typedef struct _D3DHAL_RENDERPRIMITIVEDATA *LPD3DHAL_RENDERPRIMITIVEDATA; +typedef struct _D3DHAL_TEXTURECREATEDATA *LPD3DHAL_TEXTURECREATEDATA; +typedef struct _D3DHAL_TEXTUREDESTROYDATA *LPD3DHAL_TEXTUREDESTROYDATA; +typedef struct _D3DHAL_TEXTURESWAPDATA *LPD3DHAL_TEXTURESWAPDATA; +typedef struct _D3DHAL_TEXTUREGETSURFDATA *LPD3DHAL_TEXTUREGETSURFDATA; +typedef struct _D3DHAL_GETSTATEDATA *LPD3DHAL_GETSTATEDATA; typedef DWORD (PASCAL *LPD3DHAL_CONTEXTCREATECB) (LPD3DHAL_CONTEXTCREATEDATA); typedef DWORD (PASCAL *LPD3DHAL_CONTEXTDESTROYCB) (LPD3DHAL_CONTEXTDESTROYDATA); typedef DWORD (PASCAL *LPD3DHAL_CONTEXTDESTROYALLCB)(LPD3DHAL_CONTEXTDESTROYALLDATA); -typedef DWORD (PASCAL *LPD3DHAL_SCENECAPTURECB) (LPD3DHAL_SCENECAPTUREDATA); -typedef DWORD (PASCAL *LPD3DHAL_RENDERSTATECB) (LPD3DHAL_RENDERSTATEDATA); +typedef DWORD (PASCAL *LPD3DHAL_SCENECAPTURECB) (LPD3DHAL_SCENECAPTUREDATA); +typedef DWORD (PASCAL *LPD3DHAL_RENDERSTATECB) (LPD3DHAL_RENDERSTATEDATA); typedef DWORD (PASCAL *LPD3DHAL_RENDERPRIMITIVECB) (LPD3DHAL_RENDERPRIMITIVEDATA); typedef DWORD (PASCAL *LPD3DHAL_TEXTURECREATECB) (LPD3DHAL_TEXTURECREATEDATA); typedef DWORD (PASCAL *LPD3DHAL_TEXTUREDESTROYCB) (LPD3DHAL_TEXTUREDESTROYDATA); -typedef DWORD (PASCAL *LPD3DHAL_TEXTURESWAPCB) (LPD3DHAL_TEXTURESWAPDATA); +typedef DWORD (PASCAL *LPD3DHAL_TEXTURESWAPCB) (LPD3DHAL_TEXTURESWAPDATA); typedef DWORD (PASCAL *LPD3DHAL_TEXTUREGETSURFCB) (LPD3DHAL_TEXTUREGETSURFDATA); -typedef DWORD (PASCAL *LPD3DHAL_GETSTATECB) (LPD3DHAL_GETSTATEDATA); +typedef DWORD (PASCAL *LPD3DHAL_GETSTATECB) (LPD3DHAL_GETSTATEDATA); typedef struct _D3DHAL_CALLBACKS { - DWORD dwSize; - LPD3DHAL_CONTEXTCREATECB ContextCreate; - LPD3DHAL_CONTEXTDESTROYCB ContextDestroy; - LPD3DHAL_CONTEXTDESTROYALLCB ContextDestroyAll; - LPD3DHAL_SCENECAPTURECB SceneCapture; - LPVOID lpReserved10; - LPVOID lpReserved11; - LPD3DHAL_RENDERSTATECB RenderState; - LPD3DHAL_RENDERPRIMITIVECB RenderPrimitive; - DWORD dwReserved; - LPD3DHAL_TEXTURECREATECB TextureCreate; - LPD3DHAL_TEXTUREDESTROYCB TextureDestroy; - LPD3DHAL_TEXTURESWAPCB TextureSwap; - LPD3DHAL_TEXTUREGETSURFCB TextureGetSurf; + DWORD dwSize; + LPD3DHAL_CONTEXTCREATECB ContextCreate; + LPD3DHAL_CONTEXTDESTROYCB ContextDestroy; + LPD3DHAL_CONTEXTDESTROYALLCB ContextDestroyAll; + LPD3DHAL_SCENECAPTURECB SceneCapture; + LPVOID lpReserved10; + LPVOID lpReserved11; + LPD3DHAL_RENDERSTATECB RenderState; + LPD3DHAL_RENDERPRIMITIVECB RenderPrimitive; + DWORD dwReserved; + LPD3DHAL_TEXTURECREATECB TextureCreate; + LPD3DHAL_TEXTUREDESTROYCB TextureDestroy; + LPD3DHAL_TEXTURESWAPCB TextureSwap; + LPD3DHAL_TEXTUREGETSURFCB TextureGetSurf; /* now why did MS create CALLBACKS2 and CALLBACKS3 structures if * all these reserved fields were available? we may never know */ - LPVOID lpReserved12; - LPVOID lpReserved13; - LPVOID lpReserved14; - LPVOID lpReserved15; - LPVOID lpReserved16; - LPVOID lpReserved17; - LPVOID lpReserved18; - LPVOID lpReserved19; - LPVOID lpReserved20; - LPVOID lpReserved21; - LPD3DHAL_GETSTATECB GetState; - DWORD dwReserved0; - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; - DWORD dwReserved4; - DWORD dwReserved5; - DWORD dwReserved6; - DWORD dwReserved7; - DWORD dwReserved8; - DWORD dwReserved9; -} D3DHAL_CALLBACKS; - -#ifndef D3DHAL_CALLBACKS_DEFINED -typedef D3DHAL_CALLBACKS *LPD3DHAL_CALLBACKS; -#define D3DHAL_CALLBACKS_DEFINED -#endif - -typedef struct _D3DHAL_SETRENDERTARGETDATA *LPD3DHAL_SETRENDERTARGETDATA; -typedef struct _D3DHAL_CLEARDATA *LPD3DHAL_CLEARDATA; -typedef struct _D3DHAL_DRAWONEPRIMITIVEDATA *LPD3DHAL_DRAWONEPRIMITIVEDATA; -typedef struct _D3DHAL_DRAWONEINDEXEDPRIMITIVEDATA *LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA; -typedef struct _D3DHAL_DRAWPRIMITIVESDATA *LPD3DHAL_DRAWPRIMITIVESDATA; - -typedef DWORD (PASCAL *LPD3DHAL_SETRENDERTARGETCB) (LPD3DHAL_SETRENDERTARGETDATA); -typedef DWORD (PASCAL *LPD3DHAL_CLEARCB) (LPD3DHAL_CLEARDATA); -typedef DWORD (PASCAL *LPD3DHAL_DRAWONEPRIMITIVECB) (LPD3DHAL_DRAWONEPRIMITIVEDATA); + LPVOID lpReserved12; + LPVOID lpReserved13; + LPVOID lpReserved14; + LPVOID lpReserved15; + LPVOID lpReserved16; + LPVOID lpReserved17; + LPVOID lpReserved18; + LPVOID lpReserved19; + LPVOID lpReserved20; + LPVOID lpReserved21; + LPD3DHAL_GETSTATECB GetState; + DWORD dwReserved0; + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwReserved4; + DWORD dwReserved5; + DWORD dwReserved6; + DWORD dwReserved7; + DWORD dwReserved8; + DWORD dwReserved9; +} D3DHAL_CALLBACKS,*LPD3DHAL_CALLBACKS; + +typedef struct _D3DHAL_SETRENDERTARGETDATA *LPD3DHAL_SETRENDERTARGETDATA; +typedef struct _D3DHAL_CLEARDATA *LPD3DHAL_CLEARDATA; +typedef struct _D3DHAL_DRAWONEPRIMITIVEDATA *LPD3DHAL_DRAWONEPRIMITIVEDATA; +typedef struct _D3DHAL_DRAWONEINDEXEDPRIMITIVEDATA *LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA; +typedef struct _D3DHAL_DRAWPRIMITIVESDATA *LPD3DHAL_DRAWPRIMITIVESDATA; + +typedef DWORD (PASCAL *LPD3DHAL_SETRENDERTARGETCB) (LPD3DHAL_SETRENDERTARGETDATA); +typedef DWORD (PASCAL *LPD3DHAL_CLEARCB) (LPD3DHAL_CLEARDATA); +typedef DWORD (PASCAL *LPD3DHAL_DRAWONEPRIMITIVECB) (LPD3DHAL_DRAWONEPRIMITIVEDATA); typedef DWORD (PASCAL *LPD3DHAL_DRAWONEINDEXEDPRIMITIVECB)(LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA); -typedef DWORD (PASCAL *LPD3DHAL_DRAWPRIMITIVESCB) (LPD3DHAL_DRAWPRIMITIVESDATA); +typedef DWORD (PASCAL *LPD3DHAL_DRAWPRIMITIVESCB) (LPD3DHAL_DRAWPRIMITIVESDATA); typedef struct _D3DHAL_CALLBACKS2 { - DWORD dwSize; - DWORD dwFlags; - LPD3DHAL_SETRENDERTARGETCB SetRenderTarget; - LPD3DHAL_CLEARCB Clear; - LPD3DHAL_DRAWONEPRIMITIVECB DrawOnePrimitive; - LPD3DHAL_DRAWONEINDEXEDPRIMITIVECB DrawOneIndexedPrimitive; - LPD3DHAL_DRAWPRIMITIVESCB DrawPrimitives; -} D3DHAL_CALLBACKS2, *LPD3DHAL_CALLBACKS2; - -typedef struct _D3DHAL_CLEAR2DATA *LPD3DHAL_CLEAR2DATA; -typedef struct _D3DHAL_VALIDATETEXTURESTAGESTATEDATA *LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA; -typedef struct _D3DHAL_DRAWPRIMITIVES2DATA *LPD3DHAL_DRAWPRIMITIVES2DATA; - -typedef DWORD (PASCAL *LPD3DHAL_CLEAR2CB) (LPD3DHAL_CLEAR2DATA); -typedef DWORD (PASCAL *LPD3DHAL_VALIDATETEXTURESTAGESTATECB) (LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA); -typedef DWORD (PASCAL *LPD3DHAL_DRAWPRIMITIVES2CB) (LPD3DHAL_DRAWPRIMITIVES2DATA); + DWORD dwSize; + DWORD dwFlags; + LPD3DHAL_SETRENDERTARGETCB SetRenderTarget; + LPD3DHAL_CLEARCB Clear; + LPD3DHAL_DRAWONEPRIMITIVECB DrawOnePrimitive; + LPD3DHAL_DRAWONEINDEXEDPRIMITIVECB DrawOneIndexedPrimitive; + LPD3DHAL_DRAWPRIMITIVESCB DrawPrimitives; +} D3DHAL_CALLBACKS2,*LPD3DHAL_CALLBACKS2; + +typedef struct _D3DHAL_CLEAR2DATA *LPD3DHAL_CLEAR2DATA; +typedef struct _D3DHAL_VALIDATETEXTURESTAGESTATEDATA *LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA; +typedef struct _D3DHAL_DRAWPRIMITIVES2DATA *LPD3DHAL_DRAWPRIMITIVES2DATA; + +typedef DWORD (PASCAL *LPD3DHAL_CLEAR2CB) (LPD3DHAL_CLEAR2DATA); +typedef DWORD (PASCAL *LPD3DHAL_VALIDATETEXTURESTAGESTATECB)(LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA); +typedef DWORD (PASCAL *LPD3DHAL_DRAWPRIMITIVES2CB) (LPD3DHAL_DRAWPRIMITIVES2DATA); typedef struct _D3DHAL_CALLBACKS3 { - DWORD dwSize; - DWORD dwFlags; - LPD3DHAL_CLEAR2CB Clear2; - LPVOID lpvReserved; - LPD3DHAL_VALIDATETEXTURESTAGESTATECB ValidateTextureStageState; - LPD3DHAL_DRAWPRIMITIVES2CB DrawPrimitives2; -} D3DHAL_CALLBACKS3, *LPD3DHAL_CALLBACKS3; + DWORD dwSize; + DWORD dwFlags; + LPD3DHAL_CLEAR2CB Clear2; + LPVOID lpvReserved; + LPD3DHAL_VALIDATETEXTURESTAGESTATECB ValidateTextureStageState; + LPD3DHAL_DRAWPRIMITIVES2CB DrawPrimitives2; +} D3DHAL_CALLBACKS3,*LPD3DHAL_CALLBACKS3; /***************************************************************************** * parameter structures */ typedef struct _D3DHAL_CONTEXTCREATEDATA { - _ANONYMOUS_UNION union { - LPDDRAWI_DIRECTDRAW_GBL lpDDGbl; /* pre-DirectX 7 */ - LPDDRAWI_DIRECTDRAW_LCL lpDDLcl; /* DirectX 7 */ + union { + LPDDRAWI_DIRECTDRAW_GBL lpDDGbl; /* pre-DirectX 7 */ + LPDDRAWI_DIRECTDRAW_LCL lpDDLcl; /* DirectX 7 */ } DUMMYUNIONNAME1; - _ANONYMOUS_UNION union { - LPDIRECTDRAWSURFACE lpDDS; - LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl; /* DirectX 7 */ + union { + LPDIRECTDRAWSURFACE lpDDS; + LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl; /* DirectX 7 */ } DUMMYUNIONNAME2; - _ANONYMOUS_UNION union { - LPDIRECTDRAWSURFACE lpDDSZ; - LPDDRAWI_DDRAWSURFACE_LCL lpDDSZLcl; /* DirectX 7 */ + union { + LPDIRECTDRAWSURFACE lpDDSZ; + LPDDRAWI_DDRAWSURFACE_LCL lpDDSZLcl; /* DirectX 7 */ } DUMMYUNIONNAME3; - _ANONYMOUS_UNION union { - DWORD dwPID; - ULONG_PTR dwrstates; + union { + DWORD dwPID; + ULONG_PTR dwrstates; } DUMMYUNIONNAME4; - ULONG_PTR dwhContext; - HRESULT ddrval; + ULONG_PTR dwhContext; + HRESULT ddrval; } D3DHAL_CONTEXTCREATEDATA; typedef struct _D3DHAL_CONTEXTDESTROYDATA { - ULONG_PTR dwhContext; - HRESULT ddrval; + ULONG_PTR dwhContext; + HRESULT ddrval; } D3DHAL_CONTEXTDESTROYDATA; typedef struct _D3DHAL_CONTEXTDESTROYALLDATA { - DWORD dwPID; - HRESULT ddrval; + DWORD dwPID; + HRESULT ddrval; } D3DHAL_CONTEXTDESTROYALLDATA; typedef struct _D3DHAL_SCENECAPTUREDATA { - ULONG_PTR dwhContext; - DWORD dwFlag; - HRESULT ddrval; + ULONG_PTR dwhContext; + DWORD dwFlag; + HRESULT ddrval; } D3DHAL_SCENECAPTUREDATA; -#define D3DHAL_SCENE_CAPTURE_START 0x00000000 -#define D3DHAL_SCENE_CAPTURE_END 0x00000001 +#define D3DHAL_SCENE_CAPTURE_START 0x00000000 +#define D3DHAL_SCENE_CAPTURE_END 0x00000001 typedef struct _D3DHAL_SETRENDERTARGETDATA { - ULONG_PTR dwhContext; - _ANONYMOUS_UNION union { - LPDIRECTDRAWSURFACE lpDDS; - LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl; + ULONG_PTR dwhContext; + union { + LPDIRECTDRAWSURFACE lpDDS; + LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl; } DUMMYUNIONNAME1; - _ANONYMOUS_UNION union { - LPDIRECTDRAWSURFACE lpDDSZ; - LPDDRAWI_DDRAWSURFACE_LCL lpDDSZLcl; + union { + LPDIRECTDRAWSURFACE lpDDSZ; + LPDDRAWI_DDRAWSURFACE_LCL lpDDSZLcl; } DUMMYUNIONNAME2; - HRESULT ddrval; + HRESULT ddrval; } D3DHAL_SETRENDERTARGETDATA; typedef struct _D3DHAL_DRAWPRIMITIVES2DATA { - ULONG_PTR dwhContext; - DWORD dwFlags; - DWORD dwVertexType; - LPDDRAWI_DDRAWSURFACE_LCL lpDDCommands; - DWORD dwCommandOffset; - DWORD dwCommandLength; - _ANONYMOUS_UNION union { - LPDDRAWI_DDRAWSURFACE_LCL lpDDVertex; - LPVOID lpVertices; + ULONG_PTR dwhContext; + DWORD dwFlags; + DWORD dwVertexType; + LPDDRAWI_DDRAWSURFACE_LCL lpDDCommands; + DWORD dwCommandOffset; + DWORD dwCommandLength; + union { + LPDDRAWI_DDRAWSURFACE_LCL lpDDVertex; + LPVOID lpVertices; } DUMMYUNIONNAME1; - DWORD dwVertexOffset; - DWORD dwVertexLength; - DWORD dwReqVertexBufSize; - DWORD dwReqCommandBufSize; - LPDWORD lpdwRStates; - _ANONYMOUS_UNION union { - DWORD dwVertexSize; - HRESULT ddrval; + DWORD dwVertexOffset; + DWORD dwVertexLength; + DWORD dwReqVertexBufSize; + DWORD dwReqCommandBufSize; + LPDWORD lpdwRStates; + union { + DWORD dwVertexSize; + HRESULT ddrval; } DUMMYUNIONNAME2; - DWORD dwErrorOffset; + DWORD dwErrorOffset; } D3DHAL_DRAWPRIMITIVES2DATA; -#define D3DHALDP2_USERMEMVERTICES 0x00000001 -#define D3DHALDP2_EXECUTEBUFFER 0x00000002 -#define D3DHALDP2_SWAPVERTEXBUFFER 0x00000004 -#define D3DHALDP2_SWAPCOMMANDBUFFER 0x00000008 -#define D3DHALDP2_REQVERTEXBUFSIZE 0x00000010 -#define D3DHALDP2_REQCOMMANDBUFSIZE 0x00000020 -#define D3DHALDP2_VIDMEMVERTEXBUF 0x00000040 -#define D3DHALDP2_VIDMEMCOMMANDBUF 0x00000080 +#define D3DHALDP2_USERMEMVERTICES 0x00000001 +#define D3DHALDP2_EXECUTEBUFFER 0x00000002 +#define D3DHALDP2_SWAPVERTEXBUFFER 0x00000004 +#define D3DHALDP2_SWAPCOMMANDBUFFER 0x00000008 +#define D3DHALDP2_REQVERTEXBUFSIZE 0x00000010 +#define D3DHALDP2_REQCOMMANDBUFSIZE 0x00000020 +#define D3DHALDP2_VIDMEMVERTEXBUF 0x00000040 +#define D3DHALDP2_VIDMEMCOMMANDBUF 0x00000080 /***************************************************************************** * DrawPrimitives2 command structures @@ -322,101 +378,50 @@ typedef struct _D3DHAL_DRAWPRIMITIVES2DATA { typedef struct _D3DHAL_DP2COMMAND { BYTE bCommand; BYTE bReserved; - _ANONYMOUS_UNION union { + union { WORD wPrimitiveCount; WORD wStateCount; } DUMMYUNIONNAME; -} D3DHAL_DP2COMMAND, *LPD3DHAL_DP2COMMAND; +} D3DHAL_DP2COMMAND,*LPD3DHAL_DP2COMMAND; typedef enum _D3DHAL_DP2OPERATION { - D3DDP2OP_POINTS = 1, - D3DDP2OP_INDEXEDLINELIST = 2, - D3DDP2OP_INDEXEDTRIANGLELIST = 3, - D3DDP2OP_RENDERSTATE = 8, - D3DDP2OP_LINELIST = 15, - D3DDP2OP_LINESTRIP = 16, - D3DDP2OP_INDEXEDLINESTRIP = 17, - D3DDP2OP_TRIANGLELIST = 18, - D3DDP2OP_TRIANGLESTRIP = 19, - D3DDP2OP_INDEXEDTRIANGLESTRIP = 20, - D3DDP2OP_TRIANGLEFAN = 21, - D3DDP2OP_INDEXEDTRIANGLEFAN = 22, - D3DDP2OP_TRIANGLEFAN_IMM = 23, - D3DDP2OP_LINELIST_IMM = 24, - D3DDP2OP_TEXTURESTAGESTATE = 25, - D3DDP2OP_INDEXEDTRIANGLELIST2 = 26, - D3DDP2OP_INDEXEDLINELIST2 = 27, - D3DDP2OP_VIEWPORTINFO = 28, - D3DDP2OP_WINFO = 29, + D3DDP2OP_POINTS = 1, + D3DDP2OP_INDEXEDLINELIST = 2, + D3DDP2OP_INDEXEDTRIANGLELIST = 3, + D3DDP2OP_RENDERSTATE = 8, + D3DDP2OP_LINELIST = 15, + D3DDP2OP_LINESTRIP = 16, + D3DDP2OP_INDEXEDLINESTRIP = 17, + D3DDP2OP_TRIANGLELIST = 18, + D3DDP2OP_TRIANGLESTRIP = 19, + D3DDP2OP_INDEXEDTRIANGLESTRIP = 20, + D3DDP2OP_TRIANGLEFAN = 21, + D3DDP2OP_INDEXEDTRIANGLEFAN = 22, + D3DDP2OP_TRIANGLEFAN_IMM = 23, + D3DDP2OP_LINELIST_IMM = 24, + D3DDP2OP_TEXTURESTAGESTATE = 25, + D3DDP2OP_INDEXEDTRIANGLELIST2 = 26, + D3DDP2OP_INDEXEDLINELIST2 = 27, + D3DDP2OP_VIEWPORTINFO = 28, + D3DDP2OP_WINFO = 29, /* pre-DirectX 7 interfaces */ - D3DDP2OP_SETPALETTE = 30, - D3DDP2OP_UPDATEPALETTE = 31, + D3DDP2OP_SETPALETTE = 30, + D3DDP2OP_UPDATEPALETTE = 31, /* DirectX 7 interfaces */ - D3DDP2OP_ZRANGE = 32, - D3DDP2OP_SETMATERIAL = 33, - D3DDP2OP_SETLIGHT = 34, - D3DDP2OP_CREATELIGHT = 35, - D3DDP2OP_SETTRANSFORM = 36, - D3DDP2OP_TEXBLT = 38, - D3DDP2OP_STATESET = 39, - D3DDP2OP_SETPRIORITY = 40, + D3DDP2OP_ZRANGE = 32, + D3DDP2OP_SETMATERIAL = 33, + D3DDP2OP_SETLIGHT = 34, + D3DDP2OP_CREATELIGHT = 35, + D3DDP2OP_SETTRANSFORM = 36, + D3DDP2OP_TEXBLT = 38, + D3DDP2OP_STATESET = 39, + D3DDP2OP_SETPRIORITY = 40, /* all interfaces */ - D3DDP2OP_SETRENDERTARGET = 41, - D3DDP2OP_CLEAR = 42, + D3DDP2OP_SETRENDERTARGET = 41, + D3DDP2OP_CLEAR = 42, /* DirectX 7 interfaces */ - D3DDP2OP_SETTEXLOD = 43, - D3DPP2OP_SETCLIPPLANE = 44, -#if(DIRECT3D_VERSION >= 0x0800) - D3DDP2OP_CREATEVERTEXSHADER = 45, - D3DDP2OP_DELETEVERTEXSHADER = 46, - D3DDP2OP_SETVERTEXSHADER = 47, - D3DDP2OP_SETVERTEXSHADERCONST = 48, - D3DDP2OP_SETSTREAMSOURCE = 49, - D3DDP2OP_SETSTREAMSOURCEUM = 50, - D3DDP2OP_SETINDICES = 51, - D3DDP2OP_DRAWPRIMITIVE = 52, - D3DDP2OP_DRAWINDEXEDPRIMITIVE = 53, - D3DDP2OP_CREATEPIXELSHADER = 54, - D3DDP2OP_DELETEPIXELSHADER = 55, - D3DDP2OP_SETPIXELSHADER = 56, - D3DDP2OP_SETPIXELSHADERCONST = 57, - D3DDP2OP_CLIPPEDTRIANGLEFAN = 58, - D3DDP2OP_DRAWPRIMITIVE2 = 59, - D3DDP2OP_DRAWINDEXEDPRIMITIVE2= 60, - D3DDP2OP_DRAWRECTPATCH = 61, - D3DDP2OP_DRAWTRIPATCH = 62, - D3DDP2OP_VOLUMEBLT = 63, - D3DDP2OP_BUFFERBLT = 64, - D3DDP2OP_MULTIPLYTRANSFORM = 65, - D3DDP2OP_ADDDIRTYRECT = 66, - D3DDP2OP_ADDDIRTYBOX = 67, -#endif -#if(DIRECT3D_VERSION >= 0x0900) - D3DDP2OP_CREATEVERTEXSHADERDECL = 71, - D3DDP2OP_DELETEVERTEXSHADERDECL = 72, - D3DDP2OP_SETVERTEXSHADERDECL = 73, - D3DDP2OP_CREATEVERTEXSHADERFUNC = 74, - D3DDP2OP_DELETEVERTEXSHADERFUNC = 75, - D3DDP2OP_SETVERTEXSHADERFUNC = 76, - D3DDP2OP_SETVERTEXSHADERCONSTI = 77, - D3DDP2OP_SETSCISSORRECT = 79, - D3DDP2OP_SETSTREAMSOURCE2 = 80, - D3DDP2OP_BLT = 81, - D3DDP2OP_COLORFILL = 82, - D3DDP2OP_SETVERTEXSHADERCONSTB = 83, - D3DDP2OP_CREATEQUERY = 84, - D3DDP2OP_SETRENDERTARGET2 = 85, - D3DDP2OP_SETDEPTHSTENCIL = 86, - D3DDP2OP_RESPONSECONTINUE = 87, - D3DDP2OP_RESPONSEQUERY = 88, - D3DDP2OP_GENERATEMIPSUBLEVELS = 89, - D3DDP2OP_DELETEQUERY = 90, - D3DDP2OP_ISSUEQUERY = 91, - D3DDP2OP_SETPIXELSHADERCONSTI = 93, - D3DDP2OP_SETPIXELSHADERCONSTB = 94, - D3DDP2OP_SETSTREAMSOURCEFREQ = 95, - D3DDP2OP_SURFACEBLT = 96 -#endif + D3DDP2OP_SETTEXLOD = 43, + D3DPP2OP_SETCLIPPLANE = 44 } D3DHAL_DP2OPERATION; /* point primitives */ @@ -424,84 +429,84 @@ typedef enum _D3DHAL_DP2OPERATION { typedef struct _D3DHAL_POINTS { WORD wCount; WORD wVStart; -} D3DHAL_DP2POINTS, *LPD3DHAL_DP2POINTS; +} D3DHAL_DP2POINTS,*LPD3DHAL_DP2POINTS; /* line primitives */ typedef struct _D3DHAL_DP2STARTVERTEX { WORD wVStart; -} D3DHAL_DP2STARTVERTEX, *LPD3DHAL_DP2STARTVERTEX; +} D3DHAL_DP2STARTVERTEX,*LPD3DHAL_DP2STARTVERTEX; typedef struct _D3DHAL_DP2LINELIST { WORD wVStart; -} D3DHAL_DP2LINELIST, *LPD3DHAL_DP2LINELIST; +} D3DHAL_DP2LINELIST,*LPD3DHAL_DP2LINELIST; typedef struct _D3DHAL_DP2INDEXEDLINELIST { WORD wV1; WORD wV2; -} D3DHAL_DP2INDEXEDLINELIST, *LPD3DHAL_DP2INDEXEDLINELIST; +} D3DHAL_DP2INDEXEDLINELIST,*LPD3DHAL_DP2INDEXEDLINELIST; typedef struct _D3DHAL_DP2LINESTRIP { WORD wVStart; -} D3DHAL_DP2LINESTRIP, *LPD3DHAL_DP2LINESTRIP; +} D3DHAL_DP2LINESTRIP,*LPD3DHAL_DP2LINESTRIP; typedef struct _D3DHAL_DP2INDEXEDLINESTRIP { WORD wV[2]; -} D3DHAL_DP2INDEXEDLINESTRIP, *LPD3DHAL_DP2INDEXEDLINESTRIP; +} D3DHAL_DP2INDEXEDLINESTRIP,*LPD3DHAL_DP2INDEXEDLINESTRIP; /* triangle primitives */ typedef struct _D3DHAL_DP2TRIANGLELIST { WORD wVStart; -} D3DHAL_DP2TRIANGLELIST, *LPD3DHAL_DP2TRIANGLELIST; +} D3DHAL_DP2TRIANGLELIST,*LPD3DHAL_DP2TRIANGLELIST; typedef struct _D3DHAL_DP2INDEXEDTRIANGLELIST { WORD wV1; WORD wV2; WORD wV3; WORD wFlags; -} D3DHAL_DP2INDEXEDTRIANGLELIST, *LPD3DHAL_DP2INDEXEDTRIANGLELIST; +} D3DHAL_DP2INDEXEDTRIANGLELIST,*LPD3DHAL_DP2INDEXEDTRIANGLELIST; typedef struct _D3DHAL_DP2INDEXEDTRIANGLELIST2 { WORD wV1; WORD wV2; WORD wV3; -} D3DHAL_DP2INDEXEDTRIANGLELIST2, *LPD3DHAL_DP2INDEXEDTRIANGLELIST2; +} D3DHAL_DP2INDEXEDTRIANGLELIST2,*LPD3DHAL_DP2INDEXEDTRIANGLELIST2; typedef struct _D3DHAL_DP2TRIANGLESTRIP { WORD wVStart; -} D3DHAL_DP2TRIANGLESTRIP, *LPD3DHAL_DP2TRIANGLESTRIP; +} D3DHAL_DP2TRIANGLESTRIP,*LPD3DHAL_DP2TRIANGLESTRIP; typedef struct _D3DHAL_DP2INDEXEDTRIANGLESTRIP { WORD wV[3]; -} D3DHAL_DP2INDEXEDTRIANGLESTRIP, *LPD3DHAL_DP2INDEXEDTRIANGLESTRIP; +} D3DHAL_DP2INDEXEDTRIANGLESTRIP,*LPD3DHAL_DP2INDEXEDTRIANGLESTRIP; typedef struct _D3DHAL_DP2TRIANGLEFAN { WORD wVStart; -} D3DHAL_DP2TRIANGLEFAN, *LPD3DHAL_DP2TRIANGLEFAN; +} D3DHAL_DP2TRIANGLEFAN,*LPD3DHAL_DP2TRIANGLEFAN; typedef struct _D3DHAL_DP2INDEXEDTRIANGLEFAN { WORD wV[3]; -} D3DHAL_DP2INDEXEDTRIANGLEFAN, *LPD3DHAL_DP2INDEXEDTRIANGLEFAN; +} D3DHAL_DP2INDEXEDTRIANGLEFAN,*LPD3DHAL_DP2INDEXEDTRIANGLEFAN; typedef struct _D3DHAL_DP2TRIANGLEFAN_IMM { DWORD dwEdgeFlags; -} D3DHAL_DP2TRIANGLEFAN_IMM, *LPD3DHAL_DP2TRIANGLEFAN_IMM; +} D3DHAL_DP2TRIANGLEFAN_IMM,*LPD3DHAL_DP2TRIANGLEFAN_IMM; /* render states */ typedef struct _D3DHAL_DP2RENDERSTATE { - D3DRENDERSTATETYPE RenderState; - _ANONYMOUS_UNION union { + D3DRENDERSTATETYPE RenderState; + union { D3DVALUE dvState; DWORD dwState; } DUMMYUNIONNAME; -} D3DHAL_DP2RENDERSTATE, *LPD3DHAL_DP2RENDERSTATE; +} D3DHAL_DP2RENDERSTATE,*LPD3DHAL_DP2RENDERSTATE; typedef struct _D3DHAL_DP2TEXTURESTAGESTATE { - WORD wStage; - WORD TSState; + WORD wStage; + WORD TSState; DWORD dwValue; -} D3DHAL_DP2TEXTURESTAGESTATE, *LPD3DHAL_DP2TEXTURESTAGESTATE; +} D3DHAL_DP2TEXTURESTAGESTATE,*LPD3DHAL_DP2TEXTURESTAGESTATE; #define D3DTSS_TEXTUREMAP 0 @@ -510,49 +515,49 @@ typedef struct _D3DHAL_DP2VIEWPORTINFO { DWORD dwY; DWORD dwWidth; DWORD dwHeight; -} D3DHAL_DP2VIEWPORTINFO, *LPD3DHAL_DP2VIEWPORTINFO; +} D3DHAL_DP2VIEWPORTINFO,*LPD3DHAL_DP2VIEWPORTINFO; typedef struct _D3DHAL_DP2WINFO { D3DVALUE dwWNear; D3DVALUE dwWFar; -} D3DHAL_DP2WINFO, *LPD3DHAL_DP2WINFO; +} D3DHAL_DP2WINFO,*LPD3DHAL_DP2WINFO; typedef struct _D3DHAL_DP2SETPALETTE { DWORD dwPaletteHandle; DWORD dwPaletteFlags; DWORD dwSurfaceHandle; -} D3DHAL_DP2SETPALETTE, *LPD3DHAL_DP2SETPALETTE; +} D3DHAL_DP2SETPALETTE,*LPD3DHAL_DP2SETPALETTE; typedef struct _D3DHAL_DP2UPDATEPALETTE { DWORD dwPaletteHandle; - WORD wStartIndex; - WORD wNumEntries; -} D3DHAL_DP2UPDATEPALETTE, *LPD3DHAL_DP2UPDATEPALETTE; + WORD wStartIndex; + WORD wNumEntries; +} D3DHAL_DP2UPDATEPALETTE,*LPD3DHAL_DP2UPDATEPALETTE; typedef struct _D3DHAL_DP2ZRANGE { D3DVALUE dvMinZ; D3DVALUE dvMaxZ; -} D3DHAL_DP2ZRANGE, *LPD3DHAL_DP2ZRANGE; +} D3DHAL_DP2ZRANGE,*LPD3DHAL_DP2ZRANGE; typedef D3DMATERIAL7 D3DHAL_DP2SETMATERIAL,*LPD3DHAL_DP2SETMATERIAL; typedef struct _D3DHAL_DP2SETLIGHT { DWORD dwIndex; DWORD dwDataType; -} D3DHAL_DP2SETLIGHT, *LPD3DHAL_DP2SETLIGHT; +} D3DHAL_DP2SETLIGHT,*LPD3DHAL_DP2SETLIGHT; -#define D3DHAL_SETLIGHT_ENABLE 0 -#define D3DHAL_SETLIGHT_DISABLE 1 -#define D3DHAL_SETLIGHT_DATA 2 +#define D3DHAL_SETLIGHT_ENABLE 0 +#define D3DHAL_SETLIGHT_DISABLE 1 +#define D3DHAL_SETLIGHT_DATA 2 typedef struct _D3DHAL_DP2CREATELIGHT { DWORD dwIndex; -} D3DHAL_DP2CREATELIGHT, *LPD3DHAL_DP2CREATELIGHT; +} D3DHAL_DP2CREATELIGHT,*LPD3DHAL_DP2CREATELIGHT; typedef struct _D3DHAL_DP2SETTRANSFORM { - D3DTRANSFORMSTATETYPE xfrmType; - D3DMATRIX matrix; -} D3DHAL_DP2SETTRANSFORM, *LPD3DHAL_DP2SETTRANSFORM; + D3DTRANSFORMSTATETYPE xfrmType; + D3DMATRIX matrix; +} D3DHAL_DP2SETTRANSFORM,*LPD3DHAL_DP2SETTRANSFORM; typedef struct _D3DHAL_DP2TEXBLT { DWORD dwDDDestSurface; @@ -560,237 +565,45 @@ typedef struct _D3DHAL_DP2TEXBLT { POINT pDest; RECTL rSrc; DWORD dwFlags; -} D3DHAL_DP2TEXBLT, *LPD3DHAL_DP2TEXBLT; +} D3DHAL_DP2TEXBLT,*LPD3DHAL_DP2TEXBLT; typedef struct _D3DHAL_DP2STATESET { - DWORD dwOperation; - DWORD dwParam; - D3DSTATEBLOCKTYPE sbType; -} D3DHAL_DP2STATESET, *LPD3DHAL_DP2STATESET; + DWORD dwOperation; + DWORD dwParam; + D3DSTATEBLOCKTYPE sbType; +} D3DHAL_DP2STATESET,*LPD3DHAL_DP2STATESET; -#define D3DHAL_STATESETBEGIN 0 -#define D3DHAL_STATESETEND 1 -#define D3DHAL_STATESETDELETE 2 -#define D3DHAL_STATESETEXECUTE 3 -#define D3DHAL_STATESETCAPTURE 4 +#define D3DHAL_STATESETBEGIN 0 +#define D3DHAL_STATESETEND 1 +#define D3DHAL_STATESETDELETE 2 +#define D3DHAL_STATESETEXECUTE 3 +#define D3DHAL_STATESETCAPTURE 4 typedef struct _D3DHAL_DP2SETPRIORITY { DWORD dwDDSurface; DWORD dwPriority; -} D3DHAL_DP2SETPRIORITY, *LPD3DHAL_DP2SETPRIORITY; +} D3DHAL_DP2SETPRIORITY,*LPD3DHAL_DP2SETPRIORITY; typedef struct _D3DHAL_DP2SETRENDERTARGET { DWORD hRenderTarget; DWORD hZBuffer; -} D3DHAL_DP2SETRENDERTARGET, *LPD3DHAL_DP2SETRENDERTARGET; +} D3DHAL_DP2SETRENDERTARGET,*LPD3DHAL_DP2SETRENDERTARGET; typedef struct _D3DHAL_DP2CLEAR { - DWORD dwFlags; - DWORD dwFillColor; - D3DVALUE dvFillDepth; - DWORD dwFillStencil; - RECT Rects[1]; -} D3DHAL_DP2CLEAR, *LPD3DHAL_DP2CLEAR; + DWORD dwFlags; + DWORD dwFillColor; + D3DVALUE dvFillDepth; + DWORD dwFillStencil; + RECT Rects[1]; +} D3DHAL_DP2CLEAR,*LPD3DHAL_DP2CLEAR; typedef struct _D3DHAL_DP2SETTEXLOD { DWORD dwDDSurface; DWORD dwLOD; -} D3DHAL_DP2SETTEXLOD, *LPD3DHAL_DP2SETTEXLOD; - -#if (DIRECT3D_VERSION >= 0x0900) - -#define DX9_DDI_VERSION 4 - -#ifndef D3DVTXPCAPS_NO_VSDT_UBYTE4 -#define D3DVTXPCAPS_NO_VSDT_UBYTE4 0x00000080 -#endif - -#ifndef D3DPMISCCAPS_LINEPATTERNREP -#define D3DPMISCCAPS_LINEPATTERNREP 0x00000004 -#endif - -#define D3DDEVCAPS_HWVERTEXBUFFER 0x02000000 -#define D3DDEVCAPS_HWINDEXBUFFER 0x04000000 -#define D3DDEVCAPS_SUBVOLUMELOCK 0x08000000 - -#ifndef D3DPMISCCAPS_FOGINFVF -#define D3DPMISCCAPS_FOGINFVF 0x00002000 -#endif - -#ifndef D3DFVF_FOG -#define D3DFVF_FOG 0x00002000 -#endif - -typedef struct _DD_GETDRIVERINFO2DATA { - DWORD dwReserved; - DWORD dwMagic; - DWORD dwType; - DWORD dwExpectedSize; -} DD_GETDRIVERINFO2DATA; - -/** - * A driver must check DD_GETDRIVERINFO2DATA.dwHeight for - * D3DGDI2_MAGIC to see if the passed GUID is GUID_GetDriverInfo2 - * or a GUID_DDStereoMode. - */ -#define GUID_GetDriverInfo2 GUID_DDStereoMode - -/** - * Magic number used in DD_GETDRIVERINFO2DATA.dwHeight when - * GUID_GetDriverInfo2/GUID_DDStereoMode is specified in a - * GetDriverInfo call. - */ -#define D3DGDI2_MAGIC 0xFFFFFFFF - -#define D3DGDI2_TYPE_GETD3DCAPS8 0x00000001 -#define D3DGDI2_TYPE_GETFORMATCOUNT 0x00000002 -#define D3DGDI2_TYPE_GETFORMAT 0x00000003 -#define D3DGDI2_TYPE_DXVERSION 0x00000004 /* Make driver aware of currently used DirectX version */ -#define D3DGDI2_TYPE_GETD3DCAPS9 0x00000010 -#define D3DGDI2_TYPE_GETEXTENDEDMODECOUNT 0x00000011 -#define D3DGDI2_TYPE_GETEXTENDEDMODE 0x00000012 -#define D3DGDI2_TYPE_GETADAPTERGROUP 0x00000013 -#define D3DGDI2_TYPE_GETMULTISAMPLEQUALITYLEVELS 0x00000016 -#define D3DGDI2_TYPE_DEFERRED_AGP_AWARE 0x00000018 -#define D3DGDI2_TYPE_FREE_DEFERRED_AGP 0x00000019 -#define D3DGDI2_TYPE_DEFER_AGP_FREES 0x00000020 -#define D3DGDI2_TYPE_GETD3DQUERYCOUNT 0x00000021 -#define D3DGDI2_TYPE_GETD3DQUERY 0x00000022 -#define D3DGDI2_TYPE_GETDDIVERSION 0x00000023 /* Returns DX9_DDI_VERSION, used to check which DDK version the driver is compiled against */ - -typedef struct _D3DCAPS8 { - D3DDEVTYPE DeviceType; - UINT AdapterOrdinal; - DWORD Caps; - DWORD Caps2; - DWORD Caps3; - DWORD PresentationIntervals; - DWORD CursorCaps; - DWORD DevCaps; - DWORD PrimitiveMiscCaps; - DWORD RasterCaps; - DWORD ZCmpCaps; - DWORD SrcBlendCaps; - DWORD DestBlendCaps; - DWORD AlphaCmpCaps; - DWORD ShadeCaps; - DWORD TextureCaps; - DWORD TextureFilterCaps; - DWORD CubeTextureFilterCaps; - DWORD VolumeTextureFilterCaps; - DWORD TextureAddressCaps; - DWORD VolumeTextureAddressCaps; - DWORD LineCaps; - DWORD MaxTextureWidth; - DWORD MaxTextureHeight; - DWORD MaxVolumeExtent; - DWORD MaxTextureRepeat; - DWORD MaxTextureAspectRatio; - DWORD MaxAnisotropy; - float MaxVertexW; - float GuardBandLeft; - float GuardBandTop; - float GuardBandRight; - float GuardBandBottom; - float ExtentsAdjust; - DWORD StencilCaps; - DWORD FVFCaps; - DWORD TextureOpCaps; - DWORD MaxTextureBlendStages; - DWORD MaxSimultaneousTextures; - DWORD VertexProcessingCaps; - DWORD MaxActiveLights; - DWORD MaxUserClipPlanes; - DWORD MaxVertexBlendMatrices; - DWORD MaxVertexBlendMatrixIndex; - float MaxPointSize; - DWORD MaxPrimitiveCount; - DWORD MaxVertexIndex; - DWORD MaxStreams; - DWORD MaxStreamStride; - DWORD VertexShaderVersion; - DWORD MaxVertexShaderConst; - DWORD PixelShaderVersion; - float MaxPixelShaderValue; -} D3DCAPS8; - -typedef struct _DD_GETFORMATCOUNTDATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwFormatCount; - DWORD dwReserved; -} DD_GETFORMATCOUNTDATA; - -typedef struct _DD_GETFORMATDATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwFormatIndex; - DDPIXELFORMAT format; -} DD_GETFORMATDATA; - -typedef struct _DD_DXVERSION { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwDXVersion; - DWORD dwReserved; -} DD_DXVERSION; - -typedef struct _DD_DEFERRED_AGP_AWARE_DATA { - DD_GETDRIVERINFO2DATA gdi2; -} DD_DEFERRED_AGP_AWARE_DATA; - -typedef struct _DD_FREE_DEFERRED_AGP_DATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwProcessId; -} DD_FREE_DEFERRED_AGP_DATA; - -typedef struct _DD_GETEXTENDEDMODECOUNTDATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwModeCount; - DWORD dwReserved; -} DD_GETEXTENDEDMODECOUNTDATA; - -typedef struct _DD_GETEXTENDEDMODEDATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwModeIndex; - D3DDISPLAYMODE mode; -} DD_GETEXTENDEDMODEDATA; - -typedef struct _DD_GETADAPTERGROUPDATA { - DD_GETDRIVERINFO2DATA gdi2; - ULONG_PTR ulUniqueAdapterGroupId; - DWORD dwReserved1; - DWORD dwReserved2; -} DD_GETADAPTERGROUPDATA; - -typedef struct _DD_MULTISAMPLEQUALITYLEVELSDATA { - DD_GETDRIVERINFO2DATA gdi2; - D3DFORMAT Format; - WINBOOL bFlip : 1; - D3DMULTISAMPLE_TYPE MSType : 31; - DWORD QualityLevels; -} DD_MULTISAMPLEQUALITYLEVELSDATA; - -typedef struct _DD_GETD3DQUERYCOUNTDATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwNumQueries; -} DD_GETD3DQUERYCOUNTDATA; - -typedef struct _DD_GETD3DQUERYDATA { - DD_GETDRIVERINFO2DATA gdi2; - __GNU_EXTENSION union { - DWORD dwQueryIndex; - D3DQUERYTYPE QueryType; - }; -} DD_GETD3DQUERYDATA; - -typedef struct _DD_GETDDIVERSIONDATA { - DD_GETDRIVERINFO2DATA gdi2; - DWORD dwDXVersion; - DWORD dwDDIVersion; -} DD_GETDDIVERSIONDATA; - -#endif /* (DIRECT3D_VERSION >= 0x0900) */ +} D3DHAL_DP2SETTEXLOD,*LPD3DHAL_DP2SETTEXLOD; #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* _D3DHAL_H_ */ +#endif /* __WINE_D3DHAL_H */ diff --git a/sdk/include/psdk/CMakeLists.txt b/sdk/include/psdk/CMakeLists.txt index 814f0e19214..9a9002e279f 100644 --- a/sdk/include/psdk/CMakeLists.txt +++ b/sdk/include/psdk/CMakeLists.txt @@ -149,13 +149,43 @@ list(APPEND SOURCE ctfutb.idl xmllite.idl) +list(APPEND D3D + d3dcommon.idl + dcommon.idl + d3d10.idl + dxgi.idl + dxgiformat.idl + dxgicommon.idl + dxgitype.idl + dxgi1_2.idl + dxgi1_3.idl + dxgi1_4.idl + dxgi1_5.idl + dxgi1_6.idl + dxva2api.idl + d3d10sdklayers.idl + d3d10_1.idl + d3d11_1.idl + d3d11_2.idl + d3d11_3.idl + d3d11_4.idl + d3d11.idl + d3d11sdklayers.idl + d3d12.idl + d3dx10core.idl + d3dx11core.idl + dwrite.idl + dwrite_1.idl + dwrite_2.idl + dwrite_3.idl) + +add_idl_headers(d3d_idl_headers ${D3D}) + add_idl_headers(psdk ${SOURCE}) add_dependencies(psdk xdk) add_typelib(stdole2.idl) add_custom_target(stdole2 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/stdole2.tlb) -add_idl_headers(d3d_idl_headers d3dcommon.idl) - add_iid_library(adsiid iads.idl transact.idl) add_iid_library(wuguid wuapi.idl) add_iid_library(xml_uuids msxml2.idl) diff --git a/sdk/include/psdk/d3d10.idl b/sdk/include/psdk/d3d10.idl index 4b058ac6b0b..f125956fddc 100644 --- a/sdk/include/psdk/d3d10.idl +++ b/sdk/include/psdk/d3d10.idl @@ -242,7 +242,7 @@ const unsigned int D3D_SPEC_DATE_YEAR cpp_quote("#endif") const unsigned int D3D10_APPEND_ALIGNED_ELEMENT = 0xffffffff; -const unsigned int _FACD3D10 = 0x87; +const unsigned int _FACD3D10 = 0x879; const unsigned int _FACD3D10DEBUG = _FACD3D10 + 1; const unsigned int D3D10_FILTER_TYPE_MASK = 0x3; const unsigned int D3D10_SDK_VERSION = 29; @@ -893,6 +893,35 @@ typedef enum D3D10_COLOR_WRITE_ENABLE { D3D10_COLOR_WRITE_ENABLE_BLUE | D3D10_COLOR_WRITE_ENABLE_ALPHA) } D3D10_COLOR_WRITE_ENABLE; +typedef enum D3D10_FORMAT_SUPPORT +{ + D3D10_FORMAT_SUPPORT_BUFFER = 0x00000001, + D3D10_FORMAT_SUPPORT_IA_VERTEX_BUFFER = 0x00000002, + D3D10_FORMAT_SUPPORT_IA_INDEX_BUFFER = 0x00000004, + D3D10_FORMAT_SUPPORT_SO_BUFFER = 0x00000008, + D3D10_FORMAT_SUPPORT_TEXTURE1D = 0x00000010, + D3D10_FORMAT_SUPPORT_TEXTURE2D = 0x00000020, + D3D10_FORMAT_SUPPORT_TEXTURE3D = 0x00000040, + D3D10_FORMAT_SUPPORT_TEXTURECUBE = 0x00000080, + D3D10_FORMAT_SUPPORT_SHADER_LOAD = 0x00000100, + D3D10_FORMAT_SUPPORT_SHADER_SAMPLE = 0x00000200, + D3D10_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON = 0x00000400, + D3D10_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT = 0x00000800, + D3D10_FORMAT_SUPPORT_MIP = 0x00001000, + D3D10_FORMAT_SUPPORT_MIP_AUTOGEN = 0x00002000, + D3D10_FORMAT_SUPPORT_RENDER_TARGET = 0x00004000, + D3D10_FORMAT_SUPPORT_BLENDABLE = 0x00008000, + D3D10_FORMAT_SUPPORT_DEPTH_STENCIL = 0x00010000, + D3D10_FORMAT_SUPPORT_CPU_LOCKABLE = 0x00020000, + D3D10_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE = 0x00040000, + D3D10_FORMAT_SUPPORT_DISPLAY = 0x00080000, + D3D10_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT = 0x00100000, + D3D10_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET = 0x00200000, + D3D10_FORMAT_SUPPORT_MULTISAMPLE_LOAD = 0x00400000, + D3D10_FORMAT_SUPPORT_SHADER_GATHER = 0x00800000, + D3D10_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x01000000, +} D3D10_FORMAT_SUPPORT; + typedef enum D3D10_TEXTURECUBE_FACE { D3D10_TEXTURECUBE_FACE_POSITIVE_X, D3D10_TEXTURECUBE_FACE_NEGATIVE_X, @@ -1595,7 +1624,7 @@ interface ID3D10Multithread : IUnknown } cpp_quote("#ifndef D3D10_IGNORE_SDK_LAYERS") -cpp_quote("/* FIXME: # include */") +cpp_quote("#include \"d3d10sdklayers.h\"") cpp_quote("#endif") cpp_quote("#include \"d3d10misc.h\"") cpp_quote("#include \"d3d10shader.h\"") diff --git a/sdk/include/psdk/d3d10_1.idl b/sdk/include/psdk/d3d10_1.idl new file mode 100644 index 00000000000..a37ff9ea3b2 --- /dev/null +++ b/sdk/include/psdk/d3d10_1.idl @@ -0,0 +1,157 @@ +/* + * Copyright 2010 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; + +cpp_quote("#ifndef _D3D10_1_CONSTANTS") +cpp_quote("#define _D3D10_1_CONSTANTS") +const UINT D3D10_1_DEFAULT_SAMPLE_MASK = 0xffffffff; +const UINT D3D10_1_GS_INPUT_REGISTER_COUNT = 32; +const UINT D3D10_1_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; +const UINT D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS = 128; +const UINT D3D10_1_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT = 32; +const UINT D3D10_1_PS_OUTPUT_MASK_REGISTER_COMPONENTS = 1; +const UINT D3D10_1_PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT = 32; +const UINT D3D10_1_PS_OUTPUT_MASK_REGISTER_COUNT = 1; +const UINT D3D10_1_SHADER_MAJOR_VERSION = 4; +const UINT D3D10_1_SHADER_MINOR_VERSION = 1; +const UINT D3D10_1_SO_BUFFER_MAX_STRIDE_IN_BYTES = 2048; +const UINT D3D10_1_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES = 256; +const UINT D3D10_1_SO_BUFFER_SLOT_COUNT = 4; +const UINT D3D10_1_SO_MULTIPLE_BUFFER_ELEMENTS_PER_BUFFER = 1; +const UINT D3D10_1_SO_SINGLE_BUFFER_COMPONENT_LIMIT = 64; +const UINT D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT = 32; +const UINT D3D10_1_SUBPIXEL_FRACTIONAL_BIT_COUNT = 8; +const UINT D3D10_1_VS_INPUT_REGISTER_COUNT = 32; +const UINT D3D10_1_VS_OUTPUT_REGISTER_COUNT = 32; +cpp_quote("#endif") + +cpp_quote("#define D3D10_1_FLOAT16_FUSED_TOLERANCE_IN_ULP (0.6)") +cpp_quote("#define D3D10_1_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP (0.6f)") + +import "d3d10.idl"; +cpp_quote("#include ") + + +typedef enum D3D10_FEATURE_LEVEL1 +{ + D3D10_FEATURE_LEVEL_10_0 = 0xa000, + D3D10_FEATURE_LEVEL_10_1 = 0xa100, + D3D10_FEATURE_LEVEL_9_1 = 0x9100, + D3D10_FEATURE_LEVEL_9_2 = 0x9200, + D3D10_FEATURE_LEVEL_9_3 = 0x9300 +} D3D10_FEATURE_LEVEL1; + +typedef struct D3D10_RENDER_TARGET_BLEND_DESC1 +{ + BOOL BlendEnable; + D3D10_BLEND SrcBlend; + D3D10_BLEND DestBlend; + D3D10_BLEND_OP BlendOp; + D3D10_BLEND SrcBlendAlpha; + D3D10_BLEND DestBlendAlpha; + D3D10_BLEND_OP BlendOpAlpha; + UINT8 RenderTargetWriteMask; +} D3D10_RENDER_TARGET_BLEND_DESC1; + +typedef struct D3D10_BLEND_DESC1 +{ + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D10_RENDER_TARGET_BLEND_DESC1 RenderTarget[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT]; +} D3D10_BLEND_DESC1; + +[ + uuid(edad8d99-8a35-4d6d-8566-2ea276cde161), + object, + local, + pointer_default(unique) +] +interface ID3D10BlendState1 : ID3D10BlendState +{ + void GetDesc1([out] D3D10_BLEND_DESC1 *pDesc); +} + +typedef struct D3D10_TEXCUBE_ARRAY_SRV1 +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT First2DArrayFace; + UINT NumCubes; +} D3D10_TEXCUBE_ARRAY_SRV1; + +typedef D3D_SRV_DIMENSION D3D10_SRV_DIMENSION1; + +typedef struct D3D10_SHADER_RESOURCE_VIEW_DESC1 +{ + DXGI_FORMAT Format; + D3D10_SRV_DIMENSION1 ViewDimension; + union { + D3D10_BUFFER_SRV Buffer; + D3D10_TEX1D_SRV Texture1D; + D3D10_TEX1D_ARRAY_SRV Texture1DArray; + D3D10_TEX2D_SRV Texture2D; + D3D10_TEX2D_ARRAY_SRV Texture2DArray; + D3D10_TEX2DMS_SRV Texture2DMS; + D3D10_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D10_TEX3D_SRV Texture3D; + D3D10_TEXCUBE_SRV TextureCube; + D3D10_TEXCUBE_ARRAY_SRV1 TextureCubeArray; + }; +} D3D10_SHADER_RESOURCE_VIEW_DESC1; + +[ + uuid(9b7e4c87-342c-4106-a19f-4f2704f689f0), + object, + local, + pointer_default(unique) +] +interface ID3D10ShaderResourceView1 : ID3D10ShaderResourceView +{ + void GetDesc1([out] D3D10_SHADER_RESOURCE_VIEW_DESC1 *pDesc); +} + +[ + uuid(9b7e4c8f-342c-4106-a19f-4f2704f689f0), + object, + local, + pointer_default(unique) +] +interface ID3D10Device1 : ID3D10Device +{ + HRESULT CreateShaderResourceView1( + [in] ID3D10Resource *pResource, + [in, out] const D3D10_SHADER_RESOURCE_VIEW_DESC1 *pDesc, + [out] ID3D10ShaderResourceView1 **ppSRView); + + HRESULT CreateBlendState1( + [in] const D3D10_BLEND_DESC1 *pBlendStateDesc, + [out] ID3D10BlendState1 **ppBlendState); + + D3D10_FEATURE_LEVEL1 GetFeatureLevel(); +} + +const UINT D3D10_1_SDK_VERSION = 0x20; + +cpp_quote("HRESULT WINAPI D3D10CreateDevice1(IDXGIAdapter*,D3D10_DRIVER_TYPE,") +cpp_quote(" HMODULE,UINT,D3D10_FEATURE_LEVEL1,UINT,ID3D10Device1**);") + +[local] HRESULT __stdcall D3D10CreateDeviceAndSwapChain1(IDXGIAdapter *adapter, enum D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, D3D10_FEATURE_LEVEL1 feature_level, UINT sdk_version, + DXGI_SWAP_CHAIN_DESC *swapchain_desc, IDXGISwapChain **swapchain, ID3D10Device1 **device); diff --git a/sdk/include/psdk/d3d10_1shader.h b/sdk/include/psdk/d3d10_1shader.h new file mode 100644 index 00000000000..06dded7e0e8 --- /dev/null +++ b/sdk/include/psdk/d3d10_1shader.h @@ -0,0 +1,52 @@ +/* + * Copyright 2010 Rico Schüller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __D3D10_1SHADER_H__ +#define __D3D10_1SHADER_H__ + +#include "d3d10shader.h" + +DEFINE_GUID(IID_ID3D10ShaderReflection1, 0xc3457783, 0xa846, 0x47ce, 0x95, 0x20, 0xce, 0xa6, 0xf6, 0x6e, 0x74, 0x47); + +#define INTERFACE ID3D10ShaderReflection1 +DECLARE_INTERFACE_(ID3D10ShaderReflection1, IUnknown) +{ + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **out) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + /* ID3D10ShaderReflection1 methods */ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_DESC *desc) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionConstantBuffer *, GetConstantBufferByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionConstantBuffer *, GetConstantBufferByName)(THIS_ const char *name) PURE; + STDMETHOD(GetResourceBindingDesc)(THIS_ UINT index, D3D10_SHADER_INPUT_BIND_DESC *desc) PURE; + STDMETHOD(GetInputParameterDesc)(THIS_ UINT index, D3D10_SIGNATURE_PARAMETER_DESC *desc) PURE; + STDMETHOD(GetOutputParameterDesc)(THIS_ UINT index, D3D10_SIGNATURE_PARAMETER_DESC *desc) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionVariable *, GetVariableByName)(THIS_ const char *name) PURE; + STDMETHOD(GetResourceBindingDescByName)(THIS_ const char *name, D3D10_SHADER_INPUT_BIND_DESC *desc) PURE; + STDMETHOD(GetMovInstructionCount)(THIS_ UINT *count) PURE; + STDMETHOD(GetMovcInstructionCount)(THIS_ UINT *count) PURE; + STDMETHOD(GetConversionInstructionCount)(THIS_ UINT *count) PURE; + STDMETHOD(GetBitwiseInstructionCount)(THIS_ UINT *count) PURE; + STDMETHOD(GetGSInputPrimitive)(THIS_ D3D10_PRIMITIVE *prim) PURE; + STDMETHOD(IsLevel9Shader)(THIS_ BOOL *level9shader) PURE; + STDMETHOD(IsSampleFrequencyShader)(THIS_ BOOL *samplefrequency) PURE; +}; +#undef INTERFACE + +#endif diff --git a/sdk/include/psdk/d3d10effect.h b/sdk/include/psdk/d3d10effect.h index 14948941bd0..b4a33daca48 100644 --- a/sdk/include/psdk/d3d10effect.h +++ b/sdk/include/psdk/d3d10effect.h @@ -832,6 +832,8 @@ HRESULT WINAPI D3D10CompileEffectFromMemory(void *data, SIZE_T data_size, const ID3D10Blob **effect, ID3D10Blob **errors); HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT flags, ID3D10Device *device, ID3D10EffectPool *effect_pool, ID3D10Effect **effect); +HRESULT WINAPI D3D10CreateEffectPoolFromMemory(void *data, SIZE_T data_size, UINT fx_flags, + ID3D10Device *device, ID3D10EffectPool **effect_pool); HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *device, D3D10_STATE_BLOCK_MASK *mask, ID3D10StateBlock **stateblock); diff --git a/sdk/include/psdk/d3d10sdklayers.idl b/sdk/include/psdk/d3d10sdklayers.idl new file mode 100644 index 00000000000..c6606d2fd6f --- /dev/null +++ b/sdk/include/psdk/d3d10sdklayers.idl @@ -0,0 +1,676 @@ +/* + * Copyright 2016 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi.idl"; + +cpp_quote("#ifdef WINE_NO_UNICODE_MACROS") +cpp_quote("#undef GetMessage") +cpp_quote("#endif") + +typedef enum D3D10_MESSAGE_CATEGORY +{ + D3D10_MESSAGE_CATEGORY_APPLICATION_DEFINED, + D3D10_MESSAGE_CATEGORY_MISCELLANEOUS, + D3D10_MESSAGE_CATEGORY_INITIALIZATION, + D3D10_MESSAGE_CATEGORY_CLEANUP, + D3D10_MESSAGE_CATEGORY_COMPILATION, + D3D10_MESSAGE_CATEGORY_STATE_CREATION, + D3D10_MESSAGE_CATEGORY_STATE_SETTING, + D3D10_MESSAGE_CATEGORY_STATE_GETTING, + D3D10_MESSAGE_CATEGORY_RESOURCE_MANIPULATION, + D3D10_MESSAGE_CATEGORY_EXECUTION, + D3D10_MESSAGE_CATEGORY_SHADER, +} D3D10_MESSAGE_CATEGORY; + +typedef enum D3D10_MESSAGE_SEVERITY +{ + D3D10_MESSAGE_SEVERITY_CORRUPTION, + D3D10_MESSAGE_SEVERITY_ERROR, + D3D10_MESSAGE_SEVERITY_WARNING, + D3D10_MESSAGE_SEVERITY_INFO, + D3D10_MESSAGE_SEVERITY_MESSAGE, +} D3D10_MESSAGE_SEVERITY; + +typedef enum D3D10_MESSAGE_ID +{ + D3D10_MESSAGE_ID_UNKNOWN = 0, + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_HAZARD, + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_HAZARD, + D3D10_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_HAZARD, + D3D10_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_HAZARD, + D3D10_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_HAZARD, + D3D10_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_HAZARD, + D3D10_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD, + D3D10_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_HAZARD, + D3D10_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD, + D3D10_MESSAGE_ID_DEVICE_SOSETTARGETS_HAZARD, + D3D10_MESSAGE_ID_STRING_FROM_APPLICATION, + D3D10_MESSAGE_ID_CORRUPTED_THIS, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER1, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER2, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER3, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER4, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER5, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER6, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER7, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER8, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER9, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER10, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER11, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER12, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER13, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER14, + D3D10_MESSAGE_ID_CORRUPTED_PARAMETER15, + D3D10_MESSAGE_ID_CORRUPTED_MULTITHREADING, + D3D10_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY, + D3D10_MESSAGE_ID_IASETINPUTLAYOUT_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_IASETINDEXBUFFER_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_VSSETSHADER_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_VSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_VSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_VSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_GSSETSHADER_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_GSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_GSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_GSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_SOSETTARGETS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_PSSETSHADER_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_PSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_PSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_PSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_RSSETSTATE_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_OMSETBLENDSTATE_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_OMSETDEPTHSTENCILSTATE_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_SETPREDICATION_UNBINDDELETINGOBJECT, + D3D10_MESSAGE_ID_GETPRIVATEDATA_MOREDATA, + D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA, + D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN, + D3D10_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS, + D3D10_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS, + D3D10_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY, + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDSAMPLES, + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDUSAGE, + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDBINDFLAGS, + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDMISCFLAGS, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDBINDFLAGS, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDINITIALDATA, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDMIPLEVELS, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDMISCFLAGS, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATEBUFFER_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATEBUFFER_NULLDESC, + D3D10_MESSAGE_ID_CREATEBUFFER_INVALIDCONSTANTBUFFERBINDINGS, + D3D10_MESSAGE_ID_CREATEBUFFER_LARGEALLOCATION, + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNSUPPORTEDFORMAT, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDSAMPLES, + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDUSAGE, + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDBINDFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDMISCFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDBINDFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDINITIALDATA, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDMIPLEVELS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDMISCFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE1D_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATETEXTURE1D_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATETEXTURE1D_NULLDESC, + D3D10_MESSAGE_ID_CREATETEXTURE1D_LARGEALLOCATION, + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNSUPPORTEDFORMAT, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDSAMPLES, + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDUSAGE, + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDBINDFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDMISCFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDBINDFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDINITIALDATA, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDMIPLEVELS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDMISCFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE2D_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATETEXTURE2D_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATETEXTURE2D_NULLDESC, + D3D10_MESSAGE_ID_CREATETEXTURE2D_LARGEALLOCATION, + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNSUPPORTEDFORMAT, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDSAMPLES, + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDUSAGE, + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDBINDFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDMISCFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDCPUACCESSFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDBINDFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDINITIALDATA, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDMIPLEVELS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDMISCFLAGS, + D3D10_MESSAGE_ID_CREATETEXTURE3D_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATETEXTURE3D_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATETEXTURE3D_NULLDESC, + D3D10_MESSAGE_ID_CREATETEXTURE3D_LARGEALLOCATION, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_NULLDESC, + D3D10_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY, + D3D10_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE, + D3D10_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE, + D3D10_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY, + D3D10_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE, + D3D10_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_TOOMANYOBJECTS, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC, + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDQUERY, + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDMISCFLAGS, + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_UNEXPECTEDMISCFLAG, + D3D10_MESSAGE_ID_CREATEQUERYORPREDICATE_NULLDESC, + D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED, + D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED, + D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_INVALIDBUFFER, + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_OFFSET_TOO_LARGE, + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_IASETINDEXBUFFER_INVALIDBUFFER, + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_FORMAT_INVALID, + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_TOO_LARGE, + D3D10_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_UNALIGNED, + D3D10_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D10_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D10_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_VSSETSAMPLERS_SAMPLERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D10_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D10_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_GSSETSAMPLERS_SAMPLERS_EMPTY, + D3D10_MESSAGE_ID_SOSETTARGETS_INVALIDBUFFER, + D3D10_MESSAGE_ID_DEVICE_SOSETTARGETS_OFFSET_UNALIGNED, + D3D10_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D10_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D10_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_PSSETSAMPLERS_SAMPLERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT, + D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR, + D3D10_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH, + D3D10_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH, + D3D10_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID, + D3D10_MESSAGE_ID_DEVICE_IAGETVERTEXBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_VSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_VSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_VSGETSAMPLERS_SAMPLERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_GSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_GSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_GSGETSAMPLERS_SAMPLERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_SOGETTARGETS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_PSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_PSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_PSGETSAMPLERS_SAMPLERS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_RSGETVIEWPORTS_VIEWPORTS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_RSGETSCISSORRECTS_RECTS_EMPTY, + D3D10_MESSAGE_ID_DEVICE_GENERATEMIPS_RESOURCE_INVALID, + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSUBRESOURCE, + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESUBRESOURCE, + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCEBOX, + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCE, + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSTATE, + D3D10_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESTATE, + D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE, + D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE, + D3D10_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE, + D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE, + D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX, + D3D10_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE, + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID, + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID, + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID, + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID, + D3D10_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID, + D3D10_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE, + D3D10_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS, + D3D10_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED, + D3D10_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN, + D3D10_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED, + D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE, + D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE, + D3D10_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS, + D3D10_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED, + D3D10_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN, + D3D10_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE, + D3D10_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED, + D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE, + D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE, + D3D10_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS, + D3D10_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED, + D3D10_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN, + D3D10_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE, + D3D10_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED, + D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE, + D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE, + D3D10_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS, + D3D10_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED, + D3D10_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN, + D3D10_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE, + D3D10_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED, + D3D10_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED, + D3D10_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED, + D3D10_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS, + D3D10_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN, + D3D10_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE, + D3D10_MESSAGE_ID_REF_THREADING_MODE, + D3D10_MESSAGE_ID_REF_UMDRIVER_EXCEPTION, + D3D10_MESSAGE_ID_REF_KMDRIVER_EXCEPTION, + D3D10_MESSAGE_ID_REF_HARDWARE_EXCEPTION, + D3D10_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE, + D3D10_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER, + D3D10_MESSAGE_ID_REF_OUT_OF_MEMORY, + D3D10_MESSAGE_ID_REF_INFO, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW, + D3D10_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW, + D3D10_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW, + D3D10_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW, + D3D10_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW, + D3D10_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND, + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX, + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE, + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK, + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE, + D3D10_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_INPUTLAYOUT_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL, + D3D10_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_SHADERRESOURCEVIEW_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_VIEW_DIMENSION_MISMATCH, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL, + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_FORMAT_INVALID, + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL, + D3D10_MESSAGE_ID_DEVICE_DRAW_GS_INPUT_PRIMITIVE_MISMATCH, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH, + D3D10_MESSAGE_ID_DEVICE_DRAW_POSITION_NOT_PRESENT, + D3D10_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_NOT_SET, + D3D10_MESSAGE_ID_DEVICE_DRAW_BOUND_RESOURCE_MAPPED, + D3D10_MESSAGE_ID_DEVICE_DRAW_INVALID_PRIMITIVETOPOLOGY, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_OFFSET_UNALIGNED, + D3D10_MESSAGE_ID_DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED, + D3D10_MESSAGE_ID_DEVICE_DRAW_INDEX_OFFSET_UNALIGNED, + D3D10_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED, + D3D10_MESSAGE_ID_DEVICE_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE, + D3D10_MESSAGE_ID_DEVICE_DRAW_SO_STRIDE_LARGER_THAN_BUFFER, + D3D10_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING, + D3D10_MESSAGE_ID_DEVICE_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0, + D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT, + D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT, + D3D10_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT, + D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN, + D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN, + D3D10_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC, + D3D10_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC, + D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH, + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW, + D3D10_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS, + D3D10_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH, + D3D10_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY, + D3D10_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY, + D3D10_MESSAGE_ID_CREATEQUERY_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATEPREDICATE_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATECOUNTER_OUTOFRANGE_COUNTER, + D3D10_MESSAGE_ID_CREATECOUNTER_SIMULTANEOUS_ACTIVE_COUNTERS_EXHAUSTED, + D3D10_MESSAGE_ID_CREATECOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER, + D3D10_MESSAGE_ID_CREATECOUNTER_OUTOFMEMORY_RETURN, + D3D10_MESSAGE_ID_CREATECOUNTER_NONEXCLUSIVE_RETURN, + D3D10_MESSAGE_ID_CREATECOUNTER_NULLDESC, + D3D10_MESSAGE_ID_CHECKCOUNTER_OUTOFRANGE_COUNTER, + D3D10_MESSAGE_ID_CHECKCOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER, + D3D10_MESSAGE_ID_SETPREDICATION_INVALID_PREDICATE_STATE, + D3D10_MESSAGE_ID_QUERY_BEGIN_UNSUPPORTED, + D3D10_MESSAGE_ID_PREDICATE_BEGIN_DURING_PREDICATION, + D3D10_MESSAGE_ID_QUERY_BEGIN_DUPLICATE, + D3D10_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS, + D3D10_MESSAGE_ID_PREDICATE_END_DURING_PREDICATION, + D3D10_MESSAGE_ID_QUERY_END_ABANDONING_PREVIOUS_RESULTS, + D3D10_MESSAGE_ID_QUERY_END_WITHOUT_BEGIN, + D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_DATASIZE, + D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_FLAGS, + D3D10_MESSAGE_ID_QUERY_GETDATA_INVALID_CALL, + D3D10_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED, + D3D10_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN, + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE, + D3D10_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT, + D3D10_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH, + D3D10_MESSAGE_ID_LIVE_OBJECT_SUMMARY, + D3D10_MESSAGE_ID_LIVE_BUFFER, + D3D10_MESSAGE_ID_LIVE_TEXTURE1D, + D3D10_MESSAGE_ID_LIVE_TEXTURE2D, + D3D10_MESSAGE_ID_LIVE_TEXTURE3D, + D3D10_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW, + D3D10_MESSAGE_ID_LIVE_RENDERTARGETVIEW, + D3D10_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW, + D3D10_MESSAGE_ID_LIVE_VERTEXSHADER, + D3D10_MESSAGE_ID_LIVE_GEOMETRYSHADER, + D3D10_MESSAGE_ID_LIVE_PIXELSHADER, + D3D10_MESSAGE_ID_LIVE_INPUTLAYOUT, + D3D10_MESSAGE_ID_LIVE_SAMPLER, + D3D10_MESSAGE_ID_LIVE_BLENDSTATE, + D3D10_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE, + D3D10_MESSAGE_ID_LIVE_RASTERIZERSTATE, + D3D10_MESSAGE_ID_LIVE_QUERY, + D3D10_MESSAGE_ID_LIVE_PREDICATE, + D3D10_MESSAGE_ID_LIVE_COUNTER, + D3D10_MESSAGE_ID_LIVE_DEVICE, + D3D10_MESSAGE_ID_LIVE_SWAPCHAIN, + D3D10_MESSAGE_ID_D3D10_MESSAGES_END, + + D3D10_MESSAGE_ID_D3D10L9_MESSAGES_START = 0x00100000, + D3D10_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_STENCIL_NO_TWO_SIDED, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_DepthBiasClamp_NOT_SUPPORTED, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NO_COMPARISON_SUPPORT, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_EXCESSIVE_ANISOTROPY, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_OUT_OF_RANGE, + D3D10_MESSAGE_ID_VSSETSAMPLERS_NOT_SUPPORTED, + D3D10_MESSAGE_ID_VSSETSAMPLERS_TOO_MANY_SAMPLERS, + D3D10_MESSAGE_ID_PSSETSAMPLERS_TOO_MANY_SAMPLERS, + D3D10_MESSAGE_ID_CREATERESOURCE_NO_ARRAYS, + D3D10_MESSAGE_ID_CREATERESOURCE_NO_VB_AND_IB_BIND, + D3D10_MESSAGE_ID_CREATERESOURCE_NO_TEXTURE_1D, + D3D10_MESSAGE_ID_CREATERESOURCE_DIMENSION_OUT_OF_RANGE, + D3D10_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_SHADER_RESOURCE, + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_TOO_MANY_RENDER_TARGETS, + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_NO_DIFFERING_BIT_DEPTHS, + D3D10_MESSAGE_ID_IASETVERTEXBUFFERS_BAD_BUFFER_INDEX, + D3D10_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_TOO_MANY_VIEWPORTS, + D3D10_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_ADJACENCY_UNSUPPORTED, + D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_TOO_MANY_SCISSORS, + D3D10_MESSAGE_ID_COPYRESOURCE_ONLY_TEXTURE_2D_WITHIN_GPU_MEMORY, + D3D10_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_3D_READBACK, + D3D10_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_ONLY_READBACK, + D3D10_MESSAGE_ID_CREATEINPUTLAYOUT_UNSUPPORTED_FORMAT, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_ALPHA_TO_COVERAGE, + D3D10_MESSAGE_ID_CREATERASTERIZERSTATE_DepthClipEnable_MUST_BE_TRUE, + D3D10_MESSAGE_ID_DRAWINDEXED_STARTINDEXLOCATION_MUST_BE_POSITIVE, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_MUST_USE_LOWEST_LOD, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_MINLOD_MUST_NOT_BE_FRACTIONAL, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_MAXLOD_MUST_BE_FLT_MAX, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_FIRSTARRAYSLICE_MUST_BE_ZERO, + D3D10_MESSAGE_ID_CREATESHADERRESOURCEVIEW_CUBES_MUST_HAVE_6_SIDES, + D3D10_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_RENDER_TARGET, + D3D10_MESSAGE_ID_CREATERESOURCE_NO_DWORD_INDEX_BUFFER, + D3D10_MESSAGE_ID_CREATERESOURCE_MSAA_PRECLUDES_SHADER_RESOURCE, + D3D10_MESSAGE_ID_CREATERESOURCE_PRESENTATION_PRECLUDES_SHADER_RESOURCE, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_BLEND_ENABLE, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_WRITE_MASKS, + D3D10_MESSAGE_ID_CREATERESOURCE_NO_STREAM_OUT, + D3D10_MESSAGE_ID_CREATERESOURCE_ONLY_VB_IB_FOR_BUFFERS, + D3D10_MESSAGE_ID_CREATERESOURCE_NO_AUTOGEN_FOR_VOLUMES, + D3D10_MESSAGE_ID_CREATERESOURCE_DXGI_FORMAT_R8G8B8A8_CANNOT_BE_SHARED, + D3D10_MESSAGE_ID_VSSHADERRESOURCES_NOT_SUPPORTED, + D3D10_MESSAGE_ID_GEOMETRY_SHADER_NOT_SUPPORTED, + D3D10_MESSAGE_ID_STREAM_OUT_NOT_SUPPORTED, + D3D10_MESSAGE_ID_TEXT_FILTER_NOT_SUPPORTED, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_SEPARATE_ALPHA_BLEND, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_NO_MRT_BLEND, + D3D10_MESSAGE_ID_CREATEBLENDSTATE_OPERATION_NOT_SUPPORTED, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_NO_MIRRORONCE, + D3D10_MESSAGE_ID_DRAWINSTANCED_NOT_SUPPORTED, + D3D10_MESSAGE_ID_DRAWINDEXEDINSTANCED_NOT_SUPPORTED_BELOW_9_3, + D3D10_MESSAGE_ID_DRAWINDEXED_POINTLIST_UNSUPPORTED, + D3D10_MESSAGE_ID_SETBLENDSTATE_SAMPLE_MASK_CANNOT_BE_ZERO, + D3D10_MESSAGE_ID_CREATERESOURCE_DIMENSION_EXCEEDS_FEATURE_LEVEL_DEFINITION, + D3D10_MESSAGE_ID_CREATERESOURCE_ONLY_SINGLE_MIP_LEVEL_DEPTH_STENCIL_SUPPORTED, + D3D10_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR, + D3D10_MESSAGE_ID_SLOT_ZERO_MUST_BE_D3D10_INPUT_PER_VERTEX_DATA, + D3D10_MESSAGE_ID_CREATERESOURCE_NON_POW_2_MIPMAP, + D3D10_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_NOT_SUPPORTED, + D3D10_MESSAGE_ID_OMSETRENDERTARGETS_NO_SRGB_MRT, + D3D10_MESSAGE_ID_COPYRESOURCE_NO_3D_MISMATCHED_UPDATES, + D3D10_MESSAGE_ID_D3D10L9_MESSAGES_END, +} D3D10_MESSAGE_ID; + +typedef struct D3D10_MESSAGE +{ + D3D10_MESSAGE_CATEGORY Category; + D3D10_MESSAGE_SEVERITY Severity; + D3D10_MESSAGE_ID ID; + const char *pDescription; + SIZE_T DescriptionByteLength; +} D3D10_MESSAGE; + +typedef struct D3D10_INFO_QUEUE_FILTER_DESC +{ + UINT NumCategories; + D3D10_MESSAGE_CATEGORY *pCategoryList; + UINT NumSeverities; + D3D10_MESSAGE_SEVERITY *pSeverityList; + UINT NumIDs; + D3D10_MESSAGE_ID *pIDList; +} D3D10_INFO_QUEUE_FILTER_DESC; + +typedef struct D3D10_INFO_QUEUE_FILTER +{ + D3D10_INFO_QUEUE_FILTER_DESC AllowList; + D3D10_INFO_QUEUE_FILTER_DESC DenyList; +} D3D10_INFO_QUEUE_FILTER; + +[ + local, + object, + uuid(1b940b17-2642-4d1f-ab1f-b99bad0c395f), + pointer_default(unique) +] +interface ID3D10InfoQueue : IUnknown +{ + HRESULT SetMessageCountLimit( + [in] UINT64 limit + ); + void ClearStoredMessages(); + HRESULT GetMessage( + [in] UINT64 message_idx, + [out] D3D10_MESSAGE *message, + [in, out] SIZE_T *message_size + ); + UINT64 GetNumMessagesAllowedByStorageFilter(); + UINT64 GetNumMessagesDeniedByStorageFilter(); + UINT64 GetNumStoredMessages(); + UINT64 GetNumStoredMessagesAllowedByRetrievalFilter(); + UINT64 GetNumMessagesDiscardedByMessageCountLimit(); + UINT64 GetMessageCountLimit(); + HRESULT AddStorageFilterEntries( + [in] D3D10_INFO_QUEUE_FILTER *filter + ); + HRESULT GetStorageFilter( + [out] D3D10_INFO_QUEUE_FILTER *filter, + [in, out] SIZE_T *filter_size + ); + void ClearStorageFilter(); + HRESULT PushEmptyStorageFilter(); + HRESULT PushCopyOfStorageFilter(); + HRESULT PushStorageFilter( + [in] D3D10_INFO_QUEUE_FILTER *filter + ); + void PopStorageFilter(); + UINT GetStorageFilterStackSize(); + HRESULT AddRetrievalFilterEntries( + [in] D3D10_INFO_QUEUE_FILTER *filter + ); + HRESULT GetRetrievalFilter( + [out] D3D10_INFO_QUEUE_FILTER *filter, + [in, out] SIZE_T *filterbytelength + ); + void ClearRetrievalFilter(); + HRESULT PushEmptyRetrievalFilter(); + HRESULT PushCopyOfRetrievalFilter(); + HRESULT PushRetrievalFilter( + [in] D3D10_INFO_QUEUE_FILTER *filter + ); + void PopRetrievalFilter(); + UINT GetRetrievalFilterStackSize(); + HRESULT AddMessage( + [in] D3D10_MESSAGE_CATEGORY category, + [in] D3D10_MESSAGE_SEVERITY severity, + [in] D3D10_MESSAGE_ID id, + [in] const char *description + ); + HRESULT AddApplicationMessage( + [in] D3D10_MESSAGE_SEVERITY severity, + [in] const char *description + ); + HRESULT SetBreakOnCategory( + [in] D3D10_MESSAGE_CATEGORY category, + [in] BOOL enable + ); + HRESULT SetBreakOnSeverity( + [in] D3D10_MESSAGE_SEVERITY severity, + [in] BOOL enable + ); + HRESULT SetBreakOnID( + [in] D3D10_MESSAGE_ID id, + [in] BOOL enable + ); + BOOL GetBreakOnCategory( + [in] D3D10_MESSAGE_CATEGORY category + ); + BOOL GetBreakOnSeverity( + [in] D3D10_MESSAGE_SEVERITY severity + ); + BOOL GetBreakOnID( + [in] D3D10_MESSAGE_ID id + ); + void SetMuteDebugOutput( + [in] BOOL mute + ); + BOOL GetMuteDebugOutput(); +} diff --git a/sdk/include/psdk/d3d11.idl b/sdk/include/psdk/d3d11.idl new file mode 100644 index 00000000000..78b4f334676 --- /dev/null +++ b/sdk/include/psdk/d3d11.idl @@ -0,0 +1,3823 @@ +/* + * Copyright 2010 Rico Schüller + * Copyright 2013 Austin English + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi.idl"; +import "d3dcommon.idl"; + +typedef D3D_PRIMITIVE D3D11_PRIMITIVE; +typedef D3D_PRIMITIVE_TOPOLOGY D3D11_PRIMITIVE_TOPOLOGY; +typedef D3D_SRV_DIMENSION D3D11_SRV_DIMENSION; +typedef RECT D3D11_RECT; + +interface ID3D11Device; +interface ID3D11ClassLinkage; +interface ID3D11Resource; +interface ID3D11VideoProcessorInputView; + +cpp_quote("#ifndef _D3D11_CONSTANTS") +cpp_quote("#define _D3D11_CONSTANTS") + +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT = 14; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS = 4; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT = 15; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_PARTIAL_UPDATE_EXTENTS_BYTE_ALIGNMENT = 16; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS = 4; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT = 15; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST = 1; +const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS = 1; +const UINT D3D11_COMMONSHADER_FLOWCONTROL_NESTING_LIMIT = 64; +const UINT D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS = 4; +const UINT D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT = 1; +const UINT D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST = 1; +const UINT D3D11_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS = 1; +const UINT D3D11_COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS = 1; +const UINT D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT = 128; +const UINT D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST = 1; +const UINT D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS = 1; +const UINT D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT = 128; +const UINT D3D11_COMMONSHADER_SAMPLER_REGISTER_COMPONENTS = 1; +const UINT D3D11_COMMONSHADER_SAMPLER_REGISTER_COUNT = 16; +const UINT D3D11_COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST = 1; +const UINT D3D11_COMMONSHADER_SAMPLER_REGISTER_READ_PORTS = 1; +const UINT D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT = 16; +const UINT D3D11_COMMONSHADER_SUBROUTINE_NESTING_LIMIT = 32; +const UINT D3D11_COMMONSHADER_TEMP_REGISTER_COMPONENTS = 4; +const UINT D3D11_COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_COMMONSHADER_TEMP_REGISTER_COUNT = 4096; +const UINT D3D11_COMMONSHADER_TEMP_REGISTER_READS_PER_INST = 3; +const UINT D3D11_COMMONSHADER_TEMP_REGISTER_READ_PORTS = 3; +const UINT D3D11_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX = 10; +const INT D3D11_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN = -10; +const INT D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE = -8; +const UINT D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE = 7; + +const UINT D3D11_CS_4_X_BUCKET00_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 256; +const UINT D3D11_CS_4_X_BUCKET00_MAX_NUM_THREADS_PER_GROUP = 64; +const UINT D3D11_CS_4_X_BUCKET01_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 240; +const UINT D3D11_CS_4_X_BUCKET01_MAX_NUM_THREADS_PER_GROUP = 68; +const UINT D3D11_CS_4_X_BUCKET02_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 224; +const UINT D3D11_CS_4_X_BUCKET02_MAX_NUM_THREADS_PER_GROUP = 72; +const UINT D3D11_CS_4_X_BUCKET03_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 208; +const UINT D3D11_CS_4_X_BUCKET03_MAX_NUM_THREADS_PER_GROUP = 76; +const UINT D3D11_CS_4_X_BUCKET04_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 192; +const UINT D3D11_CS_4_X_BUCKET04_MAX_NUM_THREADS_PER_GROUP = 84; +const UINT D3D11_CS_4_X_BUCKET05_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 176; +const UINT D3D11_CS_4_X_BUCKET05_MAX_NUM_THREADS_PER_GROUP = 92; +const UINT D3D11_CS_4_X_BUCKET06_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 160; +const UINT D3D11_CS_4_X_BUCKET06_MAX_NUM_THREADS_PER_GROUP = 100; +const UINT D3D11_CS_4_X_BUCKET07_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 144; +const UINT D3D11_CS_4_X_BUCKET07_MAX_NUM_THREADS_PER_GROUP = 112; +const UINT D3D11_CS_4_X_BUCKET08_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 128; +const UINT D3D11_CS_4_X_BUCKET08_MAX_NUM_THREADS_PER_GROUP = 128; +const UINT D3D11_CS_4_X_BUCKET09_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 112; +const UINT D3D11_CS_4_X_BUCKET09_MAX_NUM_THREADS_PER_GROUP = 144; +const UINT D3D11_CS_4_X_BUCKET10_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 96; +const UINT D3D11_CS_4_X_BUCKET10_MAX_NUM_THREADS_PER_GROUP = 168; +const UINT D3D11_CS_4_X_BUCKET11_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 80; +const UINT D3D11_CS_4_X_BUCKET11_MAX_NUM_THREADS_PER_GROUP = 204; +const UINT D3D11_CS_4_X_BUCKET12_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 64; +const UINT D3D11_CS_4_X_BUCKET12_MAX_NUM_THREADS_PER_GROUP = 256; +const UINT D3D11_CS_4_X_BUCKET13_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 48; +const UINT D3D11_CS_4_X_BUCKET13_MAX_NUM_THREADS_PER_GROUP = 340; +const UINT D3D11_CS_4_X_BUCKET14_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 32; +const UINT D3D11_CS_4_X_BUCKET14_MAX_NUM_THREADS_PER_GROUP = 512; +const UINT D3D11_CS_4_X_BUCKET15_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 16; +const UINT D3D11_CS_4_X_BUCKET15_MAX_NUM_THREADS_PER_GROUP = 768; +const UINT D3D11_CS_4_X_DISPATCH_MAX_THREAD_GROUPS_IN_Z_DIMENSION = 1; +const UINT D3D11_CS_4_X_RAW_UAV_BYTE_ALIGNMENT = 256; +const UINT D3D11_CS_4_X_THREAD_GROUP_MAX_THREADS_PER_GROUP = 768; +const UINT D3D11_CS_4_X_THREAD_GROUP_MAX_X = 768; +const UINT D3D11_CS_4_X_THREAD_GROUP_MAX_Y = 768; +const UINT D3D11_CS_4_X_UAV_REGISTER_COUNT = 1; +const UINT D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION = 65535; +const UINT D3D11_CS_TGSM_REGISTER_COUNT = 8192; +const UINT D3D11_CS_TGSM_REGISTER_READS_PER_INST = 1; +const UINT D3D11_CS_TGSM_RESOURCE_REGISTER_COMPONENTS = 1; +const UINT D3D11_CS_TGSM_RESOURCE_REGISTER_READ_PORTS = 1; +const UINT D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP = 1024; +const UINT D3D11_CS_THREAD_GROUP_MAX_X = 1024; +const UINT D3D11_CS_THREAD_GROUP_MAX_Y = 1024; +const UINT D3D11_CS_THREAD_GROUP_MAX_Z = 64; +const UINT D3D11_CS_THREAD_GROUP_MIN_X = 1; +const UINT D3D11_CS_THREAD_GROUP_MIN_Y = 1; +const UINT D3D11_CS_THREAD_GROUP_MIN_Z = 1; +const UINT D3D11_CS_THREAD_LOCAL_TEMP_REGISTER_POOL = 16384; + +const UINT D3D11_DEFAULT_DEPTH_BIAS = 0; +cpp_quote("#define D3D11_DEFAULT_DEPTH_BIAS_CLAMP 0.0f") +const UINT D3D11_DEFAULT_MAX_ANISOTROPY = 16; +cpp_quote("#define D3D11_DEFAULT_MIP_LOD_BIAS 0.0f") +const UINT D3D11_DEFAULT_RENDER_TARGET_ARRAY_INDEX = 0; +const UINT D3D11_DEFAULT_SAMPLE_MASK = 0xffffffff; +const UINT D3D11_DEFAULT_SCISSOR_ENDX = 0; +const UINT D3D11_DEFAULT_SCISSOR_ENDY = 0; +const UINT D3D11_DEFAULT_SCISSOR_STARTX = 0; +const UINT D3D11_DEFAULT_SCISSOR_STARTY = 0; +cpp_quote("#define D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS 0.0f") +const UINT D3D11_DEFAULT_STENCIL_READ_MASK = 0xff; +const UINT D3D11_DEFAULT_STENCIL_REFERENCE = 0; +const UINT D3D11_DEFAULT_STENCIL_WRITE_MASK = 0xff; +const UINT D3D11_DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX = 0; +const UINT D3D11_DEFAULT_VIEWPORT_HEIGHT = 0; +cpp_quote("#define D3D11_DEFAULT_VIEWPORT_MAX_DEPTH 0.0f") +cpp_quote("#define D3D11_DEFAULT_VIEWPORT_MIN_DEPTH 0.0f") +const UINT D3D11_DEFAULT_VIEWPORT_TOPLEFTX = 0; +const UINT D3D11_DEFAULT_VIEWPORT_TOPLEFTY = 0; +const UINT D3D11_DEFAULT_VIEWPORT_WIDTH = 0; + +cpp_quote("#define D3D11_FLOAT32_MAX (3.402823466e+38f)") + +const UINT D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; + +const unsigned int D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT = 8; + +const UINT D3D11_MAX_MAXANISOTROPY = 16; +const UINT D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT = 32; +const UINT D3D11_VIEWPORT_BOUNDS_MAX = 32767; +const INT D3D11_VIEWPORT_BOUNDS_MIN = -32768; +const UINT D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX = 15; +const UINT D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; + +const UINT D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL = 0xffffffff; +const UINT D3D11_KEEP_UNORDERED_ACCESS_VIEWS = 0xffffffff; + +const UINT D3D11_SHADER_MAJOR_VERSION = 5; +const UINT D3D11_SHADER_MAX_INSTANCES = 65535; +const UINT D3D11_SHADER_MAX_INTERFACES = 253; +const UINT D3D11_SHADER_MAX_INTERFACE_CALL_SITES = 4096; +const UINT D3D11_SHADER_MAX_TYPES = 65535; +const UINT D3D11_SHADER_MINOR_VERSION = 0; +const UINT D3D11_VS_OUTPUT_REGISTER_COUNT = 32; + +const UINT D3D11_OMAC_SIZE = 16; + +const UINT D3D11_PS_CS_UAV_REGISTER_COMPONENTS = 1; +const UINT D3D11_PS_CS_UAV_REGISTER_COUNT = 8; +const UINT D3D11_PS_CS_UAV_REGISTER_READS_PER_INST = 1; +const UINT D3D11_PS_CS_UAV_REGISTER_READ_PORTS = 1; +const UINT D3D11_PS_FRONTFACING_DEFAULT_VALUE = 0xffffffff; +const UINT D3D11_PS_FRONTFACING_FALSE_VALUE = 0; +const UINT D3D11_PS_FRONTFACING_TRUE_VALUE = 0xffffffff; +const UINT D3D11_PS_INPUT_REGISTER_COMPONENTS = 4; +const UINT D3D11_PS_INPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_PS_INPUT_REGISTER_COUNT = 32; +const UINT D3D11_PS_INPUT_REGISTER_READS_PER_INST = 2; +const UINT D3D11_PS_INPUT_REGISTER_READ_PORTS = 1; +cpp_quote("#define D3D11_PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT (0.0f)") +const UINT D3D11_PS_OUTPUT_DEPTH_REGISTER_COMPONENTS = 1; +const UINT D3D11_PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_PS_OUTPUT_DEPTH_REGISTER_COUNT = 1; +const UINT D3D11_PS_OUTPUT_MASK_REGISTER_COMPONENTS = 1; +const UINT D3D11_PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_PS_OUTPUT_MASK_REGISTER_COUNT = 1; +const UINT D3D11_PS_OUTPUT_REGISTER_COMPONENTS = 4; +const UINT D3D11_PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_PS_OUTPUT_REGISTER_COUNT = 8; +cpp_quote("#define D3D11_PS_PIXEL_CENTER_FRACTIONAL_COMPONENT (0.5f)") + +const UINT D3D11_RAW_UAV_SRV_BYTE_ALIGNMENT = 16; + +const UINT D3D11_REQ_BLEND_OBJECT_COUNT_PER_DEVICE = 4096; +const UINT D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP = 27; +const UINT D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; +const UINT D3D11_REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_DEVICE = 4096; +const UINT D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP = 32; +const UINT D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP = 32; +const UINT D3D11_REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION = 16384; +const UINT D3D11_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT = 1024; +const UINT D3D11_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; +const UINT D3D11_REQ_MAXANISOTROPY = 16; +const UINT D3D11_REQ_MIP_LEVELS = 15; +const UINT D3D11_REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES = 2048; +const UINT D3D11_REQ_RASTERIZER_OBJECT_COUNT_PER_DEVICE = 4096; +const UINT D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH = 16384; +const UINT D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM = 128; +cpp_quote("#define D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_B_TERM (0.25f)") +const UINT D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_C_TERM = 2048; +const UINT D3D11_REQ_RESOURCE_VIEW_COUNT_PER_DEVICE_2_TO_EXP = 20; +const UINT D3D11_REQ_SAMPLER_OBJECT_COUNT_PER_DEVICE = 4096; +const UINT D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION = 2048; +const UINT D3D11_REQ_TEXTURE1D_U_DIMENSION = 16384; +const UINT D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION = 2048; +const UINT D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION = 16384; +const UINT D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION = 2048; +const UINT D3D11_REQ_TEXTURECUBE_DIMENSION = 16384; + +const UINT D3D11_RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL = 0; + +const UINT D3D11_SHIFT_INSTRUCTION_PAD_VALUE = 0; +const UINT D3D11_SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT = 5; + +const UINT D3D11_SO_BUFFER_MAX_STRIDE_IN_BYTES = 2048; +const UINT D3D11_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES = 512; +const UINT D3D11_SO_BUFFER_SLOT_COUNT = 4; +const UINT D3D11_SO_DDI_REGISTER_INDEX_DENOTING_GAP = 0xffffffff; +const UINT D3D11_SO_NO_RASTERIZED_STREAM = 0xffffffff; +const UINT D3D11_SO_OUTPUT_COMPONENT_COUNT = 128; +const UINT D3D11_SO_STREAM_COUNT = 4; + +const UINT D3D11_SPEC_DATE_DAY = 16; +const UINT D3D11_SPEC_DATE_MONTH = 05; +const UINT D3D11_SPEC_DATE_YEAR = 2011; + +cpp_quote("#define D3D11_SPEC_VERSION (1.07)") +cpp_quote("#define D3D11_SRGB_GAMMA (2.2f)") +cpp_quote("#define D3D11_SRGB_TO_FLOAT_DENOMINATOR_1 (12.92f)") +cpp_quote("#define D3D11_SRGB_TO_FLOAT_DENOMINATOR_2 (1.055f)") +cpp_quote("#define D3D11_SRGB_TO_FLOAT_EXPONENT (2.4f)") +cpp_quote("#define D3D11_SRGB_TO_FLOAT_OFFSET (0.055f)") +cpp_quote("#define D3D11_SRGB_TO_FLOAT_THRESHOLD (0.04045f)") +cpp_quote("#define D3D11_SRGB_TO_FLOAT_TOLERANCE_IN_ULP (0.5f)") + +const UINT D3D11_STANDARD_COMPONENT_BIT_COUNT = 32; +const UINT D3D11_STANDARD_COMPONENT_BIT_COUNT_DOUBLED = 64; +const UINT D3D11_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4; +const UINT D3D11_STANDARD_PIXEL_COMPONENT_COUNT = 128; +const UINT D3D11_STANDARD_PIXEL_ELEMENT_COUNT = 32; +const UINT D3D11_STANDARD_VECTOR_SIZE = 4; +const UINT D3D11_STANDARD_VERTEX_ELEMENT_COUNT = 32; +const UINT D3D11_STANDARD_VERTEX_TOTAL_COMPONENT_COUNT = 64; + +cpp_quote("#endif") + +cpp_quote("#ifndef _D3D11_1_CONSTANTS") +cpp_quote("#define _D3D11_1_CONSTANTS") +const UINT D3D11_1_UAV_SLOT_COUNT = 64; +cpp_quote("#endif") + +cpp_quote("#ifndef _D3D11_2_CONSTANTS") +cpp_quote("#define _D3D11_2_CONSTANTS") +const UINT D3D11_2_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 0x10000; +cpp_quote("#endif") + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_DEFAULT {};") +cpp_quote("extern const DECLSPEC_SELECTANY CD3D11_DEFAULT D3D11_DEFAULT;") +cpp_quote("#endif") + +typedef enum D3D11_BLEND +{ + D3D11_BLEND_ZERO = 1, + D3D11_BLEND_ONE = 2, + D3D11_BLEND_SRC_COLOR = 3, + D3D11_BLEND_INV_SRC_COLOR = 4, + D3D11_BLEND_SRC_ALPHA = 5, + D3D11_BLEND_INV_SRC_ALPHA = 6, + D3D11_BLEND_DEST_ALPHA = 7, + D3D11_BLEND_INV_DEST_ALPHA = 8, + D3D11_BLEND_DEST_COLOR = 9, + D3D11_BLEND_INV_DEST_COLOR = 10, + D3D11_BLEND_SRC_ALPHA_SAT = 11, + D3D11_BLEND_BLEND_FACTOR = 14, + D3D11_BLEND_INV_BLEND_FACTOR = 15, + D3D11_BLEND_SRC1_COLOR = 16, + D3D11_BLEND_INV_SRC1_COLOR = 17, + D3D11_BLEND_SRC1_ALPHA = 18, + D3D11_BLEND_INV_SRC1_ALPHA = 19, +} D3D11_BLEND; + +typedef enum D3D11_BLEND_OP +{ + D3D11_BLEND_OP_ADD = 1, + D3D11_BLEND_OP_SUBTRACT, + D3D11_BLEND_OP_REV_SUBTRACT, + D3D11_BLEND_OP_MIN, + D3D11_BLEND_OP_MAX +} D3D11_BLEND_OP; + +typedef enum D3D11_VIDEO_DECODER_BUFFER_TYPE +{ + D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS = 0, + D3D11_VIDEO_DECODER_BUFFER_MACROBLOCK_CONTROL = 1, + D3D11_VIDEO_DECODER_BUFFER_RESIDUAL_DIFFERENCE = 2, + D3D11_VIDEO_DECODER_BUFFER_DEBLOCKING_CONTROL = 3, + D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX = 4, + D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL = 5, + D3D11_VIDEO_DECODER_BUFFER_BITSTREAM = 6, + D3D11_VIDEO_DECODER_BUFFER_MOTION_VECTOR = 7, + D3D11_VIDEO_DECODER_BUFFER_FILM_GRAIN = 8, +} D3D11_VIDEO_DECODER_BUFFER_TYPE; + +typedef enum D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE +{ + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_OPAQUE = 0, + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_BACKGROUND = 1, + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_DESTINATION = 2, + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_SOURCE_STREAM = 3, +} D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE; + +typedef enum D3D11_VIDEO_PROCESSOR_OUTPUT_RATE +{ + D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_NORMAL = 0, + D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_HALF = 1, + D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_CUSTOM = 2, +} D3D11_VIDEO_PROCESSOR_OUTPUT_RATE; + +typedef enum D3D11_VIDEO_PROCESSOR_STEREO_FORMAT +{ + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_MONO = 0, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_HORIZONTAL = 1, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_VERTICAL = 2, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_SEPARATE = 3, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_MONO_OFFSET = 4, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_ROW_INTERLEAVED = 5, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_COLUMN_INTERLEAVED = 6, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_CHECKERBOARD = 7, +} D3D11_VIDEO_PROCESSOR_STEREO_FORMAT; + +typedef enum D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE +{ + D3D11_VIDEO_PROCESSOR_STEREO_FLIP_NONE = 0, + D3D11_VIDEO_PROCESSOR_STEREO_FLIP_FRAME0 = 1, + D3D11_VIDEO_PROCESSOR_STEREO_FLIP_FRAME1 = 2, +} D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE; + +typedef enum D3D11_VIDEO_PROCESSOR_ROTATION +{ + D3D11_VIDEO_PROCESSOR_ROTATION_IDENTITY = 0, + D3D11_VIDEO_PROCESSOR_ROTATION_90 = 1, + D3D11_VIDEO_PROCESSOR_ROTATION_180 = 2, + D3D11_VIDEO_PROCESSOR_ROTATION_270 = 3, +} D3D11_VIDEO_PROCESSOR_ROTATION; + +typedef enum D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS +{ + D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BLEND = 0x01, + D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB = 0x02, + D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_ADAPTIVE = 0x04, + D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_MOTION_COMPENSATION = 0x08, + D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE = 0x10, + D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION = 0x20, +} D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS; + +typedef enum D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS +{ + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_32 = 0x00000001, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_22 = 0x00000002, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_2224 = 0x00000004, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_2332 = 0x00000008, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_32322 = 0x00000010, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_55 = 0x00000020, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_64 = 0x00000040, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_87 = 0x00000080, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_222222222223 = 0x00000100, + D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_OTHER = 0x80000000, +} D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS; + +typedef enum D3D11_CONTENT_PROTECTION_CAPS +{ + D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE = 0x00000001, + D3D11_CONTENT_PROTECTION_CAPS_HARDWARE = 0x00000002, + D3D11_CONTENT_PROTECTION_CAPS_PROTECTION_ALWAYS_ON = 0x00000004, + D3D11_CONTENT_PROTECTION_CAPS_PARTIAL_DECRYPTION = 0x00000008, + D3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY = 0x00000010, + D3D11_CONTENT_PROTECTION_CAPS_FRESHEN_SESSION_KEY = 0x00000020, + D3D11_CONTENT_PROTECTION_CAPS_ENCRYPTED_READ_BACK = 0x00000040, + D3D11_CONTENT_PROTECTION_CAPS_ENCRYPTED_READ_BACK_KEY = 0x00000080, + D3D11_CONTENT_PROTECTION_CAPS_SEQUENTIAL_CTR_IV = 0x00000100, + D3D11_CONTENT_PROTECTION_CAPS_ENCRYPT_SLICEDATA_ONLY = 0x00000200, + D3D11_CONTENT_PROTECTION_CAPS_DECRYPTION_BLT = 0x00000400, + D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_PROTECT_UNCOMPRESSED = 0x00000800, + D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_PROTECTED_MEMORY_PAGEABLE = 0x00001000, + D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_TEARDOWN = 0x00002000, + D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_DRM_COMMUNICATION = 0x00004000, +} D3D11_CONTENT_PROTECTION_CAPS; + +typedef enum D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE +{ + D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_UNDEFINED = 0x00000000, + D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_16_235 = 0x00000001, + D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255 = 0x00000002, +} D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE; + +typedef enum D3D11_AUTHENTICATED_PROCESS_IDENTIFIER_TYPE +{ + D3D11_PROCESSIDTYPE_UNKNOWN = 0x00000000, + D3D11_PROCESSIDTYPE_DWM = 0x00000001, + D3D11_PROCESSIDTYPE_HANDLE = 0x00000002, +} D3D11_AUTHENTICATED_PROCESS_IDENTIFIER_TYPE; + +typedef enum D3D11_BUS_TYPE +{ + D3D11_BUS_TYPE_OTHER = 0x00000000, + D3D11_BUS_TYPE_PCI = 0x00000001, + D3D11_BUS_TYPE_PCIX = 0x00000002, + D3D11_BUS_TYPE_PCIEXPRESS = 0x00000003, + D3D11_BUS_TYPE_AGP = 0x00000004, + D3D11_BUS_IMPL_MODIFIER_INSIDE_OF_CHIPSET = 0x00010000, + D3D11_BUS_IMPL_MODIFIER_TRACKS_ON_MOTHER_BOARD_TO_CHIP = 0x00020000, + D3D11_BUS_IMPL_MODIFIER_TRACKS_ON_MOTHER_BOARD_TO_SOCKET = 0x00030000, + D3D11_BUS_IMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR = 0x00040000, + D3D11_BUS_IMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR_INSIDE_OF_NUAE = 0x00050000, + D3D11_BUS_IMPL_MODIFIER_NON_STANDARD = 0x80000000, +} D3D11_BUS_TYPE; + +typedef struct D3D11_BOX +{ + UINT left; + UINT top; + UINT front; + UINT right; + UINT bottom; + UINT back; +} D3D11_BOX; + +typedef struct D3D11_BUFFER_RTV +{ + union + { + UINT FirstElement; + UINT ElementOffset; + }; + union + { + UINT NumElements; + UINT ElementWidth; + }; +} D3D11_BUFFER_RTV; + +typedef struct D3D11_BUFFER_SRV +{ + union + { + UINT FirstElement; + UINT ElementOffset; + }; + union + { + UINT NumElements; + UINT ElementWidth; + }; +} D3D11_BUFFER_SRV; + +typedef struct D3D11_BUFFER_UAV +{ + UINT FirstElement; + UINT NumElements; + UINT Flags; +} D3D11_BUFFER_UAV; + +typedef struct D3D11_BUFFEREX_SRV +{ + UINT FirstElement; + UINT NumElements; + UINT Flags; +} D3D11_BUFFEREX_SRV; + +typedef struct D3D11_CLASS_INSTANCE_DESC +{ + UINT InstanceId; + UINT InstanceIndex; + UINT TypeId; + UINT ConstantBuffer; + UINT BaseConstantBufferOffset; + UINT BaseTexture; + UINT BaseSampler; + BOOL Created; +} D3D11_CLASS_INSTANCE_DESC; + +typedef enum D3D11_COMPARISON_FUNC +{ + D3D11_COMPARISON_NEVER = 1, + D3D11_COMPARISON_LESS, + D3D11_COMPARISON_EQUAL, + D3D11_COMPARISON_LESS_EQUAL, + D3D11_COMPARISON_GREATER, + D3D11_COMPARISON_NOT_EQUAL, + D3D11_COMPARISON_GREATER_EQUAL, + D3D11_COMPARISON_ALWAYS +} D3D11_COMPARISON_FUNC; + +typedef enum D3D11_COUNTER +{ + D3D11_COUNTER_DEVICE_DEPENDENT_0 = 0x40000000, +} D3D11_COUNTER; + +typedef struct D3D11_COUNTER_DESC +{ + D3D11_COUNTER Counter; + UINT MiscFlags; +} D3D11_COUNTER_DESC; + +typedef struct D3D11_COUNTER_INFO +{ + D3D11_COUNTER LastDeviceDependentCounter; + UINT NumSimultaneousCounters; + UINT8 NumDetectableParallelUnits; +} D3D11_COUNTER_INFO; + +typedef enum D3D11_COUNTER_TYPE +{ + D3D11_COUNTER_TYPE_FLOAT32, + D3D11_COUNTER_TYPE_UINT16, + D3D11_COUNTER_TYPE_UINT32, + D3D11_COUNTER_TYPE_UINT64, +} D3D11_COUNTER_TYPE; + +typedef enum D3D11_CULL_MODE +{ + D3D11_CULL_NONE = 1, + D3D11_CULL_FRONT, + D3D11_CULL_BACK +} D3D11_CULL_MODE; + +typedef enum D3D11_DEPTH_WRITE_MASK +{ + D3D11_DEPTH_WRITE_MASK_ZERO, + D3D11_DEPTH_WRITE_MASK_ALL, +} D3D11_DEPTH_WRITE_MASK; + +typedef enum D3D11_STANDARD_MULTISAMPLE_QUALITY_LEVELS +{ + D3D11_STANDARD_MULTISAMPLE_PATTERN = 0xffffffff, + D3D11_CENTER_MULTISAMPLE_PATTERN = 0xfffffffe, +} D3D11_STANDARD_MULTISAMPLE_QUALITY_LEVELS; + +typedef enum D3D11_DEVICE_CONTEXT_TYPE +{ + D3D11_DEVICE_CONTEXT_IMMEDIATE, + D3D11_DEVICE_CONTEXT_DEFERRED, +} D3D11_DEVICE_CONTEXT_TYPE; + +typedef enum D3D11_DSV_DIMENSION +{ + D3D11_DSV_DIMENSION_UNKNOWN, + D3D11_DSV_DIMENSION_TEXTURE1D, + D3D11_DSV_DIMENSION_TEXTURE1DARRAY, + D3D11_DSV_DIMENSION_TEXTURE2D, + D3D11_DSV_DIMENSION_TEXTURE2DARRAY, + D3D11_DSV_DIMENSION_TEXTURE2DMS, + D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY, +} D3D11_DSV_DIMENSION; + +typedef enum D3D11_FEATURE +{ + D3D11_FEATURE_THREADING, + D3D11_FEATURE_DOUBLES, + D3D11_FEATURE_FORMAT_SUPPORT, + D3D11_FEATURE_FORMAT_SUPPORT2, + D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, + D3D11_FEATURE_D3D11_OPTIONS, + D3D11_FEATURE_ARCHITECTURE_INFO, + D3D11_FEATURE_D3D9_OPTIONS, + D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT, + D3D11_FEATURE_D3D9_SHADOW_SUPPORT, + D3D11_FEATURE_D3D11_OPTIONS1, + D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT, + D3D11_FEATURE_MARKER_SUPPORT, + D3D11_FEATURE_D3D9_OPTIONS1, + D3D11_FEATURE_D3D11_OPTIONS2, + D3D11_FEATURE_D3D11_OPTIONS3, + D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT, + D3D11_FEATURE_D3D11_OPTIONS4, + D3D11_FEATURE_SHADER_CACHE, +} D3D11_FEATURE; + +typedef struct D3D11_FEATURE_DATA_THREADING +{ + BOOL DriverConcurrentCreates; + BOOL DriverCommandLists; +} D3D11_FEATURE_DATA_THREADING; + +typedef struct D3D11_FEATURE_DATA_DOUBLES +{ + BOOL DoublePrecisionFloatShaderOps; +} D3D11_FEATURE_DATA_DOUBLES; + +typedef struct D3D11_FEATURE_DATA_FORMAT_SUPPORT +{ + DXGI_FORMAT InFormat; + UINT OutFormatSupport; +} D3D11_FEATURE_DATA_FORMAT_SUPPORT; + +typedef struct D3D11_FEATURE_DATA_FORMAT_SUPPORT2 +{ + DXGI_FORMAT InFormat; + UINT OutFormatSupport2; +} D3D11_FEATURE_DATA_FORMAT_SUPPORT2; + +typedef struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS +{ + BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; +} D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS; + +typedef struct D3D11_FEATURE_DATA_D3D11_OPTIONS +{ + BOOL OutputMergerLogicOp; + BOOL UAVOnlyRenderingForcedSampleCount; + BOOL DiscardAPIsSeenByDriver; + BOOL FlagsForUpdateAndCopySeenByDriver; + BOOL ClearView; + BOOL CopyWithOverlap; + BOOL ConstantBufferPartialUpdate; + BOOL ConstantBufferOffsetting; + BOOL MapNoOverwriteOnDynamicConstantBuffer; + BOOL MapNoOverwriteOnDynamicBufferSRV; + BOOL MultisampleRTVWithForcedSampleCountOne; + BOOL SAD4ShaderInstructions; + BOOL ExtendedDoublesShaderInstructions; + BOOL ExtendedResourceSharing; +} D3D11_FEATURE_DATA_D3D11_OPTIONS; + +typedef struct D3D11_FEATURE_DATA_ARCHITECTURE_INFO +{ + BOOL TileBasedDeferredRenderer; +} D3D11_FEATURE_DATA_ARCHITECTURE_INFO; + +typedef struct D3D11_FEATURE_DATA_D3D9_OPTIONS +{ + BOOL FullNonPow2TextureSupport; +} D3D11_FEATURE_DATA_D3D9_OPTIONS; + +typedef struct D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT +{ + BOOL SupportsDepthAsTextureWithLessEqualComparisonFilter; +} D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT; + +typedef enum D3D11_SHADER_MIN_PRECISION_SUPPORT +{ + D3D11_SHADER_MIN_PRECISION_10_BIT = 0x1, + D3D11_SHADER_MIN_PRECISION_16_BIT = 0x2, +} D3D11_SHADER_MIN_PRECISION_SUPPORT; + +typedef struct D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT +{ + UINT PixelShaderMinPrecision; + UINT AllOtherShaderStagesMinPrecision; +} D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT; + +typedef enum D3D11_TILED_RESOURCES_TIER +{ + D3D11_TILED_RESOURCES_NOT_SUPPORTED = 0x0, + D3D11_TILED_RESOURCES_TIER_1 = 0x1, + D3D11_TILED_RESOURCES_TIER_2 = 0x2, + D3D11_TILED_RESOURCES_TIER_3 = 0x3, +} D3D11_TILED_RESOURCES_TIER; + +typedef struct D3D11_FEATURE_DATA_D3D11_OPTIONS1 +{ + D3D11_TILED_RESOURCES_TIER TiledResourcesTier; + BOOL MinMaxFiltering; + BOOL ClearViewAlsoSupportsDepthOnlyFormats; + BOOL MapOnDefaultBuffers; +} D3D11_FEATURE_DATA_D3D11_OPTIONS1; + +typedef struct D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT +{ + BOOL SimpleInstancingSupported; +} D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT; + +typedef struct D3D11_FEATURE_DATA_MARKER_SUPPORT +{ + BOOL Profile; +} D3D11_FEATURE_DATA_MARKER_SUPPORT; + +typedef struct D3D11_FEATURE_DATA_D3D9_OPTIONS1 +{ + BOOL FullNonPow2TextureSupported; + BOOL DepthAsTextureWithLessEqualComparisonFilterSupported; + BOOL SimpleInstancingSupported; + BOOL TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported; +} D3D11_FEATURE_DATA_D3D9_OPTIONS1; + +typedef enum D3D11_CONSERVATIVE_RASTERIZATION_TIER +{ + D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED = 0x0, + D3D11_CONSERVATIVE_RASTERIZATION_TIER_1 = 0x1, + D3D11_CONSERVATIVE_RASTERIZATION_TIER_2 = 0x2, + D3D11_CONSERVATIVE_RASTERIZATION_TIER_3 = 0x3, +} D3D11_CONSERVATIVE_RASTERIZATION_TIER; + +typedef struct D3D11_FEATURE_DATA_D3D11_OPTIONS2 +{ + BOOL PSSpecifiedStencilRefSupported; + BOOL TypedUAVLoadAdditionalFormats; + BOOL ROVsSupported; + D3D11_CONSERVATIVE_RASTERIZATION_TIER ConservativeRasterizationTier; + D3D11_TILED_RESOURCES_TIER TiledResourcesTier; + BOOL MapOnDefaultTextures; + BOOL StandardSwizzle; + BOOL UnifiedMemoryArchitecture; +} D3D11_FEATURE_DATA_D3D11_OPTIONS2; + +typedef struct D3D11_FEATURE_DATA_D3D11_OPTIONS3 +{ + BOOL VPAndRTArrayIndexFromAnyShaderFeedingRasterizer; +} D3D11_FEATURE_DATA_D3D11_OPTIONS3; + +typedef struct D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT +{ + UINT MaxGPUVirtualAddressBitsPerResource; + UINT MaxGPUVirtualAddressBitsPerProcess; +} D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT; + +typedef enum D3D11_SHADER_CACHE_SUPPORT_FLAGS +{ + D3D11_SHADER_CACHE_SUPPORT_NONE = 0x0, + D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x1, + D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x2, +} D3D11_SHADER_CACHE_SUPPORT_FLAGS; + +typedef struct D3D11_FEATURE_DATA_SHADER_CACHE +{ + UINT SupportFlags; +} D3D11_FEATURE_DATA_SHADER_CACHE; + +typedef enum D3D11_FILL_MODE +{ + D3D11_FILL_WIREFRAME = 2, + D3D11_FILL_SOLID +} D3D11_FILL_MODE; + +typedef enum D3D11_FILTER_TYPE +{ + D3D11_FILTER_TYPE_POINT = 0, + D3D11_FILTER_TYPE_LINEAR = 1 +} D3D11_FILTER_TYPE; + +const UINT D3D11_MIN_FILTER_SHIFT = 4; +const UINT D3D11_MAG_FILTER_SHIFT = 2; +const UINT D3D11_MIP_FILTER_SHIFT = 0; +const UINT D3D11_FILTER_TYPE_MASK = 0x00000003; +const UINT D3D11_COMPARISON_FILTERING_BIT = 0x00000080; +const UINT D3D11_ANISOTROPIC_FILTERING_BIT = 0x00000040; + +cpp_quote("#define D3D11_ENCODE_BASIC_FILTER(min, mag, mip, bComparison) \\") +cpp_quote(" ((D3D11_FILTER)(((bComparison) ? D3D11_COMPARISON_FILTERING_BIT : 0 ) | \\") +cpp_quote(" (((min)&D3D11_FILTER_TYPE_MASK) << D3D11_MIN_FILTER_SHIFT) | \\") +cpp_quote(" (((mag)&D3D11_FILTER_TYPE_MASK) << D3D11_MAG_FILTER_SHIFT) | \\") +cpp_quote(" (((mip)&D3D11_FILTER_TYPE_MASK) << D3D11_MIP_FILTER_SHIFT)))") + +cpp_quote("#define D3D11_ENCODE_ANISOTROPIC_FILTER(bComparison) \\") +cpp_quote(" ((D3D11_FILTER)(D3D11_ANISOTROPIC_FILTERING_BIT | \\" ) +cpp_quote(" D3D11_ENCODE_BASIC_FILTER(D3D11_FILTER_TYPE_LINEAR,D3D11_FILTER_TYPE_LINEAR, \\" ) +cpp_quote(" D3D11_FILTER_TYPE_LINEAR,bComparison)))" ) + +cpp_quote("#define D3D11_DECODE_MIN_FILTER(d3d11Filter) \\") +cpp_quote(" ((D3D11_FILTER_TYPE)(((d3d11Filter) >> D3D11_MIN_FILTER_SHIFT) & D3D11_FILTER_TYPE_MASK))") + +cpp_quote("#define D3D11_DECODE_MAG_FILTER(d3d11Filter) \\") +cpp_quote(" ((D3D11_FILTER_TYPE)(((d3d11Filter) >> D3D11_MAG_FILTER_SHIFT) & D3D11_FILTER_TYPE_MASK))") + +cpp_quote("#define D3D11_DECODE_MIP_FILTER(d3d11Filter) \\") +cpp_quote(" ((D3D11_FILTER_TYPE)(((d3d11Filter) >> D3D11_MIP_FILTER_SHIFT) & D3D11_FILTER_TYPE_MASK))") + +cpp_quote("#define D3D11_DECODE_IS_COMPARISON_FILTER(d3d11Filter) ((d3d11Filter) & D3D11_COMPARISON_FILTERING_BIT)") + +cpp_quote("#define D3D11_DECODE_IS_ANISOTROPIC_FILTER(d3d11Filter) \\") +cpp_quote(" (((d3d11Filter) & D3D11_ANISOTROPIC_FILTERING_BIT ) \\" ) +cpp_quote(" && (D3D11_FILTER_TYPE_LINEAR == D3D11_DECODE_MIN_FILTER(d3d11Filter)) \\" ) +cpp_quote(" && (D3D11_FILTER_TYPE_LINEAR == D3D11_DECODE_MAG_FILTER(d3d11Filter)) \\" ) +cpp_quote(" && (D3D11_FILTER_TYPE_LINEAR == D3D11_DECODE_MIP_FILTER(d3d11Filter)))") + +typedef enum D3D11_FILTER +{ + D3D11_FILTER_MIN_MAG_MIP_POINT = 0x00, + D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x01, + D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x04, + D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x05, + D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, + D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, + D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, + D3D11_FILTER_MIN_MAG_MIP_LINEAR = 0x15, + D3D11_FILTER_ANISOTROPIC = 0x55, + D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, + D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, + D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, + D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, + D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, + D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, + D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, + D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, + D3D11_FILTER_COMPARISON_ANISOTROPIC = 0xd5 +} D3D11_FILTER; + +typedef enum D3D11_DSV_FLAG +{ + D3D11_DSV_READ_ONLY_DEPTH = 0x1, + D3D11_DSV_READ_ONLY_STENCIL = 0x2, +} D3D11_DSV_FLAG; + +typedef enum D3D11_BUFFEREX_SRV_FLAG +{ + D3D11_BUFFEREX_SRV_FLAG_RAW = 0x1, +} D3D11_BUFFEREX_SRV_FLAG; + +typedef enum D3D11_UAV_FLAG +{ + D3D11_BUFFER_UAV_FLAG_RAW = 0x1, + D3D11_BUFFER_UAV_FLAG_APPEND = 0x2, + D3D11_BUFFER_UAV_FLAG_COUNTER = 0x4, +} D3D11_UAV_FLAG; + +typedef enum D3D11_INPUT_CLASSIFICATION +{ + D3D11_INPUT_PER_VERTEX_DATA, + D3D11_INPUT_PER_INSTANCE_DATA, +} D3D11_INPUT_CLASSIFICATION; + +const UINT D3D11_APPEND_ALIGNED_ELEMENT = 0xffffffff; + +typedef struct D3D11_INPUT_ELEMENT_DESC +{ + LPCSTR SemanticName; + UINT SemanticIndex; + DXGI_FORMAT Format; + UINT InputSlot; + UINT AlignedByteOffset; + D3D11_INPUT_CLASSIFICATION InputSlotClass; + UINT InstanceDataStepRate; +} D3D11_INPUT_ELEMENT_DESC; + +typedef enum D3D11_MAP +{ + D3D11_MAP_READ = 1, + D3D11_MAP_WRITE, + D3D11_MAP_READ_WRITE, + D3D11_MAP_WRITE_DISCARD, + D3D11_MAP_WRITE_NO_OVERWRITE +} D3D11_MAP; + +typedef enum D3D11_MAP_FLAG +{ + D3D11_MAP_FLAG_DO_NOT_WAIT = 0x00100000 +} D3D11_MAP_FLAG; + +typedef struct D3D11_QUERY_DATA_SO_STATISTICS +{ + UINT64 NumPrimitivesWritten; + UINT64 PrimitivesStorageNeeded; +} D3D11_QUERY_DATA_SO_STATISTICS; + +typedef struct D3D11_MAPPED_SUBRESOURCE +{ + void *pData; + UINT RowPitch; + UINT DepthPitch; +} D3D11_MAPPED_SUBRESOURCE; + +typedef enum D3D11_QUERY +{ + D3D11_QUERY_EVENT, + D3D11_QUERY_OCCLUSION, + D3D11_QUERY_TIMESTAMP, + D3D11_QUERY_TIMESTAMP_DISJOINT, + D3D11_QUERY_PIPELINE_STATISTICS, + D3D11_QUERY_OCCLUSION_PREDICATE, + D3D11_QUERY_SO_STATISTICS, + D3D11_QUERY_SO_OVERFLOW_PREDICATE, + D3D11_QUERY_SO_STATISTICS_STREAM0, + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0, + D3D11_QUERY_SO_STATISTICS_STREAM1, + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1, + D3D11_QUERY_SO_STATISTICS_STREAM2, + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2, + D3D11_QUERY_SO_STATISTICS_STREAM3, + D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3, +} D3D11_QUERY; + +typedef enum D3D11_QUERY_MISC_FLAG +{ + D3D11_QUERY_MISC_PREDICATEHINT = 0x1, +} D3D11_QUERY_MISC_FLAG; + +typedef enum D3D11_ASYNC_GETDATA_FLAG +{ + D3D11_ASYNC_GETDATA_DONOTFLUSH = 0x0001, +} D3D11_ASYNC_GETDATA_FLAG; + +typedef enum D3D11_RESOURCE_MISC_FLAG +{ + D3D11_RESOURCE_MISC_GENERATE_MIPS = 0x00000001L, + D3D11_RESOURCE_MISC_SHARED = 0x00000002L, + D3D11_RESOURCE_MISC_TEXTURECUBE = 0x00000004L, + D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS = 0x00000010L, + D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS = 0x00000020L, + D3D11_RESOURCE_MISC_BUFFER_STRUCTURED = 0x00000040L, + D3D11_RESOURCE_MISC_RESOURCE_CLAMP = 0x00000080L, + D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x00000100L, + D3D11_RESOURCE_MISC_GDI_COMPATIBLE = 0x00000200L, + D3D11_RESOURCE_MISC_SHARED_NTHANDLE = 0x00000800L, + D3D11_RESOURCE_MISC_RESTRICTED_CONTENT = 0x00001000L, + D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE = 0x00002000L, + D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE_DRIVER = 0x00004000L, + D3D11_RESOURCE_MISC_GUARDED = 0x00008000L +} D3D11_RESOURCE_MISC_FLAG; + +typedef struct D3D11_QUERY_DESC +{ + D3D11_QUERY Query; + UINT MiscFlags; +} D3D11_QUERY_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_QUERY_DESC : public D3D11_QUERY_DESC {") +cpp_quote(" CD3D11_QUERY_DESC() {}") +cpp_quote(" ~CD3D11_QUERY_DESC() {}") +cpp_quote(" explicit CD3D11_QUERY_DESC(const D3D11_QUERY_DESC &other) : D3D11_QUERY_DESC(other) {}") +cpp_quote(" explicit CD3D11_QUERY_DESC(D3D11_QUERY query, UINT misc_flags = 0) {") +cpp_quote(" Query = query;") +cpp_quote(" MiscFlags = misc_flags;") +cpp_quote(" }") +cpp_quote(" operator const D3D11_QUERY_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D11_RASTERIZER_DESC +{ + D3D11_FILL_MODE FillMode; + D3D11_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL ScissorEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; +} D3D11_RASTERIZER_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_RASTERIZER_DESC : public D3D11_RASTERIZER_DESC {") +cpp_quote(" CD3D11_RASTERIZER_DESC() {}") +cpp_quote(" explicit CD3D11_RASTERIZER_DESC(const D3D11_RASTERIZER_DESC &o) : D3D11_RASTERIZER_DESC(o) {}") +cpp_quote(" explicit CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT) {") +cpp_quote(" FillMode = D3D11_FILL_SOLID;") +cpp_quote(" CullMode = D3D11_CULL_BACK;") +cpp_quote(" FrontCounterClockwise = FALSE;") +cpp_quote(" DepthBias = D3D11_DEFAULT_DEPTH_BIAS;") +cpp_quote(" DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;") +cpp_quote(" SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;") +cpp_quote(" DepthClipEnable = TRUE;") +cpp_quote(" ScissorEnable = FALSE;") +cpp_quote(" MultisampleEnable = FALSE;") +cpp_quote(" AntialiasedLineEnable = FALSE;") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_RASTERIZER_DESC(D3D11_FILL_MODE fillMode, D3D11_CULL_MODE cullMode," ) +cpp_quote(" BOOL frontCounterClockwise, INT depthBias, FLOAT depthBiasClamp, FLOAT slopeScaledDepthBias,") +cpp_quote(" BOOL depthClipEnable, BOOL scissorEnable, BOOL multisampleEnable, BOOL antialiasedLineEnable) {") +cpp_quote(" FillMode = fillMode;") +cpp_quote(" CullMode = cullMode;") +cpp_quote(" FrontCounterClockwise = frontCounterClockwise;") +cpp_quote(" DepthBias = depthBias;") +cpp_quote(" DepthBiasClamp = depthBiasClamp;") +cpp_quote(" SlopeScaledDepthBias = slopeScaledDepthBias;") +cpp_quote(" DepthClipEnable = depthClipEnable;") +cpp_quote(" ScissorEnable = scissorEnable;") +cpp_quote(" MultisampleEnable = multisampleEnable;") +cpp_quote(" AntialiasedLineEnable = antialiasedLineEnable;") +cpp_quote(" }") +cpp_quote(" ~CD3D11_RASTERIZER_DESC() {}") +cpp_quote(" operator const D3D11_RASTERIZER_DESC&() const { return *this; }") +cpp_quote("};") +cpp_quote("#endif") + +typedef enum D3D11_RESOURCE_DIMENSION +{ + D3D11_RESOURCE_DIMENSION_UNKNOWN, + D3D11_RESOURCE_DIMENSION_BUFFER, + D3D11_RESOURCE_DIMENSION_TEXTURE1D, + D3D11_RESOURCE_DIMENSION_TEXTURE2D, + D3D11_RESOURCE_DIMENSION_TEXTURE3D, +} D3D11_RESOURCE_DIMENSION; + +typedef enum D3D11_RTV_DIMENSION +{ + D3D11_RTV_DIMENSION_UNKNOWN, + D3D11_RTV_DIMENSION_BUFFER, + D3D11_RTV_DIMENSION_TEXTURE1D, + D3D11_RTV_DIMENSION_TEXTURE1DARRAY, + D3D11_RTV_DIMENSION_TEXTURE2D, + D3D11_RTV_DIMENSION_TEXTURE2DARRAY, + D3D11_RTV_DIMENSION_TEXTURE2DMS, + D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY, + D3D11_RTV_DIMENSION_TEXTURE3D, +} D3D11_RTV_DIMENSION; + +typedef struct D3D11_SO_DECLARATION_ENTRY +{ + UINT Stream; + LPCSTR SemanticName; + UINT SemanticIndex; + BYTE StartComponent; + BYTE ComponentCount; + BYTE OutputSlot; +} D3D11_SO_DECLARATION_ENTRY; + +typedef enum D3D11_STENCIL_OP +{ + D3D11_STENCIL_OP_KEEP = 1, + D3D11_STENCIL_OP_ZERO, + D3D11_STENCIL_OP_REPLACE, + D3D11_STENCIL_OP_INCR_SAT, + D3D11_STENCIL_OP_DECR_SAT, + D3D11_STENCIL_OP_INVERT, + D3D11_STENCIL_OP_INCR, + D3D11_STENCIL_OP_DECR +} D3D11_STENCIL_OP; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("}") +cpp_quote("inline UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels) {") +cpp_quote(" return MipSlice + ArraySlice * MipLevels;") +cpp_quote("}") +cpp_quote("extern \"C\"{") +cpp_quote("#endif") + +typedef struct D3D11_SUBRESOURCE_DATA +{ + const void *pSysMem; + UINT SysMemPitch; + UINT SysMemSlicePitch; +} D3D11_SUBRESOURCE_DATA; + +typedef struct D3D11_TEX1D_ARRAY_DSV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX1D_ARRAY_DSV; + +typedef struct D3D11_TEX1D_ARRAY_RTV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX1D_ARRAY_RTV; + +typedef struct D3D11_TEX1D_ARRAY_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX1D_ARRAY_SRV; + +typedef struct D3D11_TEX1D_ARRAY_UAV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX1D_ARRAY_UAV; + +typedef struct D3D11_TEX1D_DSV +{ + UINT MipSlice; +} D3D11_TEX1D_DSV; + +typedef struct D3D11_TEX1D_RTV +{ + UINT MipSlice; +} D3D11_TEX1D_RTV; + +typedef struct D3D11_TEX1D_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + } D3D11_TEX1D_SRV; + +typedef struct D3D11_TEX1D_UAV +{ + UINT MipSlice; +} D3D11_TEX1D_UAV; + +typedef struct D3D11_TEX2D_ARRAY_DSV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2D_ARRAY_DSV; + +typedef struct D3D11_TEX2D_ARRAY_RTV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2D_ARRAY_RTV; + +typedef struct D3D11_TEX2D_ARRAY_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2D_ARRAY_SRV; + +typedef struct D3D11_TEX2D_ARRAY_UAV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2D_ARRAY_UAV; + +typedef struct D3D11_TEX2D_DSV +{ + UINT MipSlice; +} D3D11_TEX2D_DSV; + +typedef struct D3D11_TEX2D_RTV +{ + UINT MipSlice; +} D3D11_TEX2D_RTV; + +typedef struct D3D11_TEX2D_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; +} D3D11_TEX2D_SRV; + +typedef struct D3D11_TEX2D_UAV +{ + UINT MipSlice; +} D3D11_TEX2D_UAV; + +typedef struct D3D11_TEX2DMS_ARRAY_DSV +{ + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2DMS_ARRAY_DSV; + +typedef struct D3D11_TEX2DMS_ARRAY_RTV +{ + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2DMS_ARRAY_RTV; + +typedef struct D3D11_TEX2DMS_ARRAY_SRV +{ + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2DMS_ARRAY_SRV; + +typedef struct D3D11_TEX2DMS_DSV +{ + UINT UnusedField_NothingToDefine; +} D3D11_TEX2DMS_DSV; + +typedef struct D3D11_TEX2DMS_RTV +{ + UINT UnusedField_NothingToDefine; +} D3D11_TEX2DMS_RTV; + +typedef struct D3D11_TEX2DMS_SRV +{ + UINT UnusedField_NothingToDefine; +} D3D11_TEX2DMS_SRV; + +typedef struct D3D11_TEX3D_RTV +{ + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; +} D3D11_TEX3D_RTV; + +typedef struct D3D11_TEX3D_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; +} D3D11_TEX3D_SRV; + +typedef struct D3D11_TEX3D_UAV +{ + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; +} D3D11_TEX3D_UAV; + +typedef struct D3D11_TEXCUBE_ARRAY_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT First2DArrayFace; + UINT NumCubes; +} D3D11_TEXCUBE_ARRAY_SRV; + +typedef struct D3D11_TEXCUBE_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; +} D3D11_TEXCUBE_SRV; + +typedef enum D3D11_TEXTURE_ADDRESS_MODE +{ + D3D11_TEXTURE_ADDRESS_WRAP = 1, + D3D11_TEXTURE_ADDRESS_MIRROR, + D3D11_TEXTURE_ADDRESS_CLAMP, + D3D11_TEXTURE_ADDRESS_BORDER, + D3D11_TEXTURE_ADDRESS_MIRROR_ONCE +} D3D11_TEXTURE_ADDRESS_MODE; + +typedef enum D3D11_UAV_DIMENSION +{ + D3D11_UAV_DIMENSION_UNKNOWN, + D3D11_UAV_DIMENSION_BUFFER, + D3D11_UAV_DIMENSION_TEXTURE1D, + D3D11_UAV_DIMENSION_TEXTURE1DARRAY, + D3D11_UAV_DIMENSION_TEXTURE2D, + D3D11_UAV_DIMENSION_TEXTURE2DARRAY, + D3D11_UAV_DIMENSION_TEXTURE3D = 8, +} D3D11_UAV_DIMENSION; + +typedef struct D3D11_UNORDERED_ACCESS_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D11_UAV_DIMENSION ViewDimension; + + union + { + D3D11_BUFFER_UAV Buffer; + D3D11_TEX1D_UAV Texture1D; + D3D11_TEX1D_ARRAY_UAV Texture1DArray; + D3D11_TEX2D_UAV Texture2D; + D3D11_TEX2D_ARRAY_UAV Texture2DArray; + D3D11_TEX3D_UAV Texture3D; + }; +} D3D11_UNORDERED_ACCESS_VIEW_DESC; + +typedef enum D3D11_USAGE +{ + D3D11_USAGE_DEFAULT, + D3D11_USAGE_IMMUTABLE, + D3D11_USAGE_DYNAMIC, + D3D11_USAGE_STAGING, +} D3D11_USAGE; + +typedef enum D3D11_BIND_FLAG +{ + D3D11_BIND_VERTEX_BUFFER = 0x0001, + D3D11_BIND_INDEX_BUFFER = 0x0002, + D3D11_BIND_CONSTANT_BUFFER = 0x0004, + D3D11_BIND_SHADER_RESOURCE = 0x0008, + D3D11_BIND_STREAM_OUTPUT = 0x0010, + D3D11_BIND_RENDER_TARGET = 0x0020, + D3D11_BIND_DEPTH_STENCIL = 0x0040, + D3D11_BIND_UNORDERED_ACCESS = 0x0080, + D3D11_BIND_DECODER = 0x0200, + D3D11_BIND_VIDEO_ENCODER = 0x0400 +} D3D11_BIND_FLAG; + +typedef enum D3D11_CPU_ACCESS_FLAG +{ + D3D11_CPU_ACCESS_WRITE = 0x00010000, + D3D11_CPU_ACCESS_READ = 0x00020000 +} D3D11_CPU_ACCESS_FLAG; + +typedef struct D3D11_VIEWPORT +{ + FLOAT TopLeftX; + FLOAT TopLeftY; + FLOAT Width; + FLOAT Height; + FLOAT MinDepth; + FLOAT MaxDepth; +} D3D11_VIEWPORT; + +typedef enum D3D11_COLOR_WRITE_ENABLE +{ + D3D11_COLOR_WRITE_ENABLE_RED = 1, + D3D11_COLOR_WRITE_ENABLE_GREEN = 2, + D3D11_COLOR_WRITE_ENABLE_BLUE = 4, + D3D11_COLOR_WRITE_ENABLE_ALPHA = 8, + D3D11_COLOR_WRITE_ENABLE_ALL = + (D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE|D3D11_COLOR_WRITE_ENABLE_ALPHA) +} D3D11_COLOR_WRITE_ENABLE; + +typedef enum D3D11_FORMAT_SUPPORT +{ + D3D11_FORMAT_SUPPORT_BUFFER = 0x00000001, + D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER = 0x00000002, + D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER = 0x00000004, + D3D11_FORMAT_SUPPORT_SO_BUFFER = 0x00000008, + D3D11_FORMAT_SUPPORT_TEXTURE1D = 0x00000010, + D3D11_FORMAT_SUPPORT_TEXTURE2D = 0x00000020, + D3D11_FORMAT_SUPPORT_TEXTURE3D = 0x00000040, + D3D11_FORMAT_SUPPORT_TEXTURECUBE = 0x00000080, + D3D11_FORMAT_SUPPORT_SHADER_LOAD = 0x00000100, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE = 0x00000200, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON = 0x00000400, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT = 0x00000800, + D3D11_FORMAT_SUPPORT_MIP = 0x00001000, + D3D11_FORMAT_SUPPORT_MIP_AUTOGEN = 0x00002000, + D3D11_FORMAT_SUPPORT_RENDER_TARGET = 0x00004000, + D3D11_FORMAT_SUPPORT_BLENDABLE = 0x00008000, + D3D11_FORMAT_SUPPORT_DEPTH_STENCIL = 0x00010000, + D3D11_FORMAT_SUPPORT_CPU_LOCKABLE = 0x00020000, + D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE = 0x00040000, + D3D11_FORMAT_SUPPORT_DISPLAY = 0x00080000, + D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT = 0x00100000, + D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET = 0x00200000, + D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD = 0x00400000, + D3D11_FORMAT_SUPPORT_SHADER_GATHER = 0x00800000, + D3D11_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x01000000, + D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW = 0x02000000, + D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON = 0x04000000, + D3D11_FORMAT_SUPPORT_DECODER_OUTPUT = 0x08000000, + D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT = 0x10000000, + D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT = 0x20000000, + D3D11_FORMAT_SUPPORT_VIDEO_ENCODER = 0x40000000, +} D3D11_FORMAT_SUPPORT; + +typedef enum D3D11_CLEAR_FLAG +{ + D3D11_CLEAR_DEPTH = 0x0001L, + D3D11_CLEAR_STENCIL = 0x0002L +} D3D11_CLEAR_FLAG; + +typedef struct D3D11_RENDER_TARGET_BLEND_DESC +{ + BOOL BlendEnable; + D3D11_BLEND SrcBlend; + D3D11_BLEND DestBlend; + D3D11_BLEND_OP BlendOp; + D3D11_BLEND SrcBlendAlpha; + D3D11_BLEND DestBlendAlpha; + D3D11_BLEND_OP BlendOpAlpha; + UINT8 RenderTargetWriteMask; +} D3D11_RENDER_TARGET_BLEND_DESC; + +typedef struct D3D11_BLEND_DESC +{ + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; +} D3D11_BLEND_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_BLEND_DESC : public D3D11_BLEND_DESC {") +cpp_quote(" CD3D11_BLEND_DESC() {}") +cpp_quote(" explicit CD3D11_BLEND_DESC(const D3D11_BLEND_DESC &o) : D3D11_BLEND_DESC(o) {}") +cpp_quote(" explicit CD3D11_BLEND_DESC(CD3D11_DEFAULT) {") +cpp_quote(" AlphaToCoverageEnable = FALSE;") +cpp_quote(" IndependentBlendEnable = FALSE;") +cpp_quote(" for(D3D11_RENDER_TARGET_BLEND_DESC *target = RenderTarget;") +cpp_quote(" target < RenderTarget + D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;") +cpp_quote(" target++) {") +cpp_quote(" target->BlendEnable = FALSE;") +cpp_quote(" target->SrcBlend = target->SrcBlendAlpha = D3D11_BLEND_ONE;") +cpp_quote(" target->DestBlend = target->DestBlendAlpha = D3D11_BLEND_ZERO;") +cpp_quote(" target->BlendOp = target->BlendOpAlpha = D3D11_BLEND_OP_ADD;") +cpp_quote(" target->RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;") +cpp_quote(" }") +cpp_quote(" }") +cpp_quote(" ~CD3D11_BLEND_DESC() {}") +cpp_quote(" operator const D3D11_BLEND_DESC&() const { return *this; }") +cpp_quote("};" ) +cpp_quote("#endif" ) + +typedef struct D3D11_BUFFER_DESC +{ + UINT ByteWidth; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + UINT StructureByteStride; +} D3D11_BUFFER_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_BUFFER_DESC : public D3D11_BUFFER_DESC {") +cpp_quote(" CD3D11_BUFFER_DESC() {}" ) +cpp_quote(" explicit CD3D11_BUFFER_DESC(const D3D11_BUFFER_DESC &o) : D3D11_BUFFER_DESC(o) {}") +cpp_quote(" explicit CD3D11_BUFFER_DESC(UINT byteWidth,UINT bindFlags,") +cpp_quote(" D3D11_USAGE usage = D3D11_USAGE_DEFAULT, UINT cpuaccessFlags = 0,") +cpp_quote(" UINT miscFlags = 0, UINT structureByteStride = 0 ) {") +cpp_quote(" ByteWidth = byteWidth;") +cpp_quote(" Usage = usage;") +cpp_quote(" BindFlags = bindFlags;") +cpp_quote(" CPUAccessFlags = cpuaccessFlags;") +cpp_quote(" MiscFlags = miscFlags;" ) +cpp_quote(" StructureByteStride = structureByteStride;") +cpp_quote(" }") +cpp_quote(" ~CD3D11_BUFFER_DESC() {}") +cpp_quote(" operator const D3D11_BUFFER_DESC&() const { return *this; }") +cpp_quote("};" ) +cpp_quote("#endif" ) + +typedef struct D3D11_DEPTH_STENCIL_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D11_DSV_DIMENSION ViewDimension; + UINT Flags; + + union + { + D3D11_TEX1D_DSV Texture1D; + D3D11_TEX1D_ARRAY_DSV Texture1DArray; + D3D11_TEX2D_DSV Texture2D; + D3D11_TEX2D_ARRAY_DSV Texture2DArray; + D3D11_TEX2DMS_DSV Texture2DMS; + D3D11_TEX2DMS_ARRAY_DSV Texture2DMSArray; + }; +} D3D11_DEPTH_STENCIL_VIEW_DESC; + +typedef struct D3D11_DEPTH_STENCILOP_DESC +{ + D3D11_STENCIL_OP StencilFailOp; + D3D11_STENCIL_OP StencilDepthFailOp; + D3D11_STENCIL_OP StencilPassOp; + D3D11_COMPARISON_FUNC StencilFunc; +} D3D11_DEPTH_STENCILOP_DESC; + +typedef struct D3D11_DEPTH_STENCIL_DESC +{ + BOOL DepthEnable; + D3D11_DEPTH_WRITE_MASK DepthWriteMask; + D3D11_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D11_DEPTH_STENCILOP_DESC FrontFace; + D3D11_DEPTH_STENCILOP_DESC BackFace; +} D3D11_DEPTH_STENCIL_DESC; + +cpp_quote("#if !defined( D3D11_NO_HELPERS ) && defined( __cplusplus )") +cpp_quote("struct CD3D11_DEPTH_STENCIL_DESC : public D3D11_DEPTH_STENCIL_DESC {") +cpp_quote(" CD3D11_DEPTH_STENCIL_DESC() {}") +cpp_quote(" explicit CD3D11_DEPTH_STENCIL_DESC(const D3D11_DEPTH_STENCIL_DESC &other) : D3D11_DEPTH_STENCIL_DESC(other) {}") +cpp_quote(" explicit CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT) {") +cpp_quote(" const D3D11_DEPTH_STENCILOP_DESC default_op =") +cpp_quote(" {D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS};") +cpp_quote(" DepthEnable = TRUE;") +cpp_quote(" DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;") +cpp_quote(" DepthFunc = D3D11_COMPARISON_LESS;") +cpp_quote(" StencilEnable = FALSE;") +cpp_quote(" StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;") +cpp_quote(" StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;") +cpp_quote(" FrontFace = default_op;") +cpp_quote(" BackFace = default_op;") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_DEPTH_STENCIL_DESC(") +cpp_quote(" BOOL depth_enable,") +cpp_quote(" D3D11_DEPTH_WRITE_MASK depth_write_mask,") +cpp_quote(" D3D11_COMPARISON_FUNC depth_func,") +cpp_quote(" BOOL stencil_enable,") +cpp_quote(" UINT8 stencil_read_mask,") +cpp_quote(" UINT8 stencil_write_mask,") +cpp_quote(" D3D11_STENCIL_OP front_stencil_fail_op,") +cpp_quote(" D3D11_STENCIL_OP front_stencil_depth_fail_op,") +cpp_quote(" D3D11_STENCIL_OP front_stencil_pass_op,") +cpp_quote(" D3D11_COMPARISON_FUNC front_stencil_func,") +cpp_quote(" D3D11_STENCIL_OP back_stencil_fail_op,") +cpp_quote(" D3D11_STENCIL_OP back_stencil_depth_fail_op,") +cpp_quote(" D3D11_STENCIL_OP back_stencil_pass_op,") +cpp_quote(" D3D11_COMPARISON_FUNC back_stencil_func) {") +cpp_quote(" DepthEnable = depth_enable;") +cpp_quote(" DepthWriteMask = depth_write_mask;") +cpp_quote(" DepthFunc = depth_func;") +cpp_quote(" StencilEnable = stencil_enable;") +cpp_quote(" StencilReadMask = stencil_read_mask;") +cpp_quote(" StencilWriteMask = stencil_write_mask;") +cpp_quote(" FrontFace.StencilFailOp = front_stencil_fail_op;") +cpp_quote(" FrontFace.StencilDepthFailOp = front_stencil_depth_fail_op;") +cpp_quote(" FrontFace.StencilPassOp = front_stencil_pass_op;") +cpp_quote(" FrontFace.StencilFunc = front_stencil_func;") +cpp_quote(" BackFace.StencilFailOp = back_stencil_fail_op;") +cpp_quote(" BackFace.StencilDepthFailOp = back_stencil_depth_fail_op;") +cpp_quote(" BackFace.StencilPassOp = back_stencil_pass_op;") +cpp_quote(" BackFace.StencilFunc = back_stencil_func;") +cpp_quote(" }") +cpp_quote(" ~CD3D11_DEPTH_STENCIL_DESC() {}") +cpp_quote(" operator const D3D11_DEPTH_STENCIL_DESC&() const { return *this; }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D11_RENDER_TARGET_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D11_RTV_DIMENSION ViewDimension; + + union + { + D3D11_BUFFER_RTV Buffer; + D3D11_TEX1D_RTV Texture1D; + D3D11_TEX1D_ARRAY_RTV Texture1DArray; + D3D11_TEX2D_RTV Texture2D; + D3D11_TEX2D_ARRAY_RTV Texture2DArray; + D3D11_TEX2DMS_RTV Texture2DMS; + D3D11_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D11_TEX3D_RTV Texture3D; + }; +} D3D11_RENDER_TARGET_VIEW_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_RENDER_TARGET_VIEW_DESC : public D3D11_RENDER_TARGET_VIEW_DESC {") +cpp_quote(" CD3D11_RENDER_TARGET_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION dim, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN,") +cpp_quote(" UINT mip_slice = 0, UINT first_slice = 0, UINT array_size = -1) {") +cpp_quote(" Format = format;") +cpp_quote(" ViewDimension = dim;") +cpp_quote(" switch(dim) {") +cpp_quote(" case D3D11_RTV_DIMENSION_BUFFER:") +cpp_quote(" Buffer.FirstElement = mip_slice;") +cpp_quote(" Buffer.NumElements = first_slice;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE1D:") +cpp_quote(" Texture1D.MipSlice = mip_slice;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:") +cpp_quote(" Texture1DArray.MipSlice = mip_slice;") +cpp_quote(" Texture1DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture1DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE2D:") +cpp_quote(" Texture2D.MipSlice = mip_slice;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:") +cpp_quote(" Texture2DArray.MipSlice = mip_slice;") +cpp_quote(" Texture2DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:") +cpp_quote(" Texture2DMSArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DMSArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE3D:") +cpp_quote(" Texture3D.MipSlice = mip_slice;") +cpp_quote(" Texture3D.FirstWSlice = first_slice;") +cpp_quote(" Texture3D.WSize = array_size;") +cpp_quote(" break;") +cpp_quote(" default:") +cpp_quote(" break;") +cpp_quote(" }") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Buffer*, DXGI_FORMAT format, UINT first_elem,") +cpp_quote(" UINT elem_cnt) {") +cpp_quote(" Format = format;") +cpp_quote(" ViewDimension = D3D11_RTV_DIMENSION_BUFFER;") +cpp_quote(" Buffer.FirstElement = first_elem;") +cpp_quote(" Buffer.NumElements = elem_cnt;") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Texture1D *texture, D3D11_RTV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT mip_slice = 0, UINT first_slice = 0,") +cpp_quote(" UINT array_size = -1);") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Texture2D *texture, D3D11_RTV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT mip_slice = 0, UINT first_slice = 0,") +cpp_quote(" UINT array_size = -1);") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Texture3D *texture, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN,") +cpp_quote(" UINT mip_slice = 0, UINT first_w_slice = 0, UINT w_slice = -1 );") /* FIXME: implement */ +cpp_quote(" ~CD3D11_RENDER_TARGET_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(const D3D11_RENDER_TARGET_VIEW_DESC &other)") +cpp_quote(" : D3D11_RENDER_TARGET_VIEW_DESC(other) {}") +cpp_quote(" operator const D3D11_RENDER_TARGET_VIEW_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + + +typedef struct D3D11_SAMPLER_DESC +{ + D3D11_FILTER Filter; + D3D11_TEXTURE_ADDRESS_MODE AddressU; + D3D11_TEXTURE_ADDRESS_MODE AddressV; + D3D11_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D11_COMPARISON_FUNC ComparisonFunc; + FLOAT BorderColor[4]; + FLOAT MinLOD; + FLOAT MaxLOD; +} D3D11_SAMPLER_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_SAMPLER_DESC : public D3D11_SAMPLER_DESC {") +cpp_quote(" CD3D11_SAMPLER_DESC() {}") +cpp_quote(" explicit CD3D11_SAMPLER_DESC(const D3D11_SAMPLER_DESC &o) : D3D11_SAMPLER_DESC(o) {}") +cpp_quote(" explicit CD3D11_SAMPLER_DESC(CD3D11_DEFAULT) {" ) +cpp_quote(" Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;") +cpp_quote(" AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;") +cpp_quote(" AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;") +cpp_quote(" AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;") +cpp_quote(" MipLODBias = 0;") +cpp_quote(" MaxAnisotropy = 1;") +cpp_quote(" ComparisonFunc = D3D11_COMPARISON_NEVER;") +cpp_quote(" BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 1.0f;") +cpp_quote(" MinLOD = -3.402823466e+38f;") +cpp_quote(" MaxLOD = 3.402823466e+38f;") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_SAMPLER_DESC(D3D11_FILTER filter, D3D11_TEXTURE_ADDRESS_MODE addressU,") +cpp_quote(" D3D11_TEXTURE_ADDRESS_MODE addressV, D3D11_TEXTURE_ADDRESS_MODE addressW,") +cpp_quote(" FLOAT mipLODBias, UINT maxAnisotropy, D3D11_COMPARISON_FUNC comparisonFunc,") +cpp_quote(" const FLOAT *borderColor, FLOAT minLOD, FLOAT maxLOD) {" ) +cpp_quote(" Filter = filter;") +cpp_quote(" AddressU = addressU;") +cpp_quote(" AddressV = addressV;") +cpp_quote(" AddressW = addressW;") +cpp_quote(" MipLODBias = mipLODBias;") +cpp_quote(" MaxAnisotropy = maxAnisotropy;") +cpp_quote(" ComparisonFunc = comparisonFunc;") +cpp_quote(" if(borderColor) {") +cpp_quote(" BorderColor[0] = borderColor[0];") +cpp_quote(" BorderColor[1] = borderColor[1];") +cpp_quote(" BorderColor[2] = borderColor[2];") +cpp_quote(" BorderColor[3] = borderColor[3];") +cpp_quote(" }else {") +cpp_quote(" BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 1.0f;") +cpp_quote(" }") +cpp_quote(" MinLOD = minLOD;") +cpp_quote(" MaxLOD = maxLOD;") +cpp_quote(" }") +cpp_quote(" ~CD3D11_SAMPLER_DESC() {}") +cpp_quote(" operator const D3D11_SAMPLER_DESC&() const { return *this; }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D11_SHADER_RESOURCE_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D11_SRV_DIMENSION ViewDimension; + + union + { + D3D11_BUFFER_SRV Buffer; + D3D11_TEX1D_SRV Texture1D; + D3D11_TEX1D_ARRAY_SRV Texture1DArray; + D3D11_TEX2D_SRV Texture2D; + D3D11_TEX2D_ARRAY_SRV Texture2DArray; + D3D11_TEX2DMS_SRV Texture2DMS; + D3D11_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D11_TEX3D_SRV Texture3D; + D3D11_TEXCUBE_SRV TextureCube; + D3D11_TEXCUBE_ARRAY_SRV TextureCubeArray; + D3D11_BUFFEREX_SRV BufferEx; + }; +} D3D11_SHADER_RESOURCE_VIEW_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined( __cplusplus )") +cpp_quote("struct CD3D11_SHADER_RESOURCE_VIEW_DESC : public D3D11_SHADER_RESOURCE_VIEW_DESC {") +cpp_quote(" CD3D11_SHADER_RESOURCE_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT most_detailed_mip = 0,") +cpp_quote(" UINT mip_levels = -1, UINT first_slice = 0, UINT array_size = -1, UINT flags = 0) {") +cpp_quote(" Format = format;") +cpp_quote(" ViewDimension = dim;") +cpp_quote(" switch(ViewDimension) {") +cpp_quote(" case D3D11_SRV_DIMENSION_BUFFER:") +cpp_quote(" Buffer.FirstElement = most_detailed_mip;") +cpp_quote(" Buffer.NumElements = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE1D:") +cpp_quote(" Texture1D.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture1D.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:") +cpp_quote(" Texture1DArray.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture1DArray.MipLevels = mip_levels;") +cpp_quote(" Texture1DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture1DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE2D:") +cpp_quote(" Texture2D.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture2D.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:") +cpp_quote(" Texture2DArray.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture2DArray.MipLevels = mip_levels;") +cpp_quote(" Texture2DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:") +cpp_quote(" Texture2DMSArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DMSArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE3D:") +cpp_quote(" Texture3D.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture3D.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURECUBE:") +cpp_quote(" TextureCube.MostDetailedMip = most_detailed_mip;") +cpp_quote(" TextureCube.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:") +cpp_quote(" TextureCubeArray.MostDetailedMip = most_detailed_mip;") +cpp_quote(" TextureCubeArray.MipLevels = mip_levels;") +cpp_quote(" TextureCubeArray.First2DArrayFace = first_slice;") +cpp_quote(" TextureCubeArray.NumCubes = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_BUFFEREX:") +cpp_quote(" BufferEx.FirstElement = most_detailed_mip;") +cpp_quote(" BufferEx.NumElements = mip_levels;") +cpp_quote(" BufferEx.Flags = flags;") +cpp_quote(" break;") +cpp_quote(" default:") +cpp_quote(" break;") +cpp_quote(" }") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Buffer*, DXGI_FORMAT format, UINT first_elem,") +cpp_quote(" UINT elem_cnt, UINT flags = 0);") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Texture1D *texture, D3D11_SRV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT most_detailed_mip = 0, UINT mip_levels = -1,") +cpp_quote(" UINT first_slice = 0, UINT array_size = -1 );") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Texture2D *texture, D3D11_SRV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT most_detailed_mip = 0, UINT mip_levels = -1,") +cpp_quote(" UINT first_slice = 0, UINT array_size = -1 );") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Texture3D *texture, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN,") +cpp_quote(" UINT most_detailed_mip = 0, UINT mip_levels = -1 );") +cpp_quote(" ~CD3D11_SHADER_RESOURCE_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(const D3D11_SHADER_RESOURCE_VIEW_DESC &other)") +cpp_quote(" : D3D11_SHADER_RESOURCE_VIEW_DESC(other) {}") +cpp_quote(" operator const D3D11_SHADER_RESOURCE_VIEW_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D11_TEXTURE1D_DESC +{ + UINT Width; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D11_TEXTURE1D_DESC; + +typedef struct D3D11_TEXTURE2D_DESC +{ + UINT Width; + UINT Height; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D11_TEXTURE2D_DESC; + +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_TEXTURE2D_DESC : public D3D11_TEXTURE2D_DESC {") +cpp_quote(" CD3D11_TEXTURE2D_DESC() {}") +cpp_quote(" explicit CD3D11_TEXTURE2D_DESC(const D3D11_TEXTURE2D_DESC &o) : D3D11_TEXTURE2D_DESC(o) {}") +cpp_quote(" explicit CD3D11_TEXTURE2D_DESC(DXGI_FORMAT format, UINT width, UINT height, UINT arraySize = 1,") +cpp_quote(" UINT mipLevels = 0, UINT bindFlags = D3D11_BIND_SHADER_RESOURCE,") +cpp_quote(" D3D11_USAGE usage = D3D11_USAGE_DEFAULT, UINT cpuaccessFlags = 0, UINT sampleCount = 1," ) +cpp_quote(" UINT sampleQuality = 0, UINT miscFlags = 0) {") +cpp_quote(" Width = width;") +cpp_quote(" Height = height;") +cpp_quote(" MipLevels = mipLevels;") +cpp_quote(" ArraySize = arraySize;") +cpp_quote(" Format = format;") +cpp_quote(" SampleDesc.Count = sampleCount;") +cpp_quote(" SampleDesc.Quality = sampleQuality;") +cpp_quote(" Usage = usage;") +cpp_quote(" BindFlags = bindFlags;") +cpp_quote(" CPUAccessFlags = cpuaccessFlags;") +cpp_quote(" MiscFlags = miscFlags;") +cpp_quote(" }" ) +cpp_quote(" ~CD3D11_TEXTURE2D_DESC() {}") +cpp_quote(" operator const D3D11_TEXTURE2D_DESC&() const { return *this; }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D11_TEXTURE3D_DESC +{ + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + DXGI_FORMAT Format; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D11_TEXTURE3D_DESC; + +typedef struct D3D11_VIDEO_DECODER_DESC +{ + GUID Guid; + UINT SampleWidth; + UINT SampleHeight; + DXGI_FORMAT OutputFormat; +} D3D11_VIDEO_DECODER_DESC; + +typedef struct D3D11_VIDEO_DECODER_CONFIG +{ + GUID guidConfigBitstreamEncryption; + GUID guidConfigMBcontrolEncryption; + GUID guidConfigResidDiffEncryption; + UINT ConfigBitstreamRaw; + UINT ConfigMBcontrolRasterOrder; + UINT ConfigResidDiffHost; + UINT ConfigSpatialResid8; + UINT ConfigResid8Subtraction; + UINT ConfigSpatialHost8or9Clipping; + UINT ConfigSpatialResidInterleaved; + UINT ConfigIntraResidUnsigned; + UINT ConfigResidDiffAccelerator; + UINT ConfigHostInverseScan; + UINT ConfigSpecificIDCT; + UINT Config4GroupedCoefs; + USHORT ConfigMinRenderTargetBuffCount; + USHORT ConfigDecoderSpecific; +} D3D11_VIDEO_DECODER_CONFIG; + +typedef enum D3D11_VIDEO_FRAME_FORMAT +{ + D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE = 0, + D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST = 1, + D3D11_VIDEO_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST = 2 +} D3D11_VIDEO_FRAME_FORMAT; + +typedef enum D3D11_VIDEO_USAGE +{ + D3D11_VIDEO_USAGE_PLAYBACK_NORMAL = 0, + D3D11_VIDEO_USAGE_OPTIMAL_SPEED = 1, + D3D11_VIDEO_USAGE_OPTIMAL_QUALITY = 2 +} D3D11_VIDEO_USAGE; + +typedef struct D3D11_VIDEO_PROCESSOR_CONTENT_DESC +{ + D3D11_VIDEO_FRAME_FORMAT InputFrameFormat; + DXGI_RATIONAL InputFrameRate; + UINT InputWidth; + UINT InputHeight; + DXGI_RATIONAL OutputFrameRate; + UINT OutputWidth; + UINT OutputHeight; + D3D11_VIDEO_USAGE Usage; +} D3D11_VIDEO_PROCESSOR_CONTENT_DESC; + +typedef struct D3D11_VIDEO_PROCESSOR_CAPS +{ + UINT DeviceCaps; + UINT FeatureCaps; + UINT FilterCaps; + UINT InputFormatCaps; + UINT AutoStreamCaps; + UINT StereoCaps; + UINT RateConversionCapsCount; + UINT MaxInputStreams; + UINT MaxStreamStates; +} D3D11_VIDEO_PROCESSOR_CAPS; + +typedef struct D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS +{ + UINT PastFrames; + UINT FutureFrames; + UINT ProcessorCaps; + UINT ITelecineCaps; + UINT CustomRateCount; +} D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS; + +typedef struct D3D11_VIDEO_PROCESSOR_CUSTOM_RATE +{ + DXGI_RATIONAL CustomRate; + UINT OutputFrames; + BOOL InputInterlaced; + UINT InputFramesOrFields; +} D3D11_VIDEO_PROCESSOR_CUSTOM_RATE; + +typedef enum D3D11_VIDEO_PROCESSOR_FILTER +{ + D3D11_VIDEO_PROCESSOR_FILTER_BRIGHTNESS = 0, + D3D11_VIDEO_PROCESSOR_FILTER_CONTRAST = 1, + D3D11_VIDEO_PROCESSOR_FILTER_HUE = 2, + D3D11_VIDEO_PROCESSOR_FILTER_SATURATION = 3, + D3D11_VIDEO_PROCESSOR_FILTER_NOISE_REDUCTION = 4, + D3D11_VIDEO_PROCESSOR_FILTER_EDGE_ENHANCEMENT = 5, + D3D11_VIDEO_PROCESSOR_FILTER_ANAMORPHIC_SCALING = 6, + D3D11_VIDEO_PROCESSOR_FILTER_STEREO_ADJUSTMENT = 7 +} D3D11_VIDEO_PROCESSOR_FILTER; + +typedef struct D3D11_VIDEO_PROCESSOR_FILTER_RANGE +{ + int Minimum; + int Maximum; + int Default; + float Multiplier; +} D3D11_VIDEO_PROCESSOR_FILTER_RANGE; + +typedef enum D3D11_AUTHENTICATED_CHANNEL_TYPE +{ + D3D11_AUTHENTICATED_CHANNEL_D3D11 = 1, + D3D11_AUTHENTICATED_CHANNEL_DRIVER_SOFTWARE = 2, + D3D11_AUTHENTICATED_CHANNEL_DRIVER_HARDWARE = 3 +} D3D11_AUTHENTICATED_CHANNEL_TYPE; + +typedef enum D3D11_VDOV_DIMENSION +{ + D3D11_VDOV_DIMENSION_UNKNOWN = 0, + D3D11_VDOV_DIMENSION_TEXTURE2D = 1 +} D3D11_VDOV_DIMENSION; + +typedef struct D3D11_TEX2D_VDOV +{ + UINT ArraySlice; +} D3D11_TEX2D_VDOV; + +typedef struct D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC +{ + GUID DecodeProfile; + D3D11_VDOV_DIMENSION ViewDimension; + union { + D3D11_TEX2D_VDOV Texture2D; + }; +} D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC; + +typedef enum D3D11_VPIV_DIMENSION +{ + D3D11_VPIV_DIMENSION_UNKNOWN = 0, + D3D11_VPIV_DIMENSION_TEXTURE2D = 1 +} D3D11_VPIV_DIMENSION; + +typedef struct D3D11_TEX2D_VPIV +{ + UINT MipSlice; + UINT ArraySlice; +} D3D11_TEX2D_VPIV; + +typedef struct D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC +{ + UINT FourCC; + D3D11_VPIV_DIMENSION ViewDimension; + union { + D3D11_TEX2D_VPIV Texture2D; + }; +} D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC; + +typedef enum D3D11_VPOV_DIMENSION +{ + D3D11_VPOV_DIMENSION_UNKNOWN = 0, + D3D11_VPOV_DIMENSION_TEXTURE2D = 1, + D3D11_VPOV_DIMENSION_TEXTURE2DARRAY = 2 +} D3D11_VPOV_DIMENSION; + +typedef struct D3D11_TEX2D_VPOV +{ + UINT MipSlice; +} D3D11_TEX2D_VPOV; + +typedef struct D3D11_TEX2D_ARRAY_VPOV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D11_TEX2D_ARRAY_VPOV; + +typedef struct D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC +{ + D3D11_VPOV_DIMENSION ViewDimension; + union { + D3D11_TEX2D_VPOV Texture2D; + D3D11_TEX2D_ARRAY_VPOV Texture2DArray; + }; +} D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC; + +typedef struct D3D11_VIDEO_CONTENT_PROTECTION_CAPS +{ + UINT Caps; + UINT KeyExchangeTypeCount; + UINT BlockAlignmentSize; + ULONGLONG ProtectedMemorySize; +} D3D11_VIDEO_CONTENT_PROTECTION_CAPS; + +typedef struct D3D11_ENCRYPTED_BLOCK_INFO +{ + UINT NumEncryptedBytesAtBeginning; + UINT NumBytesInSkipPattern; + UINT NumBytesInEncryptPattern; +} D3D11_ENCRYPTED_BLOCK_INFO; + +typedef struct D3D11_VIDEO_DECODER_BUFFER_DESC +{ + D3D11_VIDEO_DECODER_BUFFER_TYPE BufferType; + UINT BufferIndex; + UINT DataOffset; + UINT DataSize; + UINT FirstMBaddress; + UINT NumMBsInBuffer; + UINT Width; + UINT Height; + UINT Stride; + UINT ReservedBits; + void *pIV; + UINT IVSize; + BOOL PartialEncryption; + D3D11_ENCRYPTED_BLOCK_INFO EncryptedBlockInfo; +} D3D11_VIDEO_DECODER_BUFFER_DESC; + +typedef struct D3D11_VIDEO_DECODER_EXTENSION +{ + UINT Function; + void *pPrivateInputData; + UINT PrivateInputDataSize; + void *pPrivateOutputData; + UINT PrivateOutputDataSize; + UINT ResourceCount; + ID3D11Resource **ppResourceList; +} D3D11_VIDEO_DECODER_EXTENSION; + +typedef struct D3D11_VIDEO_COLOR_YCbCrA +{ + float Y; + float Cb; + float Cr; + float A; +} D3D11_VIDEO_COLOR_YCbCrA; + +typedef struct D3D11_VIDEO_COLOR_RGBA +{ + float R; + float G; + float B; + float A; +} D3D11_VIDEO_COLOR_RGBA; + +typedef struct D3D11_VIDEO_COLOR +{ + union + { + D3D11_VIDEO_COLOR_YCbCrA YCbCr; + D3D11_VIDEO_COLOR_RGBA RGBA; + }; +} D3D11_VIDEO_COLOR; + +typedef struct D3D11_VIDEO_PROCESSOR_COLOR_SPACE +{ + UINT Usage : 1; + UINT RGB_Range : 1; + UINT YCbCr_Matrix : 1; + UINT YCbCr_xvYCC : 1; + UINT Nominal_Range : 2; + UINT Reserved : 26; +} D3D11_VIDEO_PROCESSOR_COLOR_SPACE; + +typedef struct D3D11_VIDEO_PROCESSOR_STREAM +{ + BOOL Enable; + UINT OutputIndex; + UINT InputFrameOrField; + UINT PastFrames; + UINT FutureFrames; + ID3D11VideoProcessorInputView **ppPastSurfaces; + ID3D11VideoProcessorInputView *pInputSurface; + ID3D11VideoProcessorInputView **ppFutureSurfaces; + ID3D11VideoProcessorInputView **ppPastSurfacesRight; + ID3D11VideoProcessorInputView *pInputSurfaceRight; + ID3D11VideoProcessorInputView **ppFutureSurfacesRight; +} D3D11_VIDEO_PROCESSOR_STREAM; + +typedef struct D3D11_OMAC +{ + BYTE Omac[D3D11_OMAC_SIZE]; +} D3D11_OMAC; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_OUTPUT +{ + D3D11_OMAC omac; + GUID ConfigureType; + HANDLE hChannel; + UINT SequenceNumber; + HRESULT ReturnCode; +} D3D11_AUTHENTICATED_CONFIGURE_OUTPUT; + +typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT +{ + UINT64 Frequency; + BOOL Disjoint; +} D3D11_QUERY_DATA_TIMESTAMP_DISJOINT; + +typedef struct D3D11_QUERY_DATA_PIPELINE_STATISTICS +{ + UINT64 IAVertices; + UINT64 IAPrimitives; + UINT64 VSInvocations; + UINT64 GSInvocations; + UINT64 GSPrimitives; + UINT64 CInvocations; + UINT64 CPrimitives; + UINT64 PSInvocations; + UINT64 HSInvocations; + UINT64 DSInvocations; + UINT64 CSInvocations; +} D3D11_QUERY_DATA_PIPELINE_STATISTICS; + +typedef struct D3D11_DRAW_INSTANCED_INDIRECT_ARGS +{ + UINT VertexCountPerInstance; + UINT InstanceCount; + UINT StartVertexLocation; + UINT StartInstanceLocation; +} D3D11_DRAW_INSTANCED_INDIRECT_ARGS; + +typedef struct D3D11_DRAW_INDEXED_INSTANCED_INDIRECT_ARGS +{ + UINT IndexCountPerInstance; + UINT InstanceCount; + UINT StartIndexLocation; + INT BaseVertexLocation; + UINT StartInstanceLocation; +} D3D11_DRAW_INDEXED_INSTANCED_INDIRECT_ARGS; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_INPUT +{ + D3D11_OMAC omac; + GUID ConfigureType; + HANDLE hChannel; + UINT SequenceNumber; +} D3D11_AUTHENTICATED_CONFIGURE_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_INPUT +{ + GUID QueryType; + HANDLE hChannel; + UINT SequenceNumber; +} D3D11_AUTHENTICATED_QUERY_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_OUTPUT +{ + D3D11_OMAC omac; + GUID QueryType; + HANDLE hChannel; + UINT SequenceNumber; + HRESULT ReturnCode; +} D3D11_AUTHENTICATED_QUERY_OUTPUT; + +typedef union D3D11_AUTHENTICATED_PROTECTION_FLAGS +{ + struct + { + UINT ProtectionEnabled : 1; + UINT OverlayOrFullscreenRequired : 1; + UINT Reserved : 30; + } Flags; + UINT Value; +} D3D11_AUTHENTICATED_PROTECTION_FLAGS; + +typedef struct D3D11_AUTHENTICATED_QUERY_PROTECTION_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + D3D11_AUTHENTICATED_PROTECTION_FLAGS ProtectionFlags; +} D3D11_AUTHENTICATED_QUERY_PROTECTION_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_CHANNEL_TYPE_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + D3D11_AUTHENTICATED_CHANNEL_TYPE ChannelType; +} D3D11_AUTHENTICATED_QUERY_CHANNEL_TYPE_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_DEVICE_HANDLE_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + HANDLE DeviceHandle; +} D3D11_AUTHENTICATED_QUERY_DEVICE_HANDLE_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_CRYPTO_SESSION_INPUT +{ + D3D11_AUTHENTICATED_QUERY_INPUT Input; + HANDLE DecoderHandle; +} D3D11_AUTHENTICATED_QUERY_CRYPTO_SESSION_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_CRYPTO_SESSION_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + HANDLE DecoderHandle; + HANDLE CryptoSessionHandle; + HANDLE DeviceHandle; +} D3D11_AUTHENTICATED_QUERY_CRYPTO_SESSION_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_COUNT_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + UINT RestrictedSharedResourceProcessCount; +} D3D11_AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_COUNT_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_INPUT +{ + D3D11_AUTHENTICATED_QUERY_INPUT Input; + UINT ProcessIndex; +} D3D11_AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + UINT ProcessIndex; + D3D11_AUTHENTICATED_PROCESS_IDENTIFIER_TYPE ProcessIdentifier; + HANDLE ProcessHandle; +} D3D11_AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_UNRESTRICTED_PROTECTED_SHARED_RESOURCE_COUNT_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + UINT UnrestrictedProtectedSharedResourceCount; +} D3D11_AUTHENTICATED_QUERY_UNRESTRICTED_PROTECTED_SHARED_RESOURCE_COUNT_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_COUNT_INPUT +{ + D3D11_AUTHENTICATED_QUERY_INPUT Input; + HANDLE DeviceHandle; + HANDLE CryptoSessionHandle; +} D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_COUNT_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_COUNT_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + HANDLE DeviceHandle; + HANDLE CryptoSessionHandle; + UINT OutputIDCount; +} D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_COUNT_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_INPUT +{ + D3D11_AUTHENTICATED_QUERY_INPUT Input; + HANDLE DeviceHandle; + HANDLE CryptoSessionHandle; + UINT OutputIDIndex; +} D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + HANDLE DeviceHandle; + HANDLE CryptoSessionHandle; + UINT OutputIDIndex; + UINT64 OutputID; +} D3D11_AUTHENTICATED_QUERY_OUTPUT_ID_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_ACESSIBILITY_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + D3D11_BUS_TYPE BusType; + BOOL AccessibleInContiguousBlocks; + BOOL AccessibleInNonContiguousBlocks; +} D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_COUNT_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + UINT EncryptionGuidCount; +} D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_COUNT_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_INPUT +{ + D3D11_AUTHENTICATED_QUERY_INPUT Input; + UINT EncryptionGuidIndex; +} D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_INPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + UINT EncryptionGuidIndex; + GUID EncryptionGuid; +} D3D11_AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_QUERY_CURRENT_ACCESSIBILITY_ENCRYPTION_OUTPUT +{ + D3D11_AUTHENTICATED_QUERY_OUTPUT Output; + GUID EncryptionGuid; +} D3D11_AUTHENTICATED_QUERY_CURRENT_ACCESSIBILITY_ENCRYPTION_OUTPUT; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT +{ + D3D11_AUTHENTICATED_CONFIGURE_INPUT Parameters; + UINT StartSequenceQuery; + UINT StartSequenceConfigure; +} D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_PROTECTION_INPUT +{ + D3D11_AUTHENTICATED_CONFIGURE_INPUT Parameters; + D3D11_AUTHENTICATED_PROTECTION_FLAGS Protections; +} D3D11_AUTHENTICATED_CONFIGURE_PROTECTION_INPUT; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT +{ + D3D11_AUTHENTICATED_CONFIGURE_INPUT Parameters; + HANDLE DecoderHandle; + HANDLE CryptoSessionHandle; + HANDLE DeviceHandle; +} D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_SHARED_RESOURCE_INPUT +{ + D3D11_AUTHENTICATED_CONFIGURE_INPUT Parameters; + D3D11_AUTHENTICATED_PROCESS_IDENTIFIER_TYPE ProcessType; + HANDLE ProcessHandle; + BOOL AllowAccess; +} D3D11_AUTHENTICATED_CONFIGURE_SHARED_RESOURCE_INPUT; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_ACCESSIBLE_ENCRYPTION_INPUT +{ + D3D11_AUTHENTICATED_CONFIGURE_INPUT Parameters; + GUID EncryptionGuid; +} D3D11_AUTHENTICATED_CONFIGURE_ACCESSIBLE_ENCRYPTION_INPUT; + +[ + object, + local, + uuid(1841e5c8-16b0-489b-bcc8-44cfb0d5deae) +] +interface ID3D11DeviceChild : IUnknown +{ + void GetDevice( + [out] ID3D11Device **ppDevice); + HRESULT GetPrivateData( + [in] REFGUID guid, + [in, out] UINT *pDataSize, + [out] void *pData); + HRESULT SetPrivateData( + [in] REFGUID guid, + [in] UINT DataSize, + [in] const void *pData); + HRESULT SetPrivateDataInterface( + [in] REFGUID guid, + [in] const IUnknown *pData); +} + +[ + object, + local, + uuid(4b35d0cd-1e15-4258-9c98-1b1333f6dd3b) +] +interface ID3D11Asynchronous : ID3D11DeviceChild +{ + UINT GetDataSize(); +} + +[ + object, + local, + uuid(d6c00747-87b7-425e-b84d-44d108560afd) +] +interface ID3D11Query : ID3D11Asynchronous +{ + void GetDesc( + [out] D3D11_QUERY_DESC *pDesc); +} + +[ + object, + local, + uuid(dc8e63f3-d12b-4952-b47b-5e45026a862d) +] +interface ID3D11Resource : ID3D11DeviceChild +{ + void GetType( + [out] D3D11_RESOURCE_DIMENSION *pResourceDimension); + void SetEvictionPriority( + [in] UINT EvictionPriority); + UINT GetEvictionPriority(); +} + +[ + object, + local, + uuid(839d1216-bb2e-412b-b7f4-a9dbebe08ed1) +] +interface ID3D11View : ID3D11DeviceChild +{ + void GetResource( + [out] ID3D11Resource **ppResource); +} + +[ + object, + local, + uuid(75b68faa-347d-4159-8f45-a0640f01cd9a) +] +interface ID3D11BlendState : ID3D11DeviceChild +{ + void GetDesc( + [out] D3D11_BLEND_DESC *pDesc); +} + +[ + object, + local, + uuid(48570b85-d1ee-4fcd-a250-eb350722b037) +] +interface ID3D11Buffer : ID3D11Resource +{ + void GetDesc( + [out] D3D11_BUFFER_DESC *pDesc); +} + +[ + object, + local, + uuid(a6cd7faa-b0b7-4a2f-9436-8662a65797cb) +] +interface ID3D11ClassInstance : ID3D11DeviceChild +{ + void GetClassLinkage( + [out] ID3D11ClassLinkage **ppLinkage); + void GetDesc( + [out] D3D11_CLASS_INSTANCE_DESC *pDesc); + void GetInstanceName( + [out] LPSTR pInstanceName, + [in, out] SIZE_T *pBufferLength); + void GetTypeName( + [out] LPSTR pTypeName, + [in, out] SIZE_T *pBufferLength); +} + +[ + object, + local, + uuid(ddf57cba-9543-46e4-a12b-f207a0fe7fed) +] +interface ID3D11ClassLinkage : ID3D11DeviceChild +{ + HRESULT GetClassInstance( + [in] LPCSTR pClassInstanceName, + [in] UINT InstanceIndex, + [out] ID3D11ClassInstance **ppInstance); + HRESULT CreateClassInstance( + [in] LPCSTR pClassTypeName, + [in] UINT ConstantBufferOffset, + [in] UINT ConstantVectorOffset, + [in] UINT TextureOffset, + [in] UINT SamplerOffset, + [out] ID3D11ClassInstance **ppInstance); +} + +[ + object, + local, + uuid(a24bc4d1-769e-43f7-8013-98ff566c18e2) +] +interface ID3D11CommandList : ID3D11DeviceChild +{ + UINT GetContextFlags(); +} + +[ + object, + local, + uuid(4f5b196e-c2bd-495e-bd01-1fded38e4969) +] +interface ID3D11ComputeShader : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(6e8c49fb-a371-4770-b440-29086022b741) +] +interface ID3D11Counter : ID3D11Asynchronous +{ + void GetDesc( + [out] D3D11_COUNTER_DESC *pDesc); +} + +[ + object, + local, + uuid(03823efb-8d8f-4e1c-9aa2-f64bb2cbfdf1) +] +interface ID3D11DepthStencilState : ID3D11DeviceChild +{ + void GetDesc( + [out] D3D11_DEPTH_STENCIL_DESC *pDesc); +} + +[ + object, + local, + uuid(9fdac92a-1876-48c3-afad-25b94f84a9b6) +] +interface ID3D11DepthStencilView : ID3D11View +{ + void GetDesc( + [out] D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc); +} + +[ + object, + local, + uuid(f582c508-0f36-490c-9977-31eece268cfa) +] +interface ID3D11DomainShader : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(38325b96-effb-4022-ba02-2e795b70275c) +] +interface ID3D11GeometryShader : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(8e5c6061-628a-4c8e-8264-bbe45cb3d5dd) +] +interface ID3D11HullShader : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(e4819ddc-4cf0-4025-bd26-5de82a3e07b7) +] +interface ID3D11InputLayout : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(ea82e40d-51dc-4f33-93d4-db7c9125ae8c) +] +interface ID3D11PixelShader : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(9eb576dd-9f77-4d86-81aa-8bab5fe490e2) +] +interface ID3D11Predicate : ID3D11Query +{ +} + +[ + object, + local, + uuid(9bb4ab81-ab1a-4d8f-b506-fc04200b6ee7) +] +interface ID3D11RasterizerState : ID3D11DeviceChild +{ + void GetDesc( + [out] D3D11_RASTERIZER_DESC *pDesc); +} + +[ + object, + local, + uuid(dfdba067-0b8d-4865-875b-d7b4516cc164) +] +interface ID3D11RenderTargetView : ID3D11View +{ + void GetDesc( + [out] D3D11_RENDER_TARGET_VIEW_DESC *pDesc); +} + +[ + object, + local, + uuid(da6fea51-564c-4487-9810-f0d0f9b4e3a5) +] +interface ID3D11SamplerState : ID3D11DeviceChild +{ + void GetDesc( + [out] D3D11_SAMPLER_DESC *pDesc); +} + +[ + object, + local, + uuid(b0e06fe0-8192-4e1a-b1ca-36d7414710b2) +] +interface ID3D11ShaderResourceView : ID3D11View +{ + void GetDesc( + [out] D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc); +} + +[ + object, + local, + uuid(f8fb5c27-c6b3-4f75-a4c8-439af2ef564c), +] +interface ID3D11Texture1D : ID3D11Resource +{ + void GetDesc( + [out] D3D11_TEXTURE1D_DESC *pDesc); +} + +[ + object, + local, + uuid(6f15aaf2-d208-4e89-9ab4-489535d34f9c) +] +interface ID3D11Texture2D : ID3D11Resource +{ + void GetDesc( + [out] D3D11_TEXTURE2D_DESC *pDesc); +} + +[ + object, + local, + uuid(037e866e-f56d-4357-a8af-9dabbe6e250e) +] +interface ID3D11Texture3D : ID3D11Resource +{ + void GetDesc( + [out] D3D11_TEXTURE3D_DESC *pDesc); +} + +[ + object, + local, + uuid(28acf509-7f5c-48f6-8611-f316010a6380) +] +interface ID3D11UnorderedAccessView : ID3D11View +{ + void GetDesc( + [out] D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc); +} + +[ + object, + local, + uuid(3b301d64-d678-4289-8897-22f8928b72f3) +] +interface ID3D11VertexShader : ID3D11DeviceChild +{ +} + +[ + object, + local, + uuid(c0bfa96c-e089-44fb-8eaf-26f8796190da) +] +interface ID3D11DeviceContext : ID3D11DeviceChild +{ + void VSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppConstantBuffers); + void PSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D11ShaderResourceView *const *ppShaderResourceViews); + void PSSetShader( + [in] ID3D11PixelShader *pPixelShader, + [in] ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + void PSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D11SamplerState *const *ppSamplers); + void VSSetShader( + [in] ID3D11VertexShader *pVertexShader, + [in] ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + void DrawIndexed( + [in] UINT IndexCount, + [in] UINT StartIndexLocation, + [in] INT BaseVertexLocation); + void Draw( + [in] UINT VertexCount, + [in] UINT StartVertexLocation); + HRESULT Map( + [in] ID3D11Resource *pResource, + [in] UINT Subresource, + [in] D3D11_MAP MapType, + [in] UINT MapFlags, + [out] D3D11_MAPPED_SUBRESOURCE *pMappedResource); + void Unmap( + [in] ID3D11Resource *pResource, + [in] UINT Subresource); + void PSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppConstantBuffers); + void IASetInputLayout( + [in] ID3D11InputLayout *pInputLayout); + void IASetVertexBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppVertexBuffers, + [in] const UINT *pStrides, + [in] const UINT *pOffsets); + void IASetIndexBuffer( + [in] ID3D11Buffer *pIndexBuffer, + [in] DXGI_FORMAT Format, + [in] UINT Offset); + void DrawIndexedInstanced( + [in] UINT IndexCountPerInstance, + [in] UINT InstanceCount, + [in] UINT StartIndexLocation, + [in] INT BaseVertexLocation, + [in] UINT StartInstanceLocation); + void DrawInstanced( + [in] UINT VertexCountPerInstance, + [in] UINT InstanceCount, + [in] UINT StartVertexLocation, + [in] UINT StartInstanceLocation); + void GSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppConstantBuffers); + void GSSetShader( + [in] ID3D11GeometryShader *pShader, + [in] ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + void IASetPrimitiveTopology( + [in] D3D11_PRIMITIVE_TOPOLOGY Topology); + void VSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D11ShaderResourceView *const *ppShaderResourceViews); + void VSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D11SamplerState *const *ppSamplers); + void Begin( + [in] ID3D11Asynchronous *pAsync); + void End( + [in] ID3D11Asynchronous *pAsync); + HRESULT GetData( + [in] ID3D11Asynchronous *pAsync, + [in] void *pData, + [in] UINT DataSize, + [in] UINT GetDataFlags); + void SetPredication( + [in] ID3D11Predicate *pPredicate, + [in] BOOL PredicateValue); + void GSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D11ShaderResourceView *const *ppShaderResourceViews); + void GSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D11SamplerState *const *ppSamplers); + void OMSetRenderTargets( + [in] UINT NumViews, + [in] ID3D11RenderTargetView *const *ppRenderTargetViews, + [in] ID3D11DepthStencilView *pDepthStencilView); + void OMSetRenderTargetsAndUnorderedAccessViews( + [in] UINT NumRTVs, + [in] ID3D11RenderTargetView *const *ppRenderTargetViews, + [in] ID3D11DepthStencilView *pDepthStencilView, + [in] UINT UAVStartSlot, + [in] UINT NumUAVs, + [in] ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + [in] const UINT *pUAVInitialCounts); + void OMSetBlendState( + [in] ID3D11BlendState *pBlendState, + [in] const FLOAT BlendFactor[4], + [in] UINT SampleMask); + void OMSetDepthStencilState( + [in] ID3D11DepthStencilState *pDepthStencilState, + [in] UINT StencilRef); + void SOSetTargets( + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppSOTargets, + [in] const UINT *pOffsets); + void DrawAuto(); + void DrawIndexedInstancedIndirect( + [in] ID3D11Buffer *pBufferForArgs, + [in] UINT AlignedByteOffsetForArgs); + void DrawInstancedIndirect( + [in] ID3D11Buffer *pBufferForArgs, + [in] UINT AlignedByteOffsetForArgs); + void Dispatch( + [in] UINT ThreadGroupCountX, + [in] UINT ThreadGroupCountY, + [in] UINT ThreadGroupCountZ); + void DispatchIndirect( + [in] ID3D11Buffer *pBufferForArgs, + [in] UINT AlignedByteOffsetForArgs); + void RSSetState( + [in] ID3D11RasterizerState *pRasterizerState); + void RSSetViewports( + [in] UINT NumViewports, + [in] const D3D11_VIEWPORT *pViewports); + void RSSetScissorRects( + [in] UINT NumRects, + [in] const D3D11_RECT *pRects); + void CopySubresourceRegion( + [in] ID3D11Resource *pDstResource, + [in] UINT DstSubresource, + [in] UINT DstX, + [in] UINT DstY, + [in] UINT DstZ, + [in] ID3D11Resource *pSrcResource, + [in] UINT SrcSubresource, + [in] const D3D11_BOX *pSrcBox); + void CopyResource( + [in] ID3D11Resource *pDstResource, + [in] ID3D11Resource *pSrcResource); + void UpdateSubresource( + [in] ID3D11Resource *pDstResource, + [in] UINT DstSubresource, + [in] const D3D11_BOX *pDstBox, + [in] const void *pSrcData, + [in] UINT SrcRowPitch, + [in] UINT SrcDepthPitch); + void CopyStructureCount( + [in] ID3D11Buffer *pDstBuffer, + [in] UINT DstAlignedByteOffset, + [in] ID3D11UnorderedAccessView *pSrcView); + void ClearRenderTargetView( + [in] ID3D11RenderTargetView *pRenderTargetView, + [in] const FLOAT ColorRGBA[4]); + void ClearUnorderedAccessViewUint( + [in] ID3D11UnorderedAccessView *pUnorderedAccessView, + [in] const UINT Values[4]); + void ClearUnorderedAccessViewFloat( + [in] ID3D11UnorderedAccessView *pUnorderedAccessView, + [in] const FLOAT Values[4]); + void ClearDepthStencilView( + [in] ID3D11DepthStencilView *pDepthStencilView, + [in] UINT ClearFlags, + [in] FLOAT Depth, + [in] UINT8 Stencil); + void GenerateMips( + [in] ID3D11ShaderResourceView *pShaderResourceView); + void SetResourceMinLOD( + [in] ID3D11Resource *pResource, FLOAT MinLOD); + FLOAT GetResourceMinLOD( + [in] ID3D11Resource *pResource); + void ResolveSubresource( + [in] ID3D11Resource *pDstResource, + [in] UINT DstSubresource, + [in] ID3D11Resource *pSrcResource, + [in] UINT SrcSubresource, + [in] DXGI_FORMAT Format); + void ExecuteCommandList( + [in] ID3D11CommandList *pCommandList, + BOOL RestoreContextState); + void HSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D11ShaderResourceView *const *ppShaderResourceViews); + void HSSetShader( + [in] ID3D11HullShader *pHullShader, + [in] ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + void HSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D11SamplerState *const *ppSamplers); + void HSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppConstantBuffers); + void DSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D11ShaderResourceView *const *ppShaderResourceViews); + void DSSetShader( + [in] ID3D11DomainShader *pDomainShader, + [in] ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + void DSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D11SamplerState *const *ppSamplers); + void DSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppConstantBuffers); + void CSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D11ShaderResourceView *const *ppShaderResourceViews); + void CSSetUnorderedAccessViews( + [in] UINT StartSlot, + [in] UINT NumUAVs, + [in] ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + [in] const UINT *pUAVInitialCounts); + void CSSetShader( + [in] ID3D11ComputeShader *pComputeShader, + [in] ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances); + void CSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D11SamplerState *const *ppSamplers); + void CSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D11Buffer *const *ppConstantBuffers); + void VSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppConstantBuffers); + void PSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D11ShaderResourceView **ppShaderResourceViews); + void PSGetShader( + [out] ID3D11PixelShader **ppPixelShader, + [out] ID3D11ClassInstance **ppClassInstances, + [in, out] UINT *pNumClassInstances); + void PSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D11SamplerState **ppSamplers); + void VSGetShader( + [out] ID3D11VertexShader **ppVertexShader, + [out] ID3D11ClassInstance **ppClassInstances, + [in, out] UINT *pNumClassInstances); + void PSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppConstantBuffers); + void IAGetInputLayout( + [out] ID3D11InputLayout **ppInputLayout); + void IAGetVertexBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppVertexBuffers, + [out] UINT *pStrides, + [out] UINT *pOffsets); + void IAGetIndexBuffer( + [out] ID3D11Buffer **pIndexBuffer, + [out] DXGI_FORMAT* Format, + [out] UINT* Offset); + void GSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppConstantBuffers); + void GSGetShader( + [out] ID3D11GeometryShader **ppGeometryShader, + [out] ID3D11ClassInstance **ppClassInstances, + [in, out] UINT *pNumClassInstances); + void IAGetPrimitiveTopology( + [out] D3D11_PRIMITIVE_TOPOLOGY *pTopology); + void VSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D11ShaderResourceView **ppShaderResourceViews); + void VSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D11SamplerState **ppSamplers); + void GetPredication( + [out] ID3D11Predicate **ppPredicate, + [out] BOOL *pPredicateValue); + void GSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D11ShaderResourceView **ppShaderResourceViews); + void GSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D11SamplerState **ppSamplers); + void OMGetRenderTargets( + [in] UINT NumViews, + [out] ID3D11RenderTargetView **ppRenderTargetViews, + [out] ID3D11DepthStencilView **ppDepthStencilView); + void OMGetRenderTargetsAndUnorderedAccessViews( + [in] UINT NumRTVs, + [out] ID3D11RenderTargetView **ppRenderTargetViews, + [out] ID3D11DepthStencilView **ppDepthStencilView, + [in] UINT UAVStartSlot, + [in] UINT NumUAVs, + [out] ID3D11UnorderedAccessView **ppUnorderedAccessViews); + void OMGetBlendState( + [out] ID3D11BlendState **ppBlendState, + [out] FLOAT BlendFactor[4], + [out] UINT *pSampleMask); + void OMGetDepthStencilState( + [out] ID3D11DepthStencilState **ppDepthStencilState, + [out] UINT *pStencilRef); + void SOGetTargets( + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppSOTargets); + void RSGetState( + [out] ID3D11RasterizerState **ppRasterizerState); + void RSGetViewports( + [in, out] UINT *pNumViewports, + [out] D3D11_VIEWPORT *pViewports); + void RSGetScissorRects( + [in, out] UINT *pNumRects, + [out] D3D11_RECT *pRects); + void HSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D11ShaderResourceView **ppShaderResourceViews); + void HSGetShader( + [out] ID3D11HullShader **ppHullShader, + [out] ID3D11ClassInstance **ppClassInstances, + [in, out] UINT *pNumClassInstances); + void HSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D11SamplerState **ppSamplers); + void HSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppConstantBuffers); + void DSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D11ShaderResourceView **ppShaderResourceViews); + void DSGetShader( + [out] ID3D11DomainShader **ppDomainShader, + [out] ID3D11ClassInstance **ppClassInstances, + [in, out] UINT *pNumClassInstances); + void DSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D11SamplerState **ppSamplers); + void DSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppConstantBuffers); + void CSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D11ShaderResourceView **ppShaderResourceViews); + void CSGetUnorderedAccessViews( + [in] UINT StartSlot, + [in] UINT NumUAVs, + [out] ID3D11UnorderedAccessView **ppUnorderedAccessViews); + void CSGetShader( + [out] ID3D11ComputeShader **ppComputeShader, + [out] ID3D11ClassInstance **ppClassInstances, + [in, out] UINT *pNumClassInstances); + void CSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D11SamplerState **ppSamplers); + void CSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D11Buffer **ppConstantBuffers); + void ClearState(); + void Flush(); + D3D11_DEVICE_CONTEXT_TYPE GetType(); + UINT GetContextFlags(); + HRESULT FinishCommandList( + BOOL RestoreDeferredContextState, + [out] ID3D11CommandList **ppCommandList); +} + +[ + object, + uuid(3015a308-dcbd-47aa-a747-192486d14d4a), + local, + pointer_default(unique) +] +interface ID3D11AuthenticatedChannel : ID3D11DeviceChild +{ + HRESULT GetCertificateSize( + UINT *pCertificateSize); + HRESULT GetCertificate( + UINT CertificateSize, + BYTE *pCertificate); + void GetChannelHandle( + HANDLE *pChannelHandle); +} + +[ + object, + uuid(9b32f9ad-bdcc-40a6-a39d-d5c865845720), + local, + pointer_default(unique) +] +interface ID3D11CryptoSession : ID3D11DeviceChild +{ + void GetCryptoType( + GUID *pCryptoType); + void GetDecoderProfile( + GUID *pDecoderProfile); + HRESULT GetCertificateSize( + UINT *pCertificateSize); + HRESULT GetCertificate( + UINT CertificateSize, + BYTE *pCertificate); + void GetCryptoSessionHandle( + HANDLE *pCryptoSessionHandle); +} + +[ + object, + uuid(3c9c5b51-995d-48d1-9b8d-fa5caeded65c), + local, + pointer_default(unique) +] +interface ID3D11VideoDecoder : ID3D11DeviceChild +{ + HRESULT GetCreationParameters( + D3D11_VIDEO_DECODER_DESC *pVideoDesc, + D3D11_VIDEO_DECODER_CONFIG *pConfig); + HRESULT GetDriverHandle( + HANDLE *pDriverHandle); +} + +[ + object, + uuid(31627037-53ab-4200-9061-05faa9ab45f9), + local, + pointer_default(unique) +] +interface ID3D11VideoProcessorEnumerator : ID3D11DeviceChild +{ + HRESULT GetVideoProcessorContentDesc( + D3D11_VIDEO_PROCESSOR_CONTENT_DESC *pContentDesc); + HRESULT CheckVideoProcessorFormat( + DXGI_FORMAT Format, + UINT *pFlags); + HRESULT GetVideoProcessorCaps( + D3D11_VIDEO_PROCESSOR_CAPS *pCaps); + HRESULT GetVideoProcessorRateConversionCaps( + UINT TypeIndex, + D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS *pCaps); + HRESULT GetVideoProcessorCustomRate( + UINT TypeIndex, + UINT CustomRateIndex, + D3D11_VIDEO_PROCESSOR_CUSTOM_RATE *pRate); + HRESULT GetVideoProcessorFilterRange( + D3D11_VIDEO_PROCESSOR_FILTER Filter, + D3D11_VIDEO_PROCESSOR_FILTER_RANGE *pRange); +} + +[ + object, + uuid(1d7b0652-185f-41c6-85ce-0c5be3d4ae6c), + local, + pointer_default(unique) +] +interface ID3D11VideoProcessor : ID3D11DeviceChild +{ + void GetContentDesc( + D3D11_VIDEO_PROCESSOR_CONTENT_DESC *pDesc); + void GetRateConversionCaps( + D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS *pCaps); +} + +[ + object, + uuid(c2931aea-2a85-4f20-860f-fba1fd256e18), + local, + pointer_default(unique) +] +interface ID3D11VideoDecoderOutputView : ID3D11View +{ + void GetDesc( + D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC *pDesc); +} + +[ + object, + uuid(11ec5a5f-51dc-4945-ab34-6e8c21300ea5), + local, + pointer_default(unique) +] +interface ID3D11VideoProcessorInputView : ID3D11View +{ + void GetDesc( + D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC *pDesc); +} + +[ + object, + uuid(a048285e-25a9-4527-bd93-d68b68c44254), + local, + pointer_default(unique) +] +interface ID3D11VideoProcessorOutputView : ID3D11View +{ + void GetDesc( + D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC *pDesc); +} + +[ + object, + uuid(10ec4d5b-975a-4689-b9e4-d0aac30fe333), + local, + pointer_default(unique) +] +interface ID3D11VideoDevice : IUnknown +{ + HRESULT CreateVideoDecoder( + const D3D11_VIDEO_DECODER_DESC *pVideoDesc, + const D3D11_VIDEO_DECODER_CONFIG *pConfig, + ID3D11VideoDecoder **ppDecoder); + HRESULT CreateVideoProcessor( + ID3D11VideoProcessorEnumerator *pEnum, + UINT RateConversionIndex, + ID3D11VideoProcessor **ppVideoProcessor); + HRESULT CreateAuthenticatedChannel( + D3D11_AUTHENTICATED_CHANNEL_TYPE ChannelType, + ID3D11AuthenticatedChannel **ppAuthenticatedChannel); + HRESULT CreateCryptoSession( + const GUID *pCryptoType, + const GUID *pDecoderProfile, + const GUID *pKeyExchangeType, + ID3D11CryptoSession **ppCryptoSession); + HRESULT CreateVideoDecoderOutputView( + ID3D11Resource *pResource, + const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC *pDesc, + ID3D11VideoDecoderOutputView **ppVDOVView); + HRESULT CreateVideoProcessorInputView( + ID3D11Resource *pResource, + ID3D11VideoProcessorEnumerator *pEnum, + const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC *pDesc, + ID3D11VideoProcessorInputView **ppVPIView); + HRESULT CreateVideoProcessorOutputView( + ID3D11Resource *pResource, + ID3D11VideoProcessorEnumerator *pEnum, + const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC *pDesc, + ID3D11VideoProcessorOutputView **ppVPOView); + HRESULT CreateVideoProcessorEnumerator( + const D3D11_VIDEO_PROCESSOR_CONTENT_DESC *pDesc, + ID3D11VideoProcessorEnumerator **ppEnum); + UINT GetVideoDecoderProfileCount(); + HRESULT GetVideoDecoderProfile( + UINT Index, + GUID *pDecoderProfile); + HRESULT CheckVideoDecoderFormat( + const GUID *pDecoderProfile, + DXGI_FORMAT Format, + BOOL *pSupported); + HRESULT GetVideoDecoderConfigCount( + const D3D11_VIDEO_DECODER_DESC *pDesc, + UINT *pCount); + HRESULT GetVideoDecoderConfig( + const D3D11_VIDEO_DECODER_DESC *pDesc, + UINT Index, + D3D11_VIDEO_DECODER_CONFIG *pConfig); + HRESULT GetContentProtectionCaps( + const GUID *pCryptoType, + const GUID *pDecoderProfile, + D3D11_VIDEO_CONTENT_PROTECTION_CAPS *pCaps); + HRESULT CheckCryptoKeyExchange( + const GUID *pCryptoType, + const GUID *pDecoderProfile, + UINT Index, + GUID *pKeyExchangeType); + HRESULT SetPrivateData( + REFGUID guid, + UINT DataSize, + const void *pData); + HRESULT SetPrivateDataInterface( + REFGUID guid, + const IUnknown *pData); +} + +[ + object, + uuid(61f21c45-3c0e-4a74-9cea-67100d9ad5e4), + local, + pointer_default(unique) +] +interface ID3D11VideoContext : ID3D11DeviceChild +{ + HRESULT GetDecoderBuffer( + [in] ID3D11VideoDecoder *decoder, + [in] D3D11_VIDEO_DECODER_BUFFER_TYPE type, + [out] UINT *buffer_size, + [out] void **buffer + ); + HRESULT ReleaseDecoderBuffer( + [in] ID3D11VideoDecoder *decoder, + [in] D3D11_VIDEO_DECODER_BUFFER_TYPE type + ); + HRESULT DecoderBeginFrame( + [in] ID3D11VideoDecoder *decoder, + [in] ID3D11VideoDecoderOutputView *view, + [in] UINT key_size, + [in] const void *key + ); + HRESULT DecoderEndFrame( + [in] ID3D11VideoDecoder *decoder + ); + HRESULT SubmitDecoderBuffers( + [in] ID3D11VideoDecoder *decoder, + [in] UINT buffers_count, + [in] const D3D11_VIDEO_DECODER_BUFFER_DESC *buffer_desc + ); + HRESULT DecoderExtension( + [in] ID3D11VideoDecoder *decoder, + [in] const D3D11_VIDEO_DECODER_EXTENSION *extension + ); + void VideoProcessorSetOutputTargetRect( + [in] ID3D11VideoProcessor *processor, + [in] BOOL enable, + [in] const RECT *rect + ); + void VideoProcessorSetOutputBackgroundColor( + [in] ID3D11VideoProcessor *processor, + [in] BOOL y_cb_cr, + [in] const D3D11_VIDEO_COLOR *color + ); + void VideoProcessorSetOutputColorSpace( + [in] ID3D11VideoProcessor *processor, + [in] const D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorSetOutputAlphaFillMode( + [in] ID3D11VideoProcessor *processor, + [in] D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE alpha_fill_mode, + [in] UINT stream_idx + ); + void VideoProcessorSetOutputConstriction( + [in] ID3D11VideoProcessor *processor, + [in] BOOL enable, + [in] SIZE size + ); + void VideoProcessorSetOutputStereoMode( + [in] ID3D11VideoProcessor *processor, + [in] BOOL enable + ); + HRESULT VideoProcessorSetOutputExtension( + [in] ID3D11VideoProcessor *processor, + [in] const GUID *guid, + [in] UINT data_size, + [in] void *data + ); + void VideoProcessorGetOutputTargetRect( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *enabled, + [out] RECT *rect + ); + void VideoProcessorGetOutputBackgroundColor( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *y_cb_cr, + [out] D3D11_VIDEO_COLOR *color + ); + void VideoProcessorGetOutputColorSpace( + [in] ID3D11VideoProcessor *processor, + [out] D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorGetOutputAlphaFillMode( + [in] ID3D11VideoProcessor *processor, + [out] D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE *alpha_fill_mode, + [out] UINT *stream_idx + ); + void VideoProcessorGetOutputConstriction( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *enabled, + [out] SIZE *size + ); + void VideoProcessorGetOutputStereoMode( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *enabled + ); + HRESULT VideoProcessorGetOutputExtension( + [in] ID3D11VideoProcessor *processor, + [in] const GUID *guid, + [in] UINT data_size, + [out] void *data + ); + void VideoProcessorSetStreamFrameFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_FRAME_FORMAT format + ); + void VideoProcessorSetStreamColorSpace( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] const D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorSetStreamOutputRate( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_PROCESSOR_OUTPUT_RATE rate, + [in] BOOL repeat, + [in] const DXGI_RATIONAL *custom_rate + ); + void VideoProcessorSetStreamSourceRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] const RECT *rect + ); + void VideoProcessorSetStreamDestRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] const RECT *rect + ); + void VideoProcessorSetStreamAlpha( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] float alpha + ); + void VideoProcessorSetStreamPalette( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] UINT entry_count, + [in] const UINT *entries + ); + void VideoProcessorSetStreamPixelAspectRatio( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] const DXGI_RATIONAL *src_aspect_ratio, + [in] const DXGI_RATIONAL *dst_aspect_ratio + ); + void VideoProcessorSetStreamLumaKey( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] float lower, + [in] float upper + ); + void VideoProcessorSetStreamStereoFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] D3D11_VIDEO_PROCESSOR_STEREO_FORMAT format, + [in] BOOL left_view_frame0, + [in] BOOL base_view_frame0, + [in] D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE flip_mode, + [in] int mono_offset + ); + void VideoProcessorSetStreamAutoProcessingMode( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable + ); + void VideoProcessorSetStreamFilter( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_PROCESSOR_FILTER filter, + [in] BOOL enable, + [in] int level + ); + HRESULT VideoProcessorSetStreamExtension( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] const GUID *guid, + [in] UINT data_size, + [in] void *data + ); + void VideoProcessorGetStreamFrameFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] D3D11_VIDEO_FRAME_FORMAT *format + ); + void VideoProcessorGetStreamColorSpace( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorGetStreamOutputRate( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] D3D11_VIDEO_PROCESSOR_OUTPUT_RATE *rate, + [out] BOOL *repeat, + [out] DXGI_RATIONAL *custom_rate + ); + void VideoProcessorGetStreamSourceRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] RECT *rect + ); + void VideoProcessorGetStreamDestRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] RECT *rect + ); + void VideoProcessorGetStreamAlpha( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] float *alpha + ); + void VideoProcessorGetStreamPalette( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] UINT entry_count, + [out] UINT *entries + ); + void VideoProcessorGetStreamPixelAspectRatio( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] DXGI_RATIONAL *src_aspect_ratio, + [out] DXGI_RATIONAL *dst_aspect_ratio + ); + void VideoProcessorGetStreamLumaKey( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] float *lower, + [out] float *upper + ); + void VideoProcessorGetStreamStereoFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] D3D11_VIDEO_PROCESSOR_STEREO_FORMAT *format, + [out] BOOL *left_view_frame0, + [out] BOOL *base_view_frame0, + [out] D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE *flip_mode, + [out] int *mono_offset + ); + void VideoProcessorGetStreamAutoProcessingMode( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled + ); + void VideoProcessorGetStreamFilter( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_PROCESSOR_FILTER filter, + [out] BOOL *enabled, + [out] int *level + ); + HRESULT VideoProcessorGetStreamExtension( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] const GUID *guid, + [in] UINT data_size, + [out] void *data + ); + HRESULT VideoProcessorBlt( + [in] ID3D11VideoProcessor *processor, + [in] ID3D11VideoProcessorOutputView *view, + [in] UINT frame_idx, + [in] UINT stream_count, + [in] const D3D11_VIDEO_PROCESSOR_STREAM *streams + ); + HRESULT NegotiateCryptoSessionKeyExchange( + [in] ID3D11CryptoSession *session, + [in] UINT data_size, + [in, out] void *data + ); + void EncryptionBlt( + [in] ID3D11CryptoSession *session, + [in] ID3D11Texture2D *src_surface, + [in] ID3D11Texture2D *dst_surface, + [in] UINT iv_size, + [in, out] void *iv + ); + void DecryptionBlt( + [in] ID3D11CryptoSession *session, + [in] ID3D11Texture2D *src_surface, + [in] ID3D11Texture2D *dst_surface, + [in] D3D11_ENCRYPTED_BLOCK_INFO *block_info, + [in] UINT key_size, + [in] const void *key, + [in] UINT iv_size, + [in, out] void *iv + ); + void StartSessionKeyRefresh( + [in] ID3D11CryptoSession *session, + [in] UINT random_number_size, + [out] void *random_number + ); + void FinishSessionKeyRefresh( + [in] ID3D11CryptoSession *session + ); + HRESULT GetEncryptionBltKey( + [in] ID3D11CryptoSession *session, + [in] UINT key_size, + [out] void *key + ); + HRESULT NegotiateAuthenticatedChannelKeyExchange( + [in] ID3D11AuthenticatedChannel *channel, + [in] UINT data_size, + [in, out] void *data + ); + HRESULT QueryAuthenticatedChannel( + [in] ID3D11AuthenticatedChannel *channel, + [in] UINT input_size, + [in] const void *input, + [in] UINT output_size, + [out] void *output + ); + HRESULT ConfigureAuthenticatedChannel( + [in] ID3D11AuthenticatedChannel *channel, + [in] UINT input_size, + [in] const void *input, + [out] D3D11_AUTHENTICATED_CONFIGURE_OUTPUT *output + ); + void VideoProcessorSetStreamRotation( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] D3D11_VIDEO_PROCESSOR_ROTATION rotation + ); + void VideoProcessorGetStreamRotation( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enable, + [out] D3D11_VIDEO_PROCESSOR_ROTATION *rotation + ); +} + +[ + object, + local, + uuid(db6f6ddb-ac77-4e88-8253-819df9bbf140) +] +interface ID3D11Device : IUnknown +{ + HRESULT CreateBuffer( + [in] const D3D11_BUFFER_DESC *pDesc, + [in] const D3D11_SUBRESOURCE_DATA *pInitialData, + [out] ID3D11Buffer **ppBuffer); + HRESULT CreateTexture1D( + [in] const D3D11_TEXTURE1D_DESC *pDesc, + [in] const D3D11_SUBRESOURCE_DATA *pInitialData, + [out] ID3D11Texture1D **ppTexture1D); + HRESULT CreateTexture2D( + [in] const D3D11_TEXTURE2D_DESC *pDesc, + [in] const D3D11_SUBRESOURCE_DATA *pInitialData, + [out] ID3D11Texture2D **ppTexture2D); + HRESULT CreateTexture3D( + [in] const D3D11_TEXTURE3D_DESC *pDesc, + [in] const D3D11_SUBRESOURCE_DATA *pInitialData, + [out] ID3D11Texture3D **ppTexture3D); + HRESULT CreateShaderResourceView( + [in] ID3D11Resource *pResource, + [in] const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + [out] ID3D11ShaderResourceView **ppSRView); + HRESULT CreateUnorderedAccessView( + [in] ID3D11Resource *pResource, + [in] const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, + [out] ID3D11UnorderedAccessView **ppUAView); + HRESULT CreateRenderTargetView( + [in] ID3D11Resource *pResource, + [in] const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, + [out] ID3D11RenderTargetView **ppRTView); + HRESULT CreateDepthStencilView( + [in] ID3D11Resource *pResource, + [in] const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, + [out] ID3D11DepthStencilView **ppDepthStencilView); + HRESULT CreateInputLayout( + [in] const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, + [in] UINT NumElements, + [in] const void *pShaderBytecodeWithInputSignature, + [in] SIZE_T BytecodeLength, + [out] ID3D11InputLayout **ppInputLayout); + HRESULT CreateVertexShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11VertexShader **ppVertexShader); + HRESULT CreateGeometryShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11GeometryShader **ppGeometryShader); + HRESULT CreateGeometryShaderWithStreamOutput( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, + [in] UINT NumEntries, + [in] const UINT *pBufferStrides, + [in] UINT NumStrides, + [in] UINT RasterizedStream, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11GeometryShader **ppGeometryShader); + HRESULT CreatePixelShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11PixelShader **ppPixelShader); + HRESULT CreateHullShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11HullShader **ppHullShader); + HRESULT CreateDomainShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11DomainShader **ppDomainShader); + HRESULT CreateComputeShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] ID3D11ClassLinkage *pClassLinkage, + [out] ID3D11ComputeShader **ppComputeShader); + HRESULT CreateClassLinkage( + [out] ID3D11ClassLinkage **ppLinkage); + HRESULT CreateBlendState( + [in] const D3D11_BLEND_DESC *pBlendStateDesc, + [out] ID3D11BlendState **ppBlendState); + HRESULT CreateDepthStencilState( + [in] const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, + [out] ID3D11DepthStencilState **ppDepthStencilState); + HRESULT CreateRasterizerState( + [in] const D3D11_RASTERIZER_DESC *pRasterizerDesc, + [out] ID3D11RasterizerState **ppRasterizerState); + HRESULT CreateSamplerState( + [in] const D3D11_SAMPLER_DESC *pSamplerDesc, + [out] ID3D11SamplerState **ppSamplerState); + HRESULT CreateQuery( + [in] const D3D11_QUERY_DESC *pQueryDesc, + [out] ID3D11Query **ppQuery); + HRESULT CreatePredicate( + [in] const D3D11_QUERY_DESC *pPredicateDesc, + [out] ID3D11Predicate **ppPredicate); + HRESULT CreateCounter( + [in] const D3D11_COUNTER_DESC *pCounterDesc, + [out] ID3D11Counter **ppCounter); + HRESULT CreateDeferredContext( + UINT ContextFlags, + [out] ID3D11DeviceContext **ppDeferredContext); + HRESULT OpenSharedResource( + [in] HANDLE hResource, + [in] REFIID ReturnedInterface, + [out] void **ppResource); + HRESULT CheckFormatSupport( + [in] DXGI_FORMAT Format, + [out] UINT *pFormatSupport); + HRESULT CheckMultisampleQualityLevels( + [in] DXGI_FORMAT Format, + [in] UINT SampleCount, + [out] UINT *pNumQualityLevels); + void CheckCounterInfo( + [out] D3D11_COUNTER_INFO *pCounterInfo); + HRESULT CheckCounter( + [in] const D3D11_COUNTER_DESC *pDesc, + [out] D3D11_COUNTER_TYPE *pType, + [out] UINT *pActiveCounters, + [out] LPSTR szName, + [in, out] UINT *pNameLength, + [out] LPSTR szUnits, + [in, out] UINT *pUnitsLength, + [out] LPSTR szDescription, + [in, out] UINT *pDescriptionLength); + HRESULT CheckFeatureSupport( + D3D11_FEATURE Feature, + [out] void *pFeatureSupportData, + UINT FeatureSupportDataSize); + HRESULT GetPrivateData( + [in] REFGUID guid, + [in, out] UINT *pDataSize, + [out] void *pData); + HRESULT SetPrivateData( + [in] REFGUID guid, + [in] UINT DataSize, + [in] const void *pData); + HRESULT SetPrivateDataInterface( + [in] REFGUID guid, + [in] const IUnknown *pData); + D3D_FEATURE_LEVEL GetFeatureLevel(); + UINT GetCreationFlags(); + HRESULT GetDeviceRemovedReason(); + void GetImmediateContext( + [out] ID3D11DeviceContext **ppImmediateContext); + HRESULT SetExceptionMode(UINT RaiseFlags); + UINT GetExceptionMode(); +} + +typedef enum D3D11_CREATE_DEVICE_FLAG { + D3D11_CREATE_DEVICE_SINGLETHREADED = 0x0001, + D3D11_CREATE_DEVICE_DEBUG = 0x0002, + D3D11_CREATE_DEVICE_SWITCH_TO_REF = 0x0004, + D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 0x0008, + D3D11_CREATE_DEVICE_BGRA_SUPPORT = 0x0020, + D3D11_CREATE_DEVICE_DEBUGGABLE = 0x0040, + D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY = 0x0080, + D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT = 0x0100, + D3D11_CREATE_DEVICE_VIDEO_SUPPORT = 0x0800 +} D3D11_CREATE_DEVICE_FLAG; + +const UINT D3D11_SDK_VERSION = 7; + +cpp_quote("#include ") +cpp_quote("#ifndef D3D11_IGNORE_SDK_LAYERS") +cpp_quote("# include ") +cpp_quote("#endif") +cpp_quote("#include ") +cpp_quote("#include ") +cpp_quote("#include ") +cpp_quote("#include ") + +const UINT _FACD3D11 = 0x87c; +cpp_quote("#define MAKE_D3D11_HRESULT(code) MAKE_HRESULT(SEVERITY_ERROR, _FACD3D11, code)") + +cpp_quote("typedef HRESULT (WINAPI* PFN_D3D11_CREATE_DEVICE)(IDXGIAdapter*,D3D_DRIVER_TYPE,HMODULE,UINT,") +cpp_quote(" const D3D_FEATURE_LEVEL*,UINT,UINT,ID3D11Device**,D3D_FEATURE_LEVEL*,ID3D11DeviceContext**);") + +cpp_quote("HRESULT WINAPI D3D11CreateDevice(IDXGIAdapter*,D3D_DRIVER_TYPE,HMODULE,UINT,const D3D_FEATURE_LEVEL*," ) +cpp_quote(" UINT,UINT,ID3D11Device**,D3D_FEATURE_LEVEL*,ID3D11DeviceContext**);") + +cpp_quote("typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)(IDXGIAdapter*,D3D_DRIVER_TYPE,HMODULE,UINT,") +cpp_quote(" const D3D_FEATURE_LEVEL*,UINT,UINT,const DXGI_SWAP_CHAIN_DESC*,IDXGISwapChain**,ID3D11Device**,") +cpp_quote(" D3D_FEATURE_LEVEL*,ID3D11DeviceContext**);") + +[local] HRESULT __stdcall D3D11CreateDeviceAndSwapChain(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, + const DXGI_SWAP_CHAIN_DESC *swapchain_desc, IDXGISwapChain **swapchain, ID3D11Device **device, + D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context); diff --git a/sdk/include/psdk/d3d11_1.idl b/sdk/include/psdk/d3d11_1.idl new file mode 100644 index 00000000000..4fd82f002ba --- /dev/null +++ b/sdk/include/psdk/d3d11_1.idl @@ -0,0 +1,547 @@ +/* + * Copyright 2014 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi1_2.idl"; +import "d3dcommon.idl"; +import "d3d11.idl"; + +typedef enum D3D11_LOGIC_OP +{ + D3D11_LOGIC_OP_CLEAR = 0, + D3D11_LOGIC_OP_SET, + D3D11_LOGIC_OP_COPY, + D3D11_LOGIC_OP_COPY_INVERTED, + D3D11_LOGIC_OP_NOOP, + D3D11_LOGIC_OP_INVERT, + D3D11_LOGIC_OP_AND, + D3D11_LOGIC_OP_NAND, + D3D11_LOGIC_OP_OR, + D3D11_LOGIC_OP_NOR, + D3D11_LOGIC_OP_XOR, + D3D11_LOGIC_OP_EQUIV, + D3D11_LOGIC_OP_AND_REVERSE, + D3D11_LOGIC_OP_AND_INVERTED, + D3D11_LOGIC_OP_OR_REVERSE, + D3D11_LOGIC_OP_OR_INVERTED +} D3D11_LOGIC_OP; + +typedef enum D3D11_COPY_FLAGS +{ + D3D11_COPY_NO_OVERWRITE = 0x00000001, + D3D11_COPY_DISCARD = 0x00000002, +} D3D11_COPY_FLAGS; + +typedef enum D3D11_1_CREATE_DEVICE_CONTEXT_STATE_FLAG +{ + D3D11_1_CREATE_DEVICE_CONTEXT_STATE_SINGLETHREADED = 0x1, +} D3D11_1_CREATE_DEVICE_CONTEXT_STATE_FLAG; + +typedef enum D3D11_VIDEO_DECODER_CAPS +{ + D3D11_VIDEO_DECODER_CAPS_DOWNSAMPLE = 0x01, + D3D11_VIDEO_DECODER_CAPS_NON_REAL_TIME = 0x02, + D3D11_VIDEO_DECODER_CAPS_DOWNSAMPLE_DYNAMIC = 0x04, + D3D11_VIDEO_DECODER_CAPS_DOWNSAMPLE_REQUIRED = 0x08, + D3D11_VIDEO_DECODER_CAPS_UNSUPPORTED = 0x10, +} D3D11_VIDEO_DECODER_CAPS; + +typedef enum D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINTS +{ + D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_MULTIPLANE_OVERLAY_ROTATION = 0x01, + D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_MULTIPLANE_OVERLAY_RESIZE = 0x02, + D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_MULTIPLANE_OVERLAY_COLOR_SPACE_CONVERSION = 0x04, + D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINT_TRIPLE_BUFFER_OUTPUT = 0x08, +} D3D11_VIDEO_PROCESSOR_BEHAVIOR_HINTS; + +typedef enum D3D11_CRYPTO_SESSION_STATUS +{ + D3D11_CRYPTO_SESSION_STATUS_OK = 0x0, + D3D11_CRYPTO_SESSION_STATUS_KEY_LOST = 0x1, + D3D11_CRYPTO_SESSION_STATUS_KEY_AND_CONTENT_LOST = 0x2, +} D3D11_CRYPTO_SESSION_STATUS; + +typedef struct D3D11_RENDER_TARGET_BLEND_DESC1 +{ + BOOL BlendEnable; + BOOL LogicOpEnable; + D3D11_BLEND SrcBlend; + D3D11_BLEND DestBlend; + D3D11_BLEND_OP BlendOp; + D3D11_BLEND SrcBlendAlpha; + D3D11_BLEND DestBlendAlpha; + D3D11_BLEND_OP BlendOpAlpha; + D3D11_LOGIC_OP LogicOp; + UINT8 RenderTargetWriteMask; +} D3D11_RENDER_TARGET_BLEND_DESC1; + +typedef struct D3D11_BLEND_DESC1 +{ + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D11_RENDER_TARGET_BLEND_DESC1 RenderTarget[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; +} D3D11_BLEND_DESC1; + +typedef struct D3D11_RASTERIZER_DESC1 +{ + D3D11_FILL_MODE FillMode; + D3D11_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL ScissorEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; + UINT ForcedSampleCount; +} D3D11_RASTERIZER_DESC1; + +typedef struct D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK +{ + UINT ClearSize; + UINT EncryptedSize; +} D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK; + +typedef struct D3D11_VIDEO_DECODER_BUFFER_DESC1 +{ + D3D11_VIDEO_DECODER_BUFFER_TYPE BufferType; + UINT DataOffset; + UINT DataSize; + void *pIV; + UINT IVSize; + D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK *pSubSampleMappingBlock; + UINT SubSampleMappingCount; +} D3D11_VIDEO_DECODER_BUFFER_DESC1; + +typedef struct D3D11_VIDEO_DECODER_BEGIN_FRAME_CRYPTO_SESSION +{ + ID3D11CryptoSession *pCryptoSession; + UINT BlobSize; + void *pBlob; + GUID *pKeyInfoId; + UINT PrivateDataSize; + void *pPrivateData; +} D3D11_VIDEO_DECODER_BEGIN_FRAME_CRYPTO_SESSION; + +typedef struct D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT +{ + BOOL Enable; + UINT Width; + UINT Height; + DXGI_FORMAT Format; +} D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT; + +typedef struct D3D11_KEY_EXCHANGE_HW_PROTECTION_INPUT_DATA +{ + UINT PrivateDataSize; + UINT HWProtectionDataSize; + BYTE pbInput[4]; +} D3D11_KEY_EXCHANGE_HW_PROTECTION_INPUT_DATA; + +typedef struct D3D11_KEY_EXCHANGE_HW_PROTECTION_OUTPUT_DATA +{ + UINT PrivateDataSize; + UINT MaxHWProtectionDataSize; + UINT HWProtectionDataSize; + UINT64 TransportTime; + UINT64 ExecutionTime; + BYTE pbOutput[4]; +} D3D11_KEY_EXCHANGE_HW_PROTECTION_OUTPUT_DATA; + +typedef struct D3D11_KEY_EXCHANGE_HW_PROTECTION_DATA +{ + UINT HWProtectionFunctionID; + D3D11_KEY_EXCHANGE_HW_PROTECTION_INPUT_DATA *pInputData; + D3D11_KEY_EXCHANGE_HW_PROTECTION_OUTPUT_DATA *pOutputData; + HRESULT Status; +} D3D11_KEY_EXCHANGE_HW_PROTECTION_DATA; + +typedef struct D3D11_VIDEO_SAMPLE_DESC +{ + UINT Width; + UINT Height; + DXGI_FORMAT Format; + DXGI_COLOR_SPACE_TYPE ColorSpace; +} D3D11_VIDEO_SAMPLE_DESC; + +[ + uuid(cc86fabe-da55-401d-85e7-e3c9de2877e9), + object, + local, + pointer_default(unique) +] +interface ID3D11BlendState1 : ID3D11BlendState +{ + void GetDesc1(D3D11_BLEND_DESC1 *pDesc); +} + +[ + uuid(5c1e0d8a-7c23-48f9-8c59-a92958ceff11), + object, + local, + pointer_default(unique) +] +interface ID3DDeviceContextState : ID3D11DeviceChild +{ +} + +[ + uuid(bb2c6faa-b5fb-4082-8e6b-388b8cfa90e1), + object, + local, + pointer_default(unique) +] +interface ID3D11DeviceContext1 : ID3D11DeviceContext +{ + void CopySubresourceRegion1( + ID3D11Resource *pDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + ID3D11Resource *pSrcResource, + UINT SrcSubresource, + const D3D11_BOX *pSrcBox, + UINT CopyFlags); + + void UpdateSubresource1( + ID3D11Resource *pDstResource, + UINT DstSubresource, + const D3D11_BOX *pDstBox, + const void *pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch, + UINT CopyFlags); + + void DiscardResource(ID3D11Resource *pResource); + + void DiscardView(ID3D11View *pResourceView); + + void VSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants); + + void HSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants); + + void DSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants); + + void GSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants); + + void PSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants); + + void CSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants); + + void VSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, + UINT *pNumConstants); + + void HSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, + UINT *pNumConstants); + + void DSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, + UINT *pNumConstants); + + void GSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, + UINT *pNumConstants); + + void PSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, + UINT *pNumConstants); + + void CSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, + UINT *pNumConstants); + + void SwapDeviceContextState( + ID3DDeviceContextState *pState, + ID3DDeviceContextState **ppPreviousState); + + void ClearView( + ID3D11View *pView, + const FLOAT Color[4], + const D3D11_RECT *pRect, + UINT NumRects); + + void DiscardView1( + ID3D11View *pResourceView, + const D3D11_RECT *pRects, + UINT NumRects); +} + +[ + uuid(a7f026da-a5f8-4487-a564-15e34357651e), + object, + local, + pointer_default(unique) +] +interface ID3D11VideoContext1 : ID3D11VideoContext +{ + HRESULT SubmitDecoderBuffers1( + ID3D11VideoDecoder *decoder, + UINT buffer_count, + const D3D11_VIDEO_DECODER_BUFFER_DESC1 *buffer_desc + ); + HRESULT GetDataForNewHardwareKey( + ID3D11CryptoSession *session, + UINT input_size, + const void *input_data, + UINT64 *output_data + ); + HRESULT CheckCryptoSessionStatus( + ID3D11CryptoSession *session, + D3D11_CRYPTO_SESSION_STATUS *status + ); + HRESULT DecoderEnableDownsampling( + ID3D11VideoDecoder *decoder, + DXGI_COLOR_SPACE_TYPE colour_space, + const D3D11_VIDEO_SAMPLE_DESC *output_desc, + UINT reference_frame_count + ); + HRESULT DecoderUpdateDownsampling( + ID3D11VideoDecoder *decoder, + const D3D11_VIDEO_SAMPLE_DESC *output_desc + ); + void VideoProcessorSetOutputColorSpace1( + ID3D11VideoProcessor *processor, + DXGI_COLOR_SPACE_TYPE colour_space + ); + void VideoProcessorSetOutputShaderUsage( + ID3D11VideoProcessor *processor, + BOOL shader_usage + ); + void VideoProcessorGetOutputColorSpace1( + ID3D11VideoProcessor *processor, + DXGI_COLOR_SPACE_TYPE *colour_space + ); + void VideoProcessorGetOutputShaderUsage( + ID3D11VideoProcessor *processor, + BOOL *shader_usage + ); + void VideoProcessorSetStreamColorSpace1( + ID3D11VideoProcessor *processor, + UINT stream_index, + DXGI_COLOR_SPACE_TYPE colour_space + ); + void VideoProcessorSetStreamMirror( + ID3D11VideoProcessor *processor, + UINT stream_index, + BOOL enable, + BOOL flip_horizontal, + BOOL flip_vertical + ); + void VideoProcessorGetStreamColorSpace1( + ID3D11VideoProcessor *processor, + UINT stream_index, + DXGI_COLOR_SPACE_TYPE *colour_space + ); + void VideoProcessorGetStreamMirror( + ID3D11VideoProcessor *processor, + UINT stream_index, + BOOL *enable, + BOOL *flip_horizontal, + BOOL *flip_vertical + ); + HRESULT VideoProcessorGetBehaviorHints( + ID3D11VideoProcessor *processor, + UINT output_width, + UINT output_height, + DXGI_FORMAT output_format, + UINT stream_count, + const D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT *streams, + UINT *behaviour_hints + ); +} + +[ + uuid(29da1d51-1321-4454-804b-f5fc9f861f0f), + object, + local, + pointer_default(unique) +] +interface ID3D11VideoDevice1 : ID3D11VideoDevice +{ + HRESULT GetCryptoSessionPrivateDataSize( + const GUID *crypto_type, + const GUID *decoder_profile, + const GUID *key_exchange_type, + UINT *input_size, + UINT *output_size + ); + HRESULT GetVideoDecoderCaps( + const GUID *decoder_profile, + UINT sample_width, + UINT sample_height, + const DXGI_RATIONAL *framerate, + UINT bitrate, + const GUID *crypto_type, + UINT *decoder_caps + ); + HRESULT CheckVideoDecoderDownsampling( + const D3D11_VIDEO_DECODER_DESC *input_desc, + DXGI_COLOR_SPACE_TYPE input_colour_space, + const D3D11_VIDEO_DECODER_CONFIG *input_config, + const DXGI_RATIONAL *framerate, + const D3D11_VIDEO_SAMPLE_DESC *output_desc, + BOOL *supported, + BOOL *real_time_hint + ); + HRESULT RecommendVideoDecoderDownsampleParameters( + const D3D11_VIDEO_DECODER_DESC *input_desc, + DXGI_COLOR_SPACE_TYPE input_colour_space, + const D3D11_VIDEO_DECODER_CONFIG *input_config, + const DXGI_RATIONAL *framerate, + D3D11_VIDEO_SAMPLE_DESC *recommended_output_desc + ); +} + +[ + uuid(465217f2-5568-43cf-b5b9-f61d54531ca1), + object, + local, + pointer_default(unique) +] +interface ID3D11VideoProcessorEnumerator1 : ID3D11VideoProcessorEnumerator +{ + HRESULT CheckVideoProcessorFormatConversion( + DXGI_FORMAT input_format, + DXGI_COLOR_SPACE_TYPE input_colour_space, + DXGI_FORMAT output_format, + DXGI_COLOR_SPACE_TYPE output_colour_space, + BOOL *supported + ); +} + +[ + uuid(b2daad8b-03d4-4dbf-95eb-32ab4b63d0ab), + object, + local, + pointer_default(unique) +] +interface ID3DUserDefinedAnnotation : IUnknown +{ + INT BeginEvent(LPCWSTR Name); + INT EndEvent(); + void SetMarker(LPCWSTR Name); + BOOL GetStatus(); +} + +[ + uuid(1217d7a6-5039-418c-b042-9cbe256afd6e), + object, + local, + pointer_default(unique) +] +interface ID3D11RasterizerState1 : ID3D11RasterizerState +{ + void GetDesc1(D3D11_RASTERIZER_DESC1 *pDesc); +} + +[ + uuid(a04bfb29-08ef-43d6-a49c-a9bdbdcbe686), + object, + local, + pointer_default(unique) +] +interface ID3D11Device1 : ID3D11Device +{ + void GetImmediateContext1( + ID3D11DeviceContext1 **ppImmediateContext); + + HRESULT CreateDeferredContext1( + UINT ContextFlags, + ID3D11DeviceContext1 **ppDeferredContext); + + HRESULT CreateBlendState1( + const D3D11_BLEND_DESC1 *pBlendStateDesc, + ID3D11BlendState1 **ppBlendState); + + HRESULT CreateRasterizerState1( + const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, + ID3D11RasterizerState1 **ppRasterizerState); + + HRESULT CreateDeviceContextState( + UINT Flags, + const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + REFIID EmulatedInterface, + D3D_FEATURE_LEVEL *pChosenFeatureLevel, + ID3DDeviceContextState **ppContextState); + + HRESULT OpenSharedResource1( + HANDLE hResource, + REFIID returnedInterface, + void **ppResource); + + HRESULT OpenSharedResourceByName( + LPCWSTR lpName, + DWORD dwDesiredAccess, + REFIID returnedInterface, + void **ppResource); +} diff --git a/sdk/include/psdk/d3d11_2.idl b/sdk/include/psdk/d3d11_2.idl new file mode 100644 index 00000000000..bb4db021879 --- /dev/null +++ b/sdk/include/psdk/d3d11_2.idl @@ -0,0 +1,173 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi1_3.idl"; +import "d3dcommon.idl"; +import "d3d11_1.idl"; + +const UINT D3D11_PACKED_TILE = 0xffffffff; + +typedef enum D3D11_TILE_MAPPING_FLAG +{ + D3D11_TILE_MAPPING_NO_OVERWRITE = 0x1, +} D3D11_TILE_MAPPING_FLAG; + +typedef enum D3D11_TILE_RANGE_FLAG +{ + D3D11_TILE_RANGE_NULL = 0x1, + D3D11_TILE_RANGE_SKIP = 0x2, + D3D11_TILE_RANGE_REUSE_SINGLE_TILE = 0x4, +} D3D11_TILE_RANGE_FLAG; + +typedef enum D3D11_CHECK_MULTISAMPLE_QUALITY_LEVELS_FLAG +{ + D3D11_CHECK_MULTISAMPLE_QUALITY_LEVELS_TILED_RESOURCE = 0x1, +} D3D11_CHECK_MULTISAMPLE_QUALITY_LEVELS_FLAG; + +typedef enum D3D11_TILE_COPY_FLAG +{ + D3D11_TILE_COPY_NO_OVERWRITE = 0x1, + D3D11_TILE_COPY_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2, + D3D11_TILE_COPY_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4, +} D3D11_TILE_COPY_FLAG; + +typedef struct D3D11_TILED_RESOURCE_COORDINATE +{ + UINT X; + UINT Y; + UINT Z; + UINT Subresource; +} D3D11_TILED_RESOURCE_COORDINATE; + +typedef struct D3D11_TILE_REGION_SIZE +{ + UINT NumTiles; + BOOL bUseBox; + UINT Width; + UINT16 Height; + UINT16 Depth; +} D3D11_TILE_REGION_SIZE; + +typedef struct D3D11_SUBRESOURCE_TILING +{ + UINT WidthInTiles; + UINT16 HeightInTiles; + UINT16 DepthInTiles; + UINT StartTileIndexInOverallResource; +} D3D11_SUBRESOURCE_TILING; + +typedef struct D3D11_TILE_SHAPE +{ + UINT WidthInTexels; + UINT HeightInTexels; + UINT DepthInTexels; +} D3D11_TILE_SHAPE; + +typedef struct D3D11_PACKED_MIP_DESC +{ + UINT8 NumStandardMips; + UINT8 NumPackedMips; + UINT NumTilesForPackedMips; + UINT StartTileIndexInOverallResource; +} D3D11_PACKED_MIP_DESC; + +[ + uuid(420d5b32-b90c-4da4-bef0-359f6a24a83a), + object, + local, + pointer_default(unique) +] +interface ID3D11DeviceContext2 : ID3D11DeviceContext1 +{ + HRESULT UpdateTileMappings( + ID3D11Resource *resource, + UINT region_count, + const D3D11_TILED_RESOURCE_COORDINATE *region_start_coordinates, + const D3D11_TILE_REGION_SIZE *region_sizes, + ID3D11Buffer *pool, + UINT range_count, + const UINT *range_flags, + const UINT *pool_start_offsets, + const UINT *range_tile_counts, + UINT flags + ); + HRESULT CopyTileMappings( + ID3D11Resource *dst_resource, + const D3D11_TILED_RESOURCE_COORDINATE *dst_start_coordinate, + ID3D11Resource *src_resource, + const D3D11_TILED_RESOURCE_COORDINATE *src_start_coordinate, + const D3D11_TILE_REGION_SIZE *region_size, + UINT flags + ); + void CopyTiles( + ID3D11Resource *resource, + const D3D11_TILED_RESOURCE_COORDINATE *start_coordinate, + const D3D11_TILE_REGION_SIZE *size, + ID3D11Buffer *buffer, + UINT64 start_offset, + UINT flags + ); + void UpdateTiles( + ID3D11Resource *dst_resource, + const D3D11_TILED_RESOURCE_COORDINATE *dst_start_coordinate, + const D3D11_TILE_REGION_SIZE *dst_region_size, + const void *src_data, + UINT flags + ); + HRESULT ResizeTilePool( + ID3D11Buffer *pool, + UINT64 size + ); + void TiledResourceBarrier( + ID3D11DeviceChild *before_barrier, + ID3D11DeviceChild *after_barrier + ); + BOOL IsAnnotationEnabled(); + void SetMarkerInt(const WCHAR *label, int data); + void BeginEventInt(const WCHAR *label, int data); + void EndEvent(); +} + +[ + uuid(9d06dffa-d1e5-4d07-83a8-1bb123f2f841), + object, + local, + pointer_default(unique) +] +interface ID3D11Device2 : ID3D11Device1 +{ + void GetImmediateContext2(ID3D11DeviceContext2 **context); + HRESULT CreateDeferredContext2(UINT flags, ID3D11DeviceContext2 **context); + void GetResourceTiling( + ID3D11Resource *resource, + UINT *tile_count, + D3D11_PACKED_MIP_DESC *mip_desc, + D3D11_TILE_SHAPE *tile_shape, + UINT *subresource_tiling_count, + UINT first_subresource_tiling, + D3D11_SUBRESOURCE_TILING *subresource_tiling + ); + HRESULT CheckMultisampleQualityLevels1( + DXGI_FORMAT format, + UINT sample_count, + UINT flags, + UINT *quality_level_count + ); +} diff --git a/sdk/include/psdk/d3d11_3.idl b/sdk/include/psdk/d3d11_3.idl new file mode 100644 index 00000000000..4f9ea797416 --- /dev/null +++ b/sdk/include/psdk/d3d11_3.idl @@ -0,0 +1,384 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi1_3.idl"; +import "d3dcommon.idl"; +import "d3d11_2.idl"; + +typedef enum D3D11_CONTEXT_TYPE +{ + D3D11_CONTEXT_TYPE_ALL = 0x0, + D3D11_CONTEXT_TYPE_3D = 0x1, + D3D11_CONTEXT_TYPE_COMPUTE = 0x2, + D3D11_CONTEXT_TYPE_COPY = 0x3, + D3D11_CONTEXT_TYPE_VIDEO = 0x4, +} D3D11_CONTEXT_TYPE; + +typedef enum D3D11_TEXTURE_LAYOUT +{ + D3D11_TEXTURE_LAYOUT_UNDEFINED = 0x0, + D3D11_TEXTURE_LAYOUT_ROW_MAJOR = 0x1, + D3D11_TEXTURE_LAYOUT_64K_STANDARD_SWIZZLE = 0x2, +} D3D11_TEXTURE_LAYOUT; + +typedef enum D3D11_CONSERVATIVE_RASTERIZATION_MODE +{ + D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF = 0x0, + D3D11_CONSERVATIVE_RASTERIZATION_MODE_ON = 0x1, +} D3D11_CONSERVATIVE_RASTERIZATION_MODE; + +typedef enum D3D11_FENCE_FLAG +{ + D3D11_FENCE_FLAG_NONE = 0x1, + D3D11_FENCE_FLAG_SHARED = 0x2, + D3D11_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x4, +} D3D11_FENCE_FLAG; + +typedef struct D3D11_TEXTURE2D_DESC1 +{ + UINT Width; + UINT Height; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + D3D11_TEXTURE_LAYOUT TextureLayout; +} D3D11_TEXTURE2D_DESC1; + +typedef struct D3D11_TEXTURE3D_DESC1 +{ + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + DXGI_FORMAT Format; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + D3D11_TEXTURE_LAYOUT TextureLayout; +} D3D11_TEXTURE3D_DESC1; + +typedef struct D3D11_RASTERIZER_DESC2 +{ + D3D11_FILL_MODE FillMode; + D3D11_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + int DepthBias; + float DepthBiasClamp; + float SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL ScissorEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; + UINT ForcedSampleCount; + D3D11_CONSERVATIVE_RASTERIZATION_MODE ConservativeRaster; +} D3D11_RASTERIZER_DESC2; + +typedef struct D3D11_TEX2D_SRV1 +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT PlaneSlice; +} D3D11_TEX2D_SRV1; + +typedef struct D3D11_TEX2D_ARRAY_SRV1 +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; +} D3D11_TEX2D_ARRAY_SRV1; + +typedef struct D3D11_SHADER_RESOURCE_VIEW_DESC1 +{ + DXGI_FORMAT Format; + D3D11_SRV_DIMENSION ViewDimension; + + union + { + D3D11_BUFFER_SRV Buffer; + D3D11_TEX1D_SRV Texture1D; + D3D11_TEX1D_ARRAY_SRV Texture1DArray; + D3D11_TEX2D_SRV1 Texture2D; + D3D11_TEX2D_ARRAY_SRV1 Texture2DArray; + D3D11_TEX2DMS_SRV Texture2DMS; + D3D11_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D11_TEX3D_SRV Texture3D; + D3D11_TEXCUBE_SRV TextureCube; + D3D11_TEXCUBE_ARRAY_SRV TextureCubeArray; + D3D11_BUFFEREX_SRV BufferEx; + }; +} D3D11_SHADER_RESOURCE_VIEW_DESC1; + +typedef struct D3D11_TEX2D_RTV1 +{ + UINT MipSlice; + UINT PlaneSlice; +} D3D11_TEX2D_RTV1; + +typedef struct D3D11_TEX2D_ARRAY_RTV1 +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; +} D3D11_TEX2D_ARRAY_RTV1; + +typedef struct D3D11_RENDER_TARGET_VIEW_DESC1 +{ + DXGI_FORMAT Format; + D3D11_RTV_DIMENSION ViewDimension; + + union + { + D3D11_BUFFER_RTV Buffer; + D3D11_TEX1D_RTV Texture1D; + D3D11_TEX1D_ARRAY_RTV Texture1DArray; + D3D11_TEX2D_RTV1 Texture2D; + D3D11_TEX2D_ARRAY_RTV1 Texture2DArray; + D3D11_TEX2DMS_RTV Texture2DMS; + D3D11_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D11_TEX3D_RTV Texture3D; + }; +} D3D11_RENDER_TARGET_VIEW_DESC1; + +typedef struct D3D11_TEX2D_UAV1 +{ + UINT MipSlice; + UINT PlaneSlice; +} D3D11_TEX2D_UAV1; + +typedef struct D3D11_TEX2D_ARRAY_UAV1 +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; +} D3D11_TEX2D_ARRAY_UAV1; + +typedef struct D3D11_UNORDERED_ACCESS_VIEW_DESC1 +{ + DXGI_FORMAT Format; + D3D11_UAV_DIMENSION ViewDimension; + + union + { + D3D11_BUFFER_UAV Buffer; + D3D11_TEX1D_UAV Texture1D; + D3D11_TEX1D_ARRAY_UAV Texture1DArray; + D3D11_TEX2D_UAV1 Texture2D; + D3D11_TEX2D_ARRAY_UAV1 Texture2DArray; + D3D11_TEX3D_UAV Texture3D; + }; +} D3D11_UNORDERED_ACCESS_VIEW_DESC1; + +typedef struct D3D11_QUERY_DESC1 +{ + D3D11_QUERY Query; + UINT MiscFlags; + D3D11_CONTEXT_TYPE ContextType; +} D3D11_QUERY_DESC1; + +[ + uuid(51218251-1e33-4617-9ccb-4d3a4367e7bb), + object, + local, + pointer_default(unique) +] +interface ID3D11Texture2D1 : ID3D11Texture2D +{ + void GetDesc1(D3D11_TEXTURE2D_DESC1 *desc); +} + +[ + uuid(0c711683-2853-4846-9bb0-f3e60639e46a), + object, + local, + pointer_default(unique) +] +interface ID3D11Texture3D1 : ID3D11Texture3D +{ + void GetDesc1(D3D11_TEXTURE3D_DESC1 *desc); +} + +[ + uuid(6fbd02fb-209f-46c4-b059-2ed15586a6ac), + object, + local, + pointer_default(unique) +] +interface ID3D11RasterizerState2 : ID3D11RasterizerState1 +{ + void GetDesc2(D3D11_RASTERIZER_DESC2 *desc); +} + +[ + uuid(91308b87-9040-411d-8c67-c39253ce3802), + object, + local, + pointer_default(unique) +] +interface ID3D11ShaderResourceView1 : ID3D11ShaderResourceView +{ + void GetDesc1(D3D11_SHADER_RESOURCE_VIEW_DESC1 *desc); +} + +[ + uuid(ffbe2e23-f011-418a-ac56-5ceed7c5b94b), + object, + local, + pointer_default(unique) +] +interface ID3D11RenderTargetView1 : ID3D11RenderTargetView +{ + void GetDesc1(D3D11_RENDER_TARGET_VIEW_DESC1 *desc); +} + +[ + uuid(7b3b6153-a886-4544-ab37-6537c8500403), + object, + local, + pointer_default(unique) +] +interface ID3D11UnorderedAccessView1 : ID3D11UnorderedAccessView +{ + void GetDesc1(D3D11_UNORDERED_ACCESS_VIEW_DESC1 *desc); +} + +[ + uuid(631b4766-36dc-461d-8db6-c47e13e60916), + object, + local, + pointer_default(unique) +] +interface ID3D11Query1 : ID3D11Query +{ + void GetDesc1(D3D11_QUERY_DESC1 *desc); +} + +[ + uuid(b4e3c01d-e79e-4637-91b2-510e9f4c9b8f), + object, + local, + pointer_default(unique) +] +interface ID3D11DeviceContext3 : ID3D11DeviceContext2 +{ + void Flush1(D3D11_CONTEXT_TYPE type, HANDLE event); + void SetHardwareProtectionState(BOOL enable); + void GetHardwareProtectionState(BOOL *enable); +} + +[ + uuid(affde9d1-1df7-4bb7-8a34-0f46251dab80), + object, + local, + pointer_default(unique) +] +interface ID3D11Fence : ID3D11DeviceChild +{ + HRESULT CreateSharedHandle( + const SECURITY_ATTRIBUTES *attributes, + DWORD access, + const WCHAR *name, + HANDLE *handle + ); + UINT64 GetCompletedValue(); + HRESULT SetEventOnCompletion( + UINT64 value, + HANDLE event + ); +} + +[ + uuid(917600da-f58c-4c33-98d8-3e15b390fa24), + object, + local, + pointer_default(unique) +] +interface ID3D11DeviceContext4 : ID3D11DeviceContext3 +{ + HRESULT Signal(ID3D11Fence *fence, UINT64 value); + HRESULT Wait(ID3D11Fence *fence, UINT64 value); +} + +[ + uuid(a05c8c37-d2c6-4732-b3a0-9ce0b0dc9ae6), + object, + local, + pointer_default(unique) +] +interface ID3D11Device3 : ID3D11Device2 +{ + HRESULT CreateTexture2D1( + const D3D11_TEXTURE2D_DESC1 *desc, + const D3D11_SUBRESOURCE_DATA *initial_data, + ID3D11Texture2D1 **texture + ); + HRESULT CreateTexture3D1( + const D3D11_TEXTURE3D_DESC1 *desc, + const D3D11_SUBRESOURCE_DATA *initial_data, + ID3D11Texture3D1 **texture + ); + HRESULT CreateRasterizerState2( + const D3D11_RASTERIZER_DESC2 *desc, + ID3D11RasterizerState2 **state + ); + HRESULT CreateShaderResourceView1( + ID3D11Resource *resource, + const D3D11_SHADER_RESOURCE_VIEW_DESC1 *desc, + ID3D11ShaderResourceView1 **view + ); + HRESULT CreateUnorderedAccessView1( + ID3D11Resource *resource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC1 *desc, + ID3D11UnorderedAccessView1 **view + ); + HRESULT CreateRenderTargetView1( + ID3D11Resource *resource, + const D3D11_RENDER_TARGET_VIEW_DESC1 *desc, + ID3D11RenderTargetView1 **view + ); + HRESULT CreateQuery1(const D3D11_QUERY_DESC1 *desc, ID3D11Query1 **query); + void GetImmediateContext3(ID3D11DeviceContext3 **context); + HRESULT CreateDeferredContext3(UINT flags, ID3D11DeviceContext3 **context); + void WriteToSubresource( + ID3D11Resource *dst_resource, + UINT dst_subresource, + const D3D11_BOX *dst_box, + const void *src_data, + UINT src_row_pitch, + UINT src_depth_pitch + ); + void ReadFromSubresource( + void *dst_data, + UINT dst_row_pitch, + UINT dst_depth_pitch, + ID3D11Resource *src_resource, + UINT src_subresource, + const D3D11_BOX *src_box + ); +} diff --git a/sdk/include/psdk/d3d11_4.idl b/sdk/include/psdk/d3d11_4.idl new file mode 100644 index 00000000000..f98a7b89b64 --- /dev/null +++ b/sdk/include/psdk/d3d11_4.idl @@ -0,0 +1,120 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi1_5.idl"; +import "d3dcommon.idl"; +import "d3d11_3.idl"; + +typedef struct D3D11_FEATURE_DATA_D3D11_OPTIONS4 +{ + BOOL ExtendedNV12SharedTextureSupported; +} D3D11_FEATURE_DATA_D3D11_OPTIONS4; + +[ + uuid(8992ab71-02e6-4b8d-ba48-b056dcda42c4), + object, + local, + pointer_default(unique) +] +interface ID3D11Device4 : ID3D11Device3 +{ + HRESULT RegisterDeviceRemovedEvent( + [in] HANDLE event, + [out] DWORD *cookie + ); + void UnregisterDeviceRemoved( + [in] DWORD cookie + ); +} + +[ + uuid(8ffde202-a0e7-45df-9e01-e837801b5ea0), + object, + local, + pointer_default(unique) +] +interface ID3D11Device5 : ID3D11Device4 +{ + HRESULT OpenSharedFence( + [in] HANDLE handle, + [in] REFIID iid, + [out] void **fence + ); + HRESULT CreateFence( + [in] UINT64 initial_value, + [in] D3D11_FENCE_FLAG flags, + [in] REFIID iid, + [out] void **fence + ); +} + +[ + uuid(9b7e4e00-342c-4106-a19f-4f2704f689f0), + object, + local, + pointer_default(unique) +] +interface ID3D11Multithread : IUnknown +{ + void Enter(); + void Leave(); + BOOL SetMultithreadProtected( + [in] BOOL enable + ); + BOOL GetMultithreadProtected(); +} + +[ + uuid(c4e7374c-6243-4d1b-ae87-52b4f740e261), + object, + local, + pointer_default(unique) +] +interface ID3D11VideoContext2 : ID3D11VideoContext1 +{ + void VideoProcessorSetOutputHDRMetaData( + [in] ID3D11VideoProcessor *processor, + [in] DXGI_HDR_METADATA_TYPE type, + [in] UINT size, + [in] const void *meta_data + ); + void VideoProcessorGetOutputHDRMetaData( + [in] ID3D11VideoProcessor *processor, + [out] DXGI_HDR_METADATA_TYPE *type, + [in] UINT size, + [out] void *meta_data + ); + + void VideoProcessorSetStreamHDRMetaData( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_index, + [in] DXGI_HDR_METADATA_TYPE type, + [in] UINT size, + [in] const void *meta_data + ); + + void VideoProcessorGetStreamHDRMetaData( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_index, + [out] DXGI_HDR_METADATA_TYPE *type, + [in] UINT size, + [out] void *meta_data + ); +} diff --git a/sdk/include/psdk/d3d11on12.idl b/sdk/include/psdk/d3d11on12.idl new file mode 100644 index 00000000000..42083911328 --- /dev/null +++ b/sdk/include/psdk/d3d11on12.idl @@ -0,0 +1,61 @@ +/* + * Copyright 2018 Józef Kucia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "d3d11.idl"; +import "d3d12.idl"; + +typedef struct D3D11_RESOURCE_FLAGS +{ + UINT BindFlags; + UINT MiscFlags; + UINT CPUAccessFlags; + UINT StructureByteStride; +} D3D11_RESOURCE_FLAGS; + +[ + uuid(85611e73-70a9-490e-9614-a9e302777904), + object, + local, + pointer_default(unique) +] +interface ID3D11On12Device : IUnknown +{ + HRESULT CreateWrappedResource(IUnknown *d3d12_resource, + const D3D11_RESOURCE_FLAGS *flags, + D3D12_RESOURCE_STATES input_state, + D3D12_RESOURCE_STATES output_state, + REFIID iid, void **d3d11_resource); + + void ReleaseWrappedResources(ID3D11Resource * const *resources, UINT count); + + void AcquireWrappedResources(ID3D11Resource * const *resources, UINT count); +} + +[local] HRESULT __stdcall D3D11On12CreateDevice(IUnknown *device, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT feature_level_count, + IUnknown * const *queues, UINT queue_count, UINT node_mask, + ID3D11Device **d3d11_device, ID3D11DeviceContext **d3d11_immediate_context, + D3D_FEATURE_LEVEL *obtained_feature_level); + +typedef HRESULT (__stdcall *PFN_D3D11ON12_CREATE_DEVICE)(IUnknown *device, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT feature_level_count, + IUnknown * const *queues, UINT queue_count, UINT node_mask, + ID3D11Device **d3d11_device, ID3D11DeviceContext **d3d11_immediate_context, + D3D_FEATURE_LEVEL *obtained_feature_level); diff --git a/sdk/include/psdk/d3d11sdklayers.idl b/sdk/include/psdk/d3d11sdklayers.idl new file mode 100644 index 00000000000..638e53ced66 --- /dev/null +++ b/sdk/include/psdk/d3d11sdklayers.idl @@ -0,0 +1,1282 @@ +/* + * Copyright 2013 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "d3d11.idl"; + +typedef enum D3D11_MESSAGE_CATEGORY { + D3D11_MESSAGE_CATEGORY_APPLICATION_DEFINED, + D3D11_MESSAGE_CATEGORY_MISCELLANEOUS, + D3D11_MESSAGE_CATEGORY_INITIALIZATION, + D3D11_MESSAGE_CATEGORY_CLEANUP, + D3D11_MESSAGE_CATEGORY_COMPILATION, + D3D11_MESSAGE_CATEGORY_STATE_CREATION, + D3D11_MESSAGE_CATEGORY_STATE_SETTING, + D3D11_MESSAGE_CATEGORY_STATE_GETTING, + D3D11_MESSAGE_CATEGORY_RESOURCE_MANIPULATION, + D3D11_MESSAGE_CATEGORY_EXECUTION, + D3D11_MESSAGE_CATEGORY_SHADER +} D3D11_MESSAGE_CATEGORY; + +typedef enum D3D11_MESSAGE_SEVERITY { + D3D11_MESSAGE_SEVERITY_CORRUPTION, + D3D11_MESSAGE_SEVERITY_ERROR, + D3D11_MESSAGE_SEVERITY_WARNING, + D3D11_MESSAGE_SEVERITY_INFO, + D3D11_MESSAGE_SEVERITY_MESSAGE +} D3D11_MESSAGE_SEVERITY; + +typedef enum D3D11_MESSAGE_ID { + D3D11_MESSAGE_ID_UNKNOWN = 0, + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_HAZARD, + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_HAZARD, + D3D11_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_HAZARD, + D3D11_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_HAZARD, + D3D11_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_HAZARD, + D3D11_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_HAZARD, + D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD, + D3D11_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_HAZARD, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD, + D3D11_MESSAGE_ID_DEVICE_SOSETTARGETS_HAZARD, + D3D11_MESSAGE_ID_STRING_FROM_APPLICATION, + D3D11_MESSAGE_ID_CORRUPTED_THIS, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER1, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER2, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER3, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER4, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER5, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER6, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER7, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER8, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER9, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER10, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER11, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER12, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER13, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER14, + D3D11_MESSAGE_ID_CORRUPTED_PARAMETER15, + D3D11_MESSAGE_ID_CORRUPTED_MULTITHREADING, + D3D11_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY, + D3D11_MESSAGE_ID_IASETINPUTLAYOUT_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_IASETINDEXBUFFER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_VSSETSHADER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_VSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_VSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_GSSETSHADER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_GSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_GSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_SOSETTARGETS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_PSSETSHADER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_PSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_PSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_RSSETSTATE_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_OMSETBLENDSTATE_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_OMSETDEPTHSTENCILSTATE_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_SETPREDICATION_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_GETPRIVATEDATA_MOREDATA, + D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA, + D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN, + D3D11_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS, + D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS, + D3D11_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDSAMPLES, + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDUSAGE, + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDBINDFLAGS, + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATEBUFFER_UNRECOGNIZEDMISCFLAGS, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDBINDFLAGS, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDINITIALDATA, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDMIPLEVELS, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDMISCFLAGS, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATEBUFFER_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEBUFFER_NULLDESC, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDCONSTANTBUFFERBINDINGS, + D3D11_MESSAGE_ID_CREATEBUFFER_LARGEALLOCATION, + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNSUPPORTEDFORMAT, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDSAMPLES, + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDUSAGE, + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDBINDFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_UNRECOGNIZEDMISCFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDBINDFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDINITIALDATA, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDMIPLEVELS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDMISCFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE1D_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATETEXTURE1D_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATETEXTURE1D_NULLDESC, + D3D11_MESSAGE_ID_CREATETEXTURE1D_LARGEALLOCATION, + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNSUPPORTEDFORMAT, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDSAMPLES, + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDUSAGE, + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDBINDFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_UNRECOGNIZEDMISCFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDBINDFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDINITIALDATA, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDMIPLEVELS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDMISCFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE2D_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATETEXTURE2D_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATETEXTURE2D_NULLDESC, + D3D11_MESSAGE_ID_CREATETEXTURE2D_LARGEALLOCATION, + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNSUPPORTEDFORMAT, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDSAMPLES, + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDUSAGE, + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDBINDFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_UNRECOGNIZEDMISCFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDCPUACCESSFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDBINDFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDINITIALDATA, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDMIPLEVELS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDMISCFLAGS, + D3D11_MESSAGE_ID_CREATETEXTURE3D_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATETEXTURE3D_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATETEXTURE3D_NULLDESC, + D3D11_MESSAGE_ID_CREATETEXTURE3D_LARGEALLOCATION, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_NULLDESC, + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE, + D3D11_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC, + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDQUERY, + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_INVALIDMISCFLAGS, + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_UNEXPECTEDMISCFLAG, + D3D11_MESSAGE_ID_CREATEQUERYORPREDICATE_NULLDESC, + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED, + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED, + D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_OFFSET_TOO_LARGE, + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_IASETINDEXBUFFER_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_FORMAT_INVALID, + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_TOO_LARGE, + D3D11_MESSAGE_ID_DEVICE_IASETINDEXBUFFER_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_VSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_VSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_VSSETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_GSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_GSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_GSSETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_SOSETTARGETS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_SOSETTARGETS_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_PSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_PSSETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT, + D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR, + D3D11_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH, + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH, + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID, + D3D11_MESSAGE_ID_DEVICE_IAGETVERTEXBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_VSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_VSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_VSGETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_GSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_GSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_GSGETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_SOGETTARGETS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_PSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_PSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_PSGETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_RSGETVIEWPORTS_VIEWPORTS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_RSGETSCISSORRECTS_RECTS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_GENERATEMIPS_RESOURCE_INVALID, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSUBRESOURCE, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESUBRESOURCE, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCEBOX, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCE, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDDESTINATIONSTATE, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_INVALIDSOURCESTATE, + D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE, + D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE, + D3D11_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE, + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE, + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX, + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE, + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID, + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID, + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID, + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID, + D3D11_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID, + D3D11_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE, + D3D11_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS, + D3D11_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED, + D3D11_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN, + D3D11_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED, + D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE, + D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS, + D3D11_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED, + D3D11_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN, + D3D11_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED, + D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE, + D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS, + D3D11_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED, + D3D11_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN, + D3D11_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED, + D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE, + D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS, + D3D11_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED, + D3D11_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN, + D3D11_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED, + D3D11_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED, + D3D11_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED, + D3D11_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS, + D3D11_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN, + D3D11_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE, + D3D11_MESSAGE_ID_REF_THREADING_MODE, + D3D11_MESSAGE_ID_REF_UMDRIVER_EXCEPTION, + D3D11_MESSAGE_ID_REF_KMDRIVER_EXCEPTION, + D3D11_MESSAGE_ID_REF_HARDWARE_EXCEPTION, + D3D11_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE, + D3D11_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER, + D3D11_MESSAGE_ID_REF_OUT_OF_MEMORY, + D3D11_MESSAGE_ID_REF_INFO, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_INPUTLAYOUT_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL, + D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_SHADERRESOURCEVIEW_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_VIEW_DIMENSION_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL, + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_FORMAT_INVALID, + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL, + D3D11_MESSAGE_ID_DEVICE_DRAW_GS_INPUT_PRIMITIVE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_POSITION_NOT_PRESENT, + D3D11_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_BOUND_RESOURCE_MAPPED, + D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_PRIMITIVETOPOLOGY, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_STRIDE_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE, + D3D11_MESSAGE_ID_DEVICE_DRAW_SO_STRIDE_LARGER_THAN_BUFFER, + D3D11_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING, + D3D11_MESSAGE_ID_DEVICE_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0, + D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT, + D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT, + D3D11_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT, + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN, + D3D11_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC, + D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH, + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW, + D3D11_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH, + D3D11_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY, + D3D11_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY, + D3D11_MESSAGE_ID_CREATEQUERY_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEPREDICATE_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATECOUNTER_OUTOFRANGE_COUNTER, + D3D11_MESSAGE_ID_CREATECOUNTER_SIMULTANEOUS_ACTIVE_COUNTERS_EXHAUSTED, + D3D11_MESSAGE_ID_CREATECOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER, + D3D11_MESSAGE_ID_CREATECOUNTER_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATECOUNTER_NONEXCLUSIVE_RETURN, + D3D11_MESSAGE_ID_CREATECOUNTER_NULLDESC, + D3D11_MESSAGE_ID_CHECKCOUNTER_OUTOFRANGE_COUNTER, + D3D11_MESSAGE_ID_CHECKCOUNTER_UNSUPPORTED_WELLKNOWN_COUNTER, + D3D11_MESSAGE_ID_SETPREDICATION_INVALID_PREDICATE_STATE, + D3D11_MESSAGE_ID_QUERY_BEGIN_UNSUPPORTED, + D3D11_MESSAGE_ID_PREDICATE_BEGIN_DURING_PREDICATION, + D3D11_MESSAGE_ID_QUERY_BEGIN_DUPLICATE, + D3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS, + D3D11_MESSAGE_ID_PREDICATE_END_DURING_PREDICATION, + D3D11_MESSAGE_ID_QUERY_END_ABANDONING_PREVIOUS_RESULTS, + D3D11_MESSAGE_ID_QUERY_END_WITHOUT_BEGIN, + D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_DATASIZE, + D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_FLAGS, + D3D11_MESSAGE_ID_QUERY_GETDATA_INVALID_CALL, + D3D11_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN, + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE, + D3D11_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT, + D3D11_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH, + D3D11_MESSAGE_ID_LIVE_OBJECT_SUMMARY, + D3D11_MESSAGE_ID_LIVE_BUFFER, + D3D11_MESSAGE_ID_LIVE_TEXTURE1D, + D3D11_MESSAGE_ID_LIVE_TEXTURE2D, + D3D11_MESSAGE_ID_LIVE_TEXTURE3D, + D3D11_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW, + D3D11_MESSAGE_ID_LIVE_RENDERTARGETVIEW, + D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW, + D3D11_MESSAGE_ID_LIVE_VERTEXSHADER, + D3D11_MESSAGE_ID_LIVE_GEOMETRYSHADER, + D3D11_MESSAGE_ID_LIVE_PIXELSHADER, + D3D11_MESSAGE_ID_LIVE_INPUTLAYOUT, + D3D11_MESSAGE_ID_LIVE_SAMPLER, + D3D11_MESSAGE_ID_LIVE_BLENDSTATE, + D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE, + D3D11_MESSAGE_ID_LIVE_RASTERIZERSTATE, + D3D11_MESSAGE_ID_LIVE_QUERY, + D3D11_MESSAGE_ID_LIVE_PREDICATE, + D3D11_MESSAGE_ID_LIVE_COUNTER, + D3D11_MESSAGE_ID_LIVE_DEVICE, + D3D11_MESSAGE_ID_LIVE_SWAPCHAIN, + D3D11_MESSAGE_ID_D3D10_MESSAGES_END, + + D3D11_MESSAGE_ID_D3D10L9_MESSAGES_START = 0x00100000, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_STENCIL_NO_TWO_SIDED, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_DepthBiasClamp_NOT_SUPPORTED, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NO_COMPARISON_SUPPORT, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_EXCESSIVE_ANISOTROPY, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_OUT_OF_RANGE, + D3D11_MESSAGE_ID_VSSETSAMPLERS_NOT_SUPPORTED, + D3D11_MESSAGE_ID_VSSETSAMPLERS_TOO_MANY_SAMPLERS, + D3D11_MESSAGE_ID_PSSETSAMPLERS_TOO_MANY_SAMPLERS, + D3D11_MESSAGE_ID_CREATERESOURCE_NO_ARRAYS, + D3D11_MESSAGE_ID_CREATERESOURCE_NO_VB_AND_IB_BIND, + D3D11_MESSAGE_ID_CREATERESOURCE_NO_TEXTURE_1D, + D3D11_MESSAGE_ID_CREATERESOURCE_DIMENSION_OUT_OF_RANGE, + D3D11_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_SHADER_RESOURCE, + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_TOO_MANY_RENDER_TARGETS, + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_NO_DIFFERING_BIT_DEPTHS, + D3D11_MESSAGE_ID_IASETVERTEXBUFFERS_BAD_BUFFER_INDEX, + D3D11_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_TOO_MANY_VIEWPORTS, + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_ADJACENCY_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_TOO_MANY_SCISSORS, + D3D11_MESSAGE_ID_COPYRESOURCE_ONLY_TEXTURE_2D_WITHIN_GPU_MEMORY, + D3D11_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_3D_READBACK, + D3D11_MESSAGE_ID_COPYRESOURCE_NO_TEXTURE_ONLY_READBACK, + D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_UNSUPPORTED_FORMAT, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_ALPHA_TO_COVERAGE, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_DepthClipEnable_MUST_BE_TRUE, + D3D11_MESSAGE_ID_DRAWINDEXED_STARTINDEXLOCATION_MUST_BE_POSITIVE, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_MUST_USE_LOWEST_LOD, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_MINLOD_MUST_NOT_BE_FRACTIONAL, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_MAXLOD_MUST_BE_FLT_MAX, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_FIRSTARRAYSLICE_MUST_BE_ZERO, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_CUBES_MUST_HAVE_6_SIDES, + D3D11_MESSAGE_ID_CREATERESOURCE_NOT_BINDABLE_AS_RENDER_TARGET, + D3D11_MESSAGE_ID_CREATERESOURCE_NO_DWORD_INDEX_BUFFER, + D3D11_MESSAGE_ID_CREATERESOURCE_MSAA_PRECLUDES_SHADER_RESOURCE, + D3D11_MESSAGE_ID_CREATERESOURCE_PRESENTATION_PRECLUDES_SHADER_RESOURCE, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_BLEND_ENABLE, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_INDEPENDENT_WRITE_MASKS, + D3D11_MESSAGE_ID_CREATERESOURCE_NO_STREAM_OUT, + D3D11_MESSAGE_ID_CREATERESOURCE_ONLY_VB_IB_FOR_BUFFERS, + D3D11_MESSAGE_ID_CREATERESOURCE_NO_AUTOGEN_FOR_VOLUMES, + D3D11_MESSAGE_ID_CREATERESOURCE_DXGI_FORMAT_R8G8B8A8_CANNOT_BE_SHARED, + D3D11_MESSAGE_ID_VSSHADERRESOURCES_NOT_SUPPORTED, + D3D11_MESSAGE_ID_GEOMETRY_SHADER_NOT_SUPPORTED, + D3D11_MESSAGE_ID_STREAM_OUT_NOT_SUPPORTED, + D3D11_MESSAGE_ID_TEXT_FILTER_NOT_SUPPORTED, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_SEPARATE_ALPHA_BLEND, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_NO_MRT_BLEND, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_OPERATION_NOT_SUPPORTED, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_NO_MIRRORONCE, + D3D11_MESSAGE_ID_DRAWINSTANCED_NOT_SUPPORTED, + D3D11_MESSAGE_ID_DRAWINDEXEDINSTANCED_NOT_SUPPORTED_BELOW_9_3, + D3D11_MESSAGE_ID_DRAWINDEXED_POINTLIST_UNSUPPORTED, + D3D11_MESSAGE_ID_SETBLENDSTATE_SAMPLE_MASK_CANNOT_BE_ZERO, + D3D11_MESSAGE_ID_CREATERESOURCE_DIMENSION_EXCEEDS_FEATURE_LEVEL_DEFINITION, + D3D11_MESSAGE_ID_CREATERESOURCE_ONLY_SINGLE_MIP_LEVEL_DEPTH_STENCIL_SUPPORTED, + D3D11_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_NEGATIVESCISSOR, + D3D11_MESSAGE_ID_SLOT_ZERO_MUST_BE_D3D10_INPUT_PER_VERTEX_DATA, + D3D11_MESSAGE_ID_CREATERESOURCE_NON_POW_2_MIPMAP, + D3D11_MESSAGE_ID_CREATESAMPLERSTATE_BORDER_NOT_SUPPORTED, + D3D11_MESSAGE_ID_OMSETRENDERTARGETS_NO_SRGB_MRT, + D3D11_MESSAGE_ID_COPYRESOURCE_NO_3D_MISMATCHED_UPDATES, + D3D11_MESSAGE_ID_D3D10L9_MESSAGES_END, + + D3D11_MESSAGE_ID_D3D11_MESSAGES_START = 0x00200000, + D3D11_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFLAGS, + D3D11_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTREAMS, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTREAMS, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_CREATEPIXELSHADER_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALID_COMMANDLISTFLAGS, + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_SINGLETHREADED, + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_INVALID_CALL_RETURN, + D3D11_MESSAGE_ID_CREATEDEFERREDCONTEXT_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_FINISHDISPLAYLIST_ONIMMEDIATECONTEXT, + D3D11_MESSAGE_ID_FINISHDISPLAYLIST_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_FINISHDISPLAYLIST_INVALID_CALL_RETURN, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES, + D3D11_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES, + D3D11_MESSAGE_ID_DEVICE_HSSETSHADERRESOURCES_HAZARD, + D3D11_MESSAGE_ID_DEVICE_HSSETCONSTANTBUFFERS_HAZARD, + D3D11_MESSAGE_ID_HSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDCALL, + D3D11_MESSAGE_ID_CREATEHULLSHADER_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATEHULLSHADER_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_DEVICE_HSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_HSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_HSSETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_HSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_HSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_HSGETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_DSSETSHADERRESOURCES_HAZARD, + D3D11_MESSAGE_ID_DEVICE_DSSETCONSTANTBUFFERS_HAZARD, + D3D11_MESSAGE_ID_DSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCALL, + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_DEVICE_DSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_DSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_DSSETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_DSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_DSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_DSGETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_XOR_DS_MISMATCH, + D3D11_MESSAGE_ID_DEFERRED_CONTEXT_REMOVAL_PROCESS_AT_FAULT, + D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_INVALID_ARG_BUFFER, + D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_OVERFLOW, + D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDMAPTYPE, + D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_RESOURCE_MAP_INVALIDFLAGS, + D3D11_MESSAGE_ID_RESOURCE_MAP_ALREADYMAPPED, + D3D11_MESSAGE_ID_RESOURCE_MAP_DEVICEREMOVED_RETURN, + D3D11_MESSAGE_ID_RESOURCE_MAP_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_RESOURCE_MAP_WITHOUT_INITIAL_DISCARD, + D3D11_MESSAGE_ID_RESOURCE_UNMAP_INVALIDSUBRESOURCE, + D3D11_MESSAGE_ID_RESOURCE_UNMAP_NOTMAPPED, + D3D11_MESSAGE_ID_DEVICE_DRAW_RASTERIZING_CONTROL_POINTS, + D3D11_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_SIGNATURE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_CONTROL_POINT_COUNT_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_DRAW_HS_DS_TESSELLATOR_DOMAIN_MISMATCH, + D3D11_MESSAGE_ID_CREATE_CONTEXT, + D3D11_MESSAGE_ID_LIVE_CONTEXT, + D3D11_MESSAGE_ID_DESTROY_CONTEXT, + D3D11_MESSAGE_ID_CREATE_BUFFER, + D3D11_MESSAGE_ID_LIVE_BUFFER_WIN7, + D3D11_MESSAGE_ID_DESTROY_BUFFER, + D3D11_MESSAGE_ID_CREATE_TEXTURE1D, + D3D11_MESSAGE_ID_LIVE_TEXTURE1D_WIN7, + D3D11_MESSAGE_ID_DESTROY_TEXTURE1D, + D3D11_MESSAGE_ID_CREATE_TEXTURE2D, + D3D11_MESSAGE_ID_LIVE_TEXTURE2D_WIN7, + D3D11_MESSAGE_ID_DESTROY_TEXTURE2D, + D3D11_MESSAGE_ID_CREATE_TEXTURE3D, + D3D11_MESSAGE_ID_LIVE_TEXTURE3D_WIN7, + D3D11_MESSAGE_ID_DESTROY_TEXTURE3D, + D3D11_MESSAGE_ID_CREATE_SHADERRESOURCEVIEW, + D3D11_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW_WIN7, + D3D11_MESSAGE_ID_DESTROY_SHADERRESOURCEVIEW, + D3D11_MESSAGE_ID_CREATE_RENDERTARGETVIEW, + D3D11_MESSAGE_ID_LIVE_RENDERTARGETVIEW_WIN7, + D3D11_MESSAGE_ID_DESTROY_RENDERTARGETVIEW, + D3D11_MESSAGE_ID_CREATE_DEPTHSTENCILVIEW, + D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW_WIN7, + D3D11_MESSAGE_ID_DESTROY_DEPTHSTENCILVIEW, + D3D11_MESSAGE_ID_CREATE_VERTEXSHADER, + D3D11_MESSAGE_ID_LIVE_VERTEXSHADER_WIN7, + D3D11_MESSAGE_ID_DESTROY_VERTEXSHADER, + D3D11_MESSAGE_ID_CREATE_HULLSHADER, + D3D11_MESSAGE_ID_LIVE_HULLSHADER, + D3D11_MESSAGE_ID_DESTROY_HULLSHADER, + D3D11_MESSAGE_ID_CREATE_DOMAINSHADER, + D3D11_MESSAGE_ID_LIVE_DOMAINSHADER, + D3D11_MESSAGE_ID_DESTROY_DOMAINSHADER, + D3D11_MESSAGE_ID_CREATE_GEOMETRYSHADER, + D3D11_MESSAGE_ID_LIVE_GEOMETRYSHADER_WIN7, + D3D11_MESSAGE_ID_DESTROY_GEOMETRYSHADER, + D3D11_MESSAGE_ID_CREATE_PIXELSHADER, + D3D11_MESSAGE_ID_LIVE_PIXELSHADER_WIN7, + D3D11_MESSAGE_ID_DESTROY_PIXELSHADER, + D3D11_MESSAGE_ID_CREATE_INPUTLAYOUT, + D3D11_MESSAGE_ID_LIVE_INPUTLAYOUT_WIN7, + D3D11_MESSAGE_ID_DESTROY_INPUTLAYOUT, + D3D11_MESSAGE_ID_CREATE_SAMPLER, + D3D11_MESSAGE_ID_LIVE_SAMPLER_WIN7, + D3D11_MESSAGE_ID_DESTROY_SAMPLER, + D3D11_MESSAGE_ID_CREATE_BLENDSTATE, + D3D11_MESSAGE_ID_LIVE_BLENDSTATE_WIN7, + D3D11_MESSAGE_ID_DESTROY_BLENDSTATE, + D3D11_MESSAGE_ID_CREATE_DEPTHSTENCILSTATE, + D3D11_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE_WIN7, + D3D11_MESSAGE_ID_DESTROY_DEPTHSTENCILSTATE, + D3D11_MESSAGE_ID_CREATE_RASTERIZERSTATE, + D3D11_MESSAGE_ID_LIVE_RASTERIZERSTATE_WIN7, + D3D11_MESSAGE_ID_DESTROY_RASTERIZERSTATE, + D3D11_MESSAGE_ID_CREATE_QUERY, + D3D11_MESSAGE_ID_LIVE_QUERY_WIN7, + D3D11_MESSAGE_ID_DESTROY_QUERY, + D3D11_MESSAGE_ID_CREATE_PREDICATE, + D3D11_MESSAGE_ID_LIVE_PREDICATE_WIN7, + D3D11_MESSAGE_ID_DESTROY_PREDICATE, + D3D11_MESSAGE_ID_CREATE_COUNTER, + D3D11_MESSAGE_ID_DESTROY_COUNTER, + D3D11_MESSAGE_ID_CREATE_COMMANDLIST, + D3D11_MESSAGE_ID_LIVE_COMMANDLIST, + D3D11_MESSAGE_ID_DESTROY_COMMANDLIST, + D3D11_MESSAGE_ID_CREATE_CLASSINSTANCE, + D3D11_MESSAGE_ID_LIVE_CLASSINSTANCE, + D3D11_MESSAGE_ID_DESTROY_CLASSINSTANCE, + D3D11_MESSAGE_ID_CREATE_CLASSLINKAGE, + D3D11_MESSAGE_ID_LIVE_CLASSLINKAGE, + D3D11_MESSAGE_ID_DESTROY_CLASSLINKAGE, + D3D11_MESSAGE_ID_LIVE_DEVICE_WIN7, + D3D11_MESSAGE_ID_LIVE_OBJECT_SUMMARY_WIN7, + D3D11_MESSAGE_ID_CREATE_COMPUTESHADER, + D3D11_MESSAGE_ID_LIVE_COMPUTESHADER, + D3D11_MESSAGE_ID_DESTROY_COMPUTESHADER, + D3D11_MESSAGE_ID_CREATE_UNORDEREDACCESSVIEW, + D3D11_MESSAGE_ID_LIVE_UNORDEREDACCESSVIEW, + D3D11_MESSAGE_ID_DESTROY_UNORDEREDACCESSVIEW, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INTERFACES_FEATURELEVEL, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INTERFACE_COUNT_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_INDEX, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_TYPE, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INVALID_INSTANCE_DATA, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_UNBOUND_INSTANCE_DATA, + D3D11_MESSAGE_ID_DEVICE_SETSHADER_INSTANCE_DATA_BINDINGS, + D3D11_MESSAGE_ID_DEVICE_CREATESHADER_CLASSLINKAGE_FULL, + D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_UNRECOGNIZED_FEATURE, + D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE, + D3D11_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_HAZARD, + D3D11_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_HAZARD, + D3D11_MESSAGE_ID_CSSETSHADERRESOURCES_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCALL, + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_OUTOFMEMORY, + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERBYTECODE, + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERTYPE, + D3D11_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCLASSLINKAGE, + D3D11_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_INVALIDBUFFER, + D3D11_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_CSSETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_CSGETSHADERRESOURCES_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_CSGETCONSTANTBUFFERS_BUFFERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_CSGETSAMPLERS_SAMPLERS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED, + D3D11_MESSAGE_ID_CREATEBUFFER_INVALIDSTRUCTURESTRIDE, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFLAGS, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDESC, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_HAZARD, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_OVERLAPPING_OLD_SLOTS, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_NO_OP, + D3D11_MESSAGE_ID_CSSETUNORDEREDACCESSVIEWS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_PSSETUNORDEREDACCESSVIEWS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_HAZARD, + D3D11_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_DENORMFLUSH, + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSS_VIEWS_EMPTY, + D3D11_MESSAGE_ID_DEVICE_CSGETUNORDEREDACCESSS_VIEWS_EMPTY, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS, + D3D11_MESSAGE_ID_CREATESHADERRESESOURCEVIEW_TOOMANYOBJECTS, + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_INVALID_ARG_BUFFER, + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_UNALIGNED, + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDCONTEXT, + D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDRESOURCE, + D3D11_MESSAGE_ID_DEVICE_SETRESOURCEMINLOD_INVALIDMINLOD, + D3D11_MESSAGE_ID_DEVICE_GETRESOURCEMINLOD_INVALIDCONTEXT, + D3D11_MESSAGE_ID_DEVICE_GETRESOURCEMINLOD_INVALIDRESOURCE, + D3D11_MESSAGE_ID_OMSETDEPTHSTENCIL_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DEPTH_READONLY, + D3D11_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_STENCIL_READONLY, + D3D11_MESSAGE_ID_CHECKFEATURESUPPORT_FORMAT_DEPRECATED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RETURN_TYPE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_UNORDEREDACCESSVIEW_RENDERTARGETVIEW_OVERLAP, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_DIMENSION_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_APPEND_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMICS_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_STRUCTURE_STRIDE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_BUFFER_TYPE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RAW_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_LD_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_STORE_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_ADD_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_BITWISE_OPS_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_CMPSTORE_CMPEXCHANGE_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_EXCHANGE_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_SIGNED_MINMAX_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_UNSIGNED_MINMAX_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DISPATCH_BOUND_RESOURCE_MAPPED, + D3D11_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_OVERFLOW, + D3D11_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_ZERO, + D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_STRUCTURE_STRIDE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_BUFFER_TYPE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_RAW_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DISPATCH_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_UNSUPPORTED, + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDOFFSET, + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_LARGEOFFSET, + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDDESTINATIONSTATE, + D3D11_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDSOURCESTATE, + D3D11_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_NOT_SUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_INVALIDVIEW, + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_INVALIDOFFSET, + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_TOOMANYVIEWS, + D3D11_MESSAGE_ID_CLEARUNORDEREDACCESSVIEWFLOAT_INVALIDFORMAT, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_COUNTER_UNSUPPORTED, + D3D11_MESSAGE_ID_REF_WARNING, + D3D11_MESSAGE_ID_DEVICE_DRAW_PIXEL_SHADER_WITHOUT_RTV_OR_DSV, + D3D11_MESSAGE_ID_SHADER_ABORT, + D3D11_MESSAGE_ID_SHADER_MESSAGE, + D3D11_MESSAGE_ID_SHADER_ERROR, + D3D11_MESSAGE_ID_OFFERRESOURCES_INVALIDRESOURCE, + D3D11_MESSAGE_ID_HSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_DSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CSSETSAMPLERS_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_HSSETSHADER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_DSSETSHADER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_CSSETSHADER_UNBINDDELETINGOBJECT, + D3D11_MESSAGE_ID_ENQUEUESETEVENT_INVALIDARG_RETURN, + D3D11_MESSAGE_ID_ENQUEUESETEVENT_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_ENQUEUESETEVENT_ACCESSDENIED_RETURN, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_NUMUAVS_INVALIDRANGE, + D3D11_MESSAGE_ID_D3D11_MESSAGES_END, + + D3D11_MESSAGE_ID_D3D11_1_MESSAGES_START = 0x00300000, + D3D11_MESSAGE_ID_CREATE_VIDEODECODER, + D3D11_MESSAGE_ID_CREATE_VIDEOPROCESSORENUM, + D3D11_MESSAGE_ID_CREATE_VIDEOPROCESSOR, + D3D11_MESSAGE_ID_CREATE_DECODEROUTPUTVIEW, + D3D11_MESSAGE_ID_CREATE_PROCESSORINPUTVIEW, + D3D11_MESSAGE_ID_CREATE_PROCESSOROUTPUTVIEW, + D3D11_MESSAGE_ID_CREATE_DEVICECONTEXTSTATE, + D3D11_MESSAGE_ID_LIVE_VIDEODECODER, + D3D11_MESSAGE_ID_LIVE_VIDEOPROCESSORENUM, + D3D11_MESSAGE_ID_LIVE_VIDEOPROCESSOR, + D3D11_MESSAGE_ID_LIVE_DECODEROUTPUTVIEW, + D3D11_MESSAGE_ID_LIVE_PROCESSORINPUTVIEW, + D3D11_MESSAGE_ID_LIVE_PROCESSOROUTPUTVIEW, + D3D11_MESSAGE_ID_LIVE_DEVICECONTEXTSTATE, + D3D11_MESSAGE_ID_DESTROY_VIDEODECODER, + D3D11_MESSAGE_ID_DESTROY_VIDEOPROCESSORENUM, + D3D11_MESSAGE_ID_DESTROY_VIDEOPROCESSOR, + D3D11_MESSAGE_ID_DESTROY_DECODEROUTPUTVIEW, + D3D11_MESSAGE_ID_DESTROY_PROCESSORINPUTVIEW, + D3D11_MESSAGE_ID_DESTROY_PROCESSOROUTPUTVIEW, + D3D11_MESSAGE_ID_DESTROY_DEVICECONTEXTSTATE, + D3D11_MESSAGE_ID_CREATEDEVICECONTEXTSTATE_INVALIDFLAGS, + D3D11_MESSAGE_ID_CREATEDEVICECONTEXTSTATE_INVALIDFEATURELEVEL, + D3D11_MESSAGE_ID_CREATEDEVICECONTEXTSTATE_FEATURELEVELS_NOT_SUPPORTED, + D3D11_MESSAGE_ID_CREATEDEVICECONTEXTSTATE_INVALIDREFIID, + D3D11_MESSAGE_ID_DEVICE_DISCARDVIEW_INVALIDVIEW, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION1_INVALIDCOPYFLAGS, + D3D11_MESSAGE_ID_UPDATESUBRESOURCE1_INVALIDCOPYFLAGS, + D3D11_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFORCEDSAMPLECOUNT, + D3D11_MESSAGE_ID_CREATEVIDEODECODER_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEVIDEODECODER_NULLPARAM, + D3D11_MESSAGE_ID_CREATEVIDEODECODER_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATEVIDEODECODER_ZEROWIDTHHEIGHT, + D3D11_MESSAGE_ID_CREATEVIDEODECODER_DRIVER_INVALIDBUFFERSIZE, + D3D11_MESSAGE_ID_CREATEVIDEODECODER_DRIVER_INVALIDBUFFERUSAGE, + D3D11_MESSAGE_ID_GETVIDEODECODERPROFILECOUNT_OUTOFMEMORY, + D3D11_MESSAGE_ID_GETVIDEODECODERPROFILE_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEODECODERPROFILE_INVALIDINDEX, + D3D11_MESSAGE_ID_GETVIDEODECODERPROFILE_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CHECKVIDEODECODERFORMAT_NULLPARAM, + D3D11_MESSAGE_ID_CHECKVIDEODECODERFORMAT_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_GETVIDEODECODERCONFIGCOUNT_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEODECODERCONFIGCOUNT_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_GETVIDEODECODERCONFIG_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEODECODERCONFIG_INVALIDINDEX, + D3D11_MESSAGE_ID_GETVIDEODECODERCONFIG_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_GETDECODERCREATIONPARAMS_NULLPARAM, + D3D11_MESSAGE_ID_GETDECODERDRIVERHANDLE_NULLPARAM, + D3D11_MESSAGE_ID_GETDECODERBUFFER_NULLPARAM, + D3D11_MESSAGE_ID_GETDECODERBUFFER_INVALIDBUFFER, + D3D11_MESSAGE_ID_GETDECODERBUFFER_INVALIDTYPE, + D3D11_MESSAGE_ID_GETDECODERBUFFER_LOCKED, + D3D11_MESSAGE_ID_RELEASEDECODERBUFFER_NULLPARAM, + D3D11_MESSAGE_ID_RELEASEDECODERBUFFER_INVALIDTYPE, + D3D11_MESSAGE_ID_RELEASEDECODERBUFFER_NOTLOCKED, + D3D11_MESSAGE_ID_DECODERBEGINFRAME_NULLPARAM, + D3D11_MESSAGE_ID_DECODERBEGINFRAME_HAZARD, + D3D11_MESSAGE_ID_DECODERENDFRAME_NULLPARAM, + D3D11_MESSAGE_ID_SUBMITDECODERBUFFERS_NULLPARAM, + D3D11_MESSAGE_ID_SUBMITDECODERBUFFERS_INVALIDTYPE, + D3D11_MESSAGE_ID_DECODEREXTENSION_NULLPARAM, + D3D11_MESSAGE_ID_DECODEREXTENSION_INVALIDRESOURCE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_NULLPARAM, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_INVALIDFRAMEFORMAT, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_INVALIDUSAGE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_INVALIDINPUTFRAMERATE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_INVALIDOUTPUTFRAMERATE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORENUMERATOR_INVALIDWIDTHHEIGHT, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORCONTENTDESC_NULLPARAM, + D3D11_MESSAGE_ID_CHECKVIDEOPROCESSORFORMAT_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORCAPS_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORRATECONVERSIONCAPS_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORRATECONVERSIONCAPS_INVALIDINDEX, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORCUSTOMRATE_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORCUSTOMRATE_INVALIDINDEX, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORFILTERRANGE_NULLPARAM, + D3D11_MESSAGE_ID_GETVIDEOPROCESSORFILTERRANGE_UNSUPPORTED, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOR_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOR_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTTARGETRECT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTBACKGROUNDCOLOR_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTBACKGROUNDCOLOR_INVALIDALPHA, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTCOLORSPACE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTALPHAFILLMODE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTALPHAFILLMODE_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTALPHAFILLMODE_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTALPHAFILLMODE_INVALIDFILLMODE, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTCONSTRICTION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTSTEREOMODE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTSTEREOMODE_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTEXTENSION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTTARGETRECT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTBACKGROUNDCOLOR_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTCOLORSPACE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTALPHAFILLMODE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTCONSTRICTION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTCONSTRICTION_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTCONSTRICTION_INVALIDSIZE, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTSTEREOMODE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTEXTENSION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFRAMEFORMAT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFRAMEFORMAT_INVALIDFORMAT, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFRAMEFORMAT_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMCOLORSPACE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMCOLORSPACE_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMOUTPUTRATE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMOUTPUTRATE_INVALIDRATE, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMOUTPUTRATE_INVALIDFLAG, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMOUTPUTRATE_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSOURCERECT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSOURCERECT_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSOURCERECT_INVALIDRECT, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMDESTRECT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMDESTRECT_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMDESTRECT_INVALIDRECT, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMALPHA_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMALPHA_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMALPHA_INVALIDALPHA, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPALETTE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPALETTE_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPALETTE_INVALIDCOUNT, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPALETTE_INVALIDALPHA, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPIXELASPECTRATIO_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPIXELASPECTRATIO_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPIXELASPECTRATIO_INVALIDRATIO, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMLUMAKEY_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMLUMAKEY_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMLUMAKEY_INVALIDRANGE, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMLUMAKEY_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_FLIPUNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_MONOOFFSETUNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_FORMATUNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMSTEREOFORMAT_INVALIDFORMAT, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMAUTOPROCESSINGMODE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMAUTOPROCESSINGMODE_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFILTER_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFILTER_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFILTER_INVALIDFILTER, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFILTER_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMFILTER_INVALIDLEVEL, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMEXTENSION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMEXTENSION_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMFRAMEFORMAT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMCOLORSPACE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMOUTPUTRATE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMSOURCERECT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMDESTRECT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMALPHA_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMPALETTE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMPIXELASPECTRATIO_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMLUMAKEY_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMSTEREOFORMAT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMAUTOPROCESSINGMODE_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMFILTER_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMEXTENSION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMEXTENSION_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDSTREAMCOUNT, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_TARGETRECT, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDOUTPUT, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDPASTFRAMES, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDFUTUREFRAMES, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDSOURCERECT, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDDESTRECT, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDINPUTRESOURCE, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDARRAYSIZE, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDARRAY, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_RIGHTEXPECTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_RIGHTNOTEXPECTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_STEREONOTENABLED, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INVALIDRIGHTRESOURCE, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_NOSTEREOSTREAMS, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_INPUTHAZARD, + D3D11_MESSAGE_ID_VIDEOPROCESSORBLT_OUTPUTHAZARD, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_NULLPARAM, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_INVALIDTYPE, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_INVALIDBIND, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_UNSUPPORTEDFORMAT, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_INVALIDMIP, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_UNSUPPORTEMIP, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_INVALIDARRAYSIZE, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_INVALIDARRAY, + D3D11_MESSAGE_ID_CREATEVIDEODECODEROUTPUTVIEW_INVALIDDIMENSION, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_NULLPARAM, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDTYPE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDBIND, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDMISC, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDUSAGE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDFOURCC, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDMIP, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_UNSUPPORTEDMIP, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDARRAYSIZE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDARRAY, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDDIMENSION, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_NULLPARAM, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDTYPE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDBIND, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDFORMAT, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDMIP, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_UNSUPPORTEDMIP, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_UNSUPPORTEDARRAY, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDARRAY, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDDIMENSION, + D3D11_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_FORCED_SAMPLE_COUNT, + D3D11_MESSAGE_ID_CREATEBLENDSTATE_INVALIDLOGICOPS, + D3D11_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDARRAYWITHDECODER, + D3D11_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDARRAYWITHDECODER, + D3D11_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDARRAYWITHDECODER, + D3D11_MESSAGE_ID_DEVICE_LOCKEDOUT_INTERFACE, + D3D11_MESSAGE_ID_REF_WARNING_ATOMIC_INCONSISTENT, + D3D11_MESSAGE_ID_REF_WARNING_READING_UNINITIALIZED_RESOURCE, + D3D11_MESSAGE_ID_REF_WARNING_RAW_HAZARD, + D3D11_MESSAGE_ID_REF_WARNING_WAR_HAZARD, + D3D11_MESSAGE_ID_REF_WARNING_WAW_HAZARD, + D3D11_MESSAGE_ID_CREATECRYPTOSESSION_NULLPARAM, + D3D11_MESSAGE_ID_CREATECRYPTOSESSION_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_GETCRYPTOTYPE_NULLPARAM, + D3D11_MESSAGE_ID_GETDECODERPROFILE_NULLPARAM, + D3D11_MESSAGE_ID_GETCRYPTOSESSIONCERTIFICATESIZE_NULLPARAM, + D3D11_MESSAGE_ID_GETCRYPTOSESSIONCERTIFICATE_NULLPARAM, + D3D11_MESSAGE_ID_GETCRYPTOSESSIONCERTIFICATE_WRONGSIZE, + D3D11_MESSAGE_ID_GETCRYPTOSESSIONHANDLE_WRONGSIZE, + D3D11_MESSAGE_ID_NEGOTIATECRPYTOSESSIONKEYEXCHANGE_NULLPARAM, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_UNSUPPORTED, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_NULLPARAM, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_SRC_WRONGDEVICE, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_DST_WRONGDEVICE, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_FORMAT_MISMATCH, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_SIZE_MISMATCH, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_SRC_MULTISAMPLED, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_DST_NOT_STAGING, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_SRC_MAPPED, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_DST_MAPPED, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_SRC_OFFERED, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_DST_OFFERED, + D3D11_MESSAGE_ID_ENCRYPTIONBLT_SRC_CONTENT_UNDEFINED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_UNSUPPORTED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_NULLPARAM, + D3D11_MESSAGE_ID_DECRYPTIONBLT_SRC_WRONGDEVICE, + D3D11_MESSAGE_ID_DECRYPTIONBLT_DST_WRONGDEVICE, + D3D11_MESSAGE_ID_DECRYPTIONBLT_FORMAT_MISMATCH, + D3D11_MESSAGE_ID_DECRYPTIONBLT_SIZE_MISMATCH, + D3D11_MESSAGE_ID_DECRYPTIONBLT_DST_MULTISAMPLED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_SRC_NOT_STAGING, + D3D11_MESSAGE_ID_DECRYPTIONBLT_DST_NOT_RENDER_TARGET, + D3D11_MESSAGE_ID_DECRYPTIONBLT_SRC_MAPPED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_DST_MAPPED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_SRC_OFFERED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_DST_OFFERED, + D3D11_MESSAGE_ID_DECRYPTIONBLT_SRC_CONTENT_UNDEFINED, + D3D11_MESSAGE_ID_STARTSESSIONKEYREFRESH_NULLPARAM, + D3D11_MESSAGE_ID_STARTSESSIONKEYREFRESH_INVALIDSIZE, + D3D11_MESSAGE_ID_FINISHSESSIONKEYREFRESH_NULLPARAM, + D3D11_MESSAGE_ID_GETENCRYPTIONBLTKEY_NULLPARAM, + D3D11_MESSAGE_ID_GETENCRYPTIONBLTKEY_INVALIDSIZE, + D3D11_MESSAGE_ID_GETCONTENTPROTECTIONCAPS_NULLPARAM, + D3D11_MESSAGE_ID_CHECKCRYPTOKEYEXCHANGE_NULLPARAM, + D3D11_MESSAGE_ID_CHECKCRYPTOKEYEXCHANGE_INVALIDINDEX, + D3D11_MESSAGE_ID_CREATEAUTHENTICATEDCHANNEL_NULLPARAM, + D3D11_MESSAGE_ID_CREATEAUTHENTICATEDCHANNEL_UNSUPPORTED, + D3D11_MESSAGE_ID_CREATEAUTHENTICATEDCHANNEL_INVALIDTYPE, + D3D11_MESSAGE_ID_CREATEAUTHENTICATEDCHANNEL_OUTOFMEMORY_RETURN, + D3D11_MESSAGE_ID_GETAUTHENTICATEDCHANNELCERTIFICATESIZE_INVALIDCHANNEL, + D3D11_MESSAGE_ID_GETAUTHENTICATEDCHANNELCERTIFICATESIZE_NULLPARAM, + D3D11_MESSAGE_ID_GETAUTHENTICATEDCHANNELCERTIFICATE_INVALIDCHANNEL, + D3D11_MESSAGE_ID_GETAUTHENTICATEDCHANNELCERTIFICATE_NULLPARAM, + D3D11_MESSAGE_ID_GETAUTHENTICATEDCHANNELCERTIFICATE_WRONGSIZE, + D3D11_MESSAGE_ID_NEGOTIATEAUTHENTICATEDCHANNELKEYEXCHANGE_INVALIDCHANNEL, + D3D11_MESSAGE_ID_NEGOTIATEAUTHENTICATEDCHANNELKEYEXCHANGE_NULLPARAM, + D3D11_MESSAGE_ID_QUERYAUTHENTICATEDCHANNEL_NULLPARAM, + D3D11_MESSAGE_ID_QUERYAUTHENTICATEDCHANNEL_WRONGCHANNEL, + D3D11_MESSAGE_ID_QUERYAUTHENTICATEDCHANNEL_UNSUPPORTEDQUERY, + D3D11_MESSAGE_ID_QUERYAUTHENTICATEDCHANNEL_WRONGSIZE, + D3D11_MESSAGE_ID_QUERYAUTHENTICATEDCHANNEL_INVALIDPROCESSINDEX, + D3D11_MESSAGE_ID_CONFIGUREAUTHENTICATEDCHANNEL_NULLPARAM, + D3D11_MESSAGE_ID_CONFIGUREAUTHENTICATEDCHANNEL_WRONGCHANNEL, + D3D11_MESSAGE_ID_CONFIGUREAUTHENTICATEDCHANNEL_UNSUPPORTEDCONFIGURE, + D3D11_MESSAGE_ID_CONFIGUREAUTHENTICATEDCHANNEL_WRONGSIZE, + D3D11_MESSAGE_ID_CONFIGUREAUTHENTICATEDCHANNEL_INVALIDPROCESSIDTYPE, + D3D11_MESSAGE_ID_VSSETCONSTANTBUFFERS_INVALIDBUFFEROFFSETORCOUNT, + D3D11_MESSAGE_ID_DSSETCONSTANTBUFFERS_INVALIDBUFFEROFFSETORCOUNT, + D3D11_MESSAGE_ID_HSSETCONSTANTBUFFERS_INVALIDBUFFEROFFSETORCOUNT, + D3D11_MESSAGE_ID_GSSETCONSTANTBUFFERS_INVALIDBUFFEROFFSETORCOUNT, + D3D11_MESSAGE_ID_PSSETCONSTANTBUFFERS_INVALIDBUFFEROFFSETORCOUNT, + D3D11_MESSAGE_ID_CSSETCONSTANTBUFFERS_INVALIDBUFFEROFFSETORCOUNT, + D3D11_MESSAGE_ID_NEGOTIATECRPYTOSESSIONKEYEXCHANGE_INVALIDSIZE, + D3D11_MESSAGE_ID_NEGOTIATEAUTHENTICATEDCHANNELKEYEXCHANGE_INVALIDSIZE, + D3D11_MESSAGE_ID_OFFERRESOURCES_INVALIDPRIORITY, + D3D11_MESSAGE_ID_GETCRYPTOSESSIONHANDLE_OUTOFMEMORY, + D3D11_MESSAGE_ID_ACQUIREHANDLEFORCAPTURE_NULLPARAM, + D3D11_MESSAGE_ID_ACQUIREHANDLEFORCAPTURE_INVALIDTYPE, + D3D11_MESSAGE_ID_ACQUIREHANDLEFORCAPTURE_INVALIDBIND, + D3D11_MESSAGE_ID_ACQUIREHANDLEFORCAPTURE_INVALIDARRAY, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMROTATION_NULLPARAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMROTATION_INVALIDSTREAM, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMROTATION_INVALID, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMROTATION_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORGETSTREAMROTATION_NULLPARAM, + D3D11_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDVIEW, + D3D11_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEHULLSHADER_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEEXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_SHADEREXTENSIONSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_MINPRECISION, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMALPHA_UNSUPPORTED, + D3D11_MESSAGE_ID_VIDEOPROCESSORSETSTREAMPIXELASPECTRATIO_UNSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEHULLSHADER_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_UAVSNOTSUPPORTED, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_INVALIDOFFSET, + D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_TOOMANYVIEWS, + D3D11_MESSAGE_ID_DEVICE_CLEARVIEW_NOTSUPPORTED, + D3D11_MESSAGE_ID_SWAPDEVICECONTEXTSTATE_NOTSUPPORTED, + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_PREFERUPDATESUBRESOURCE1, + D3D11_MESSAGE_ID_GETDC_INACCESSIBLE, + D3D11_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDRECT, + D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLE_MASK_IGNORED_ON_FL9, + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE1_NOT_SUPPORTED, + D3D11_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BY_NAME_NOT_SUPPORTED, + D3D11_MESSAGE_ID_ENQUEUESETEVENT_NOT_SUPPORTED, + D3D11_MESSAGE_ID_OFFERRELEASE_NOT_SUPPORTED, + D3D11_MESSAGE_ID_OFFERRESOURCES_INACCESSIBLE, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDMSAA, + D3D11_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDMSAA, + D3D11_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDSOURCERECT, + D3D11_MESSAGE_ID_DEVICE_CLEARVIEW_EMPTYRECT, + D3D11_MESSAGE_ID_UPDATESUBRESOURCE_EMPTYDESTBOX, + D3D11_MESSAGE_ID_COPYSUBRESOURCEREGION_EMPTYSOURCEBOX, + D3D11_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS, + D3D11_MESSAGE_ID_DEVICE_DRAW_DEPTHSTENCILVIEW_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET, + D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET_DUE_TO_FLIP_PRESENT, + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET_DUE_TO_FLIP_PRESENT, + D3D11_MESSAGE_ID_D3D11_1_MESSAGES_END +} D3D11_MESSAGE_ID; + +typedef enum D3D11_RLDO_FLAGS { + D3D11_RLDO_SUMMARY = 1, + D3D11_RLDO_DETAIL = 2 +} D3D11_RLDO_FLAGS; + +typedef struct D3D11_MESSAGE { + D3D11_MESSAGE_CATEGORY Category; + D3D11_MESSAGE_SEVERITY Severity; + D3D11_MESSAGE_ID ID; + const char *pDescription; + SIZE_T DescriptionByteLength; +} D3D11_MESSAGE; + +typedef struct D3D11_INFO_QUEUE_FILTER_DESC { + UINT NumCategories; + D3D11_MESSAGE_CATEGORY *pCategoryList; + UINT NumSeverities; + D3D11_MESSAGE_SEVERITY *pSeverityList; + UINT NumIDs; + D3D11_MESSAGE_ID *pIDList; +} D3D11_INFO_QUEUE_FILTER_DESC; + +typedef struct D3D11_INFO_QUEUE_FILTER { + D3D11_INFO_QUEUE_FILTER_DESC AllowList; + D3D11_INFO_QUEUE_FILTER_DESC DenyList; +} D3D11_INFO_QUEUE_FILTER; + +cpp_quote("#define D3D11_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT 1024") + +[ + object, + uuid(79cf2233-7536-4948-9d36-1e4692dc5760), + local, + pointer_default(unique) +] +interface ID3D11Debug : IUnknown { + HRESULT SetFeatureMask(UINT Mask); + UINT GetFeatureMask(); + HRESULT SetPresentPerRenderOpDelay(UINT Milliseconds); + UINT GetPresentPerRenderOpDelay(); + HRESULT SetSwapChain(IDXGISwapChain *pSwapChain); + HRESULT GetSwapChain(IDXGISwapChain **ppSwapChain); + HRESULT ValidateContext(ID3D11DeviceContext *pContext); + HRESULT ReportLiveDeviceObjects(D3D11_RLDO_FLAGS Flags); + HRESULT ValidateContextForDispatch(ID3D11DeviceContext *pContext); +} + +[ + object, + uuid(6543dbb6-1b48-42f5-ab82-e97ec74326f6), + local, + pointer_default(unique) +] +interface ID3D11InfoQueue : IUnknown { + HRESULT SetMessageCountLimit(UINT64 MessageCountLimit); + void ClearStoredMessages(); + +cpp_quote("#ifdef WINE_NO_UNICODE_MACROS") +cpp_quote("#undef GetMessage") +cpp_quote("#endif") + HRESULT GetMessage(UINT64 MessageIndex, D3D11_MESSAGE* pMessage, SIZE_T *pMessageByteLength); + + UINT64 GetNumMessagesAllowedByStorageFilter(); + UINT64 GetNumMessagesDeniedByStorageFilter(); + UINT64 GetNumStoredMessages(); + UINT64 GetNumStoredMessagesAllowedByRetrievalFilter(); + UINT64 GetNumMessagesDiscardedByMessageCountLimit(); + UINT64 GetMessageCountLimit(); + HRESULT AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *pFilter); + HRESULT GetStorageFilter(D3D11_INFO_QUEUE_FILTER *pFilter, SIZE_T *pFilterByteLength); + void ClearStorageFilter(); + HRESULT PushEmptyStorageFilter(); + HRESULT PushCopyOfStorageFilter(); + HRESULT PushStorageFilter(D3D11_INFO_QUEUE_FILTER *pFilter); + void PopStorageFilter(); + UINT GetStorageFilterStackSize(); + HRESULT AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *pFilter); + HRESULT GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *pFilter, SIZE_T *pFilterByteLength); + void ClearRetrievalFilter(); + HRESULT PushEmptyRetrievalFilter(); + HRESULT PushCopyOfRetrievalFilter(); + HRESULT PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *pFilter); + void PopRetrievalFilter(); + UINT GetRetrievalFilterStackSize(); + HRESULT AddMessage(D3D11_MESSAGE_CATEGORY Category, D3D11_MESSAGE_SEVERITY Severity, + D3D11_MESSAGE_ID ID, LPCSTR pDescription); + HRESULT AddApplicationMessage(D3D11_MESSAGE_SEVERITY Severity, LPCSTR pDescription); + HRESULT SetBreakOnCategory(D3D11_MESSAGE_CATEGORY Category, BOOL bEnable); + HRESULT SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY Severity, BOOL bEnable); + HRESULT SetBreakOnID(D3D11_MESSAGE_ID ID, BOOL bEnable); + BOOL GetBreakOnCategory(D3D11_MESSAGE_CATEGORY Category); + BOOL GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY Severity); + BOOL GetBreakOnID(D3D11_MESSAGE_ID ID); + void SetMuteDebugOutput(BOOL bMute); + BOOL GetMuteDebugOutput(); +} diff --git a/sdk/include/psdk/d3d11shader.h b/sdk/include/psdk/d3d11shader.h index 1c0e8bad6d2..479020abbe5 100644 --- a/sdk/include/psdk/d3d11shader.h +++ b/sdk/include/psdk/d3d11shader.h @@ -174,7 +174,13 @@ DECLARE_INTERFACE(ID3D11ShaderReflectionConstantBuffer) }; #undef INTERFACE +#if D3D_COMPILER_VERSION <= 42 +DEFINE_GUID(IID_ID3D11ShaderReflection, 0x17f27486, 0xa342, 0x4d10, 0x88, 0x42, 0xab, 0x08, 0x74, 0xe7, 0xf6, 0x70); +#elif D3D_COMPILER_VERSION == 43 DEFINE_GUID(IID_ID3D11ShaderReflection, 0x0a233719, 0x3960, 0x4578, 0x9d, 0x7c, 0x20, 0x3b, 0x8b, 0x1d, 0x9c, 0xc1); +#else +DEFINE_GUID(IID_ID3D11ShaderReflection, 0x8d536ca1, 0x0cca, 0x4956, 0xa8, 0x37, 0x78, 0x69, 0x63, 0x75, 0x55, 0x84); +#endif #define INTERFACE ID3D11ShaderReflection DECLARE_INTERFACE_(ID3D11ShaderReflection, IUnknown) @@ -206,4 +212,45 @@ DECLARE_INTERFACE_(ID3D11ShaderReflection, IUnknown) }; #undef INTERFACE +DEFINE_GUID(IID_ID3D11ModuleInstance, 0x469e07f7, 0x45a, 0x48d5, 0xaa, 0x12, 0x68, 0xa4, 0x78, 0xcd, 0xf7, 0x5d); + +#define INTERFACE ID3D11ModuleInstance +DECLARE_INTERFACE_(ID3D11ModuleInstance, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, void **out) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + /* ID3D11ModuleInstance methods */ + STDMETHOD(BindConstantBuffer)(THIS_ UINT srcslot, UINT dstslot, UINT dstoffset) PURE; + STDMETHOD(BindConstantBufferByName)(THIS_ const char *name, UINT dstslot, UINT dstoffset) PURE; + + STDMETHOD(BindResource)(THIS_ UINT srcslot, UINT dstslot, UINT count) PURE; + STDMETHOD(BindResourceByName)(THIS_ const char *name, UINT dstslot, UINT count) PURE; + + STDMETHOD(BindSampler)(THIS_ UINT srcslot, UINT dstslot, UINT count) PURE; + STDMETHOD(BindSamplerByName)(THIS_ const char *name, UINT dstslot, UINT count) PURE; + + STDMETHOD(BindUnorderedAccessView)(THIS_ UINT srcslot, UINT dstslot, UINT count) PURE; + STDMETHOD(BindUnorderedAccessViewByName)(THIS_ const char *name, UINT dstslot, UINT count) PURE; + + STDMETHOD(BindResourceAsUnorderedAccessView)(THIS_ UINT srcslot, UINT dstslot, UINT count) PURE; + STDMETHOD(BindResourceAsUnorderedAccessViewByName)(THIS_ const char *name, UINT dstslot, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D11Module, 0xcac701ee, 0x80fc, 0x4122, 0x82, 0x42, 0x10, 0xb3, 0x9c, 0x8c, 0xec, 0x34); + +#define INTERFACE ID3D11Module +DECLARE_INTERFACE_(ID3D11Module, IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, void **out) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + /* ID3D11Module methods */ + STDMETHOD(CreateInstance)(THIS_ const char *instnamespace, ID3D11ModuleInstance **moduleinstance) PURE; +}; +#undef INTERFACE + #endif diff --git a/sdk/include/psdk/d3d12.idl b/sdk/include/psdk/d3d12.idl new file mode 100644 index 00000000000..201e01f07ef --- /dev/null +++ b/sdk/include/psdk/d3d12.idl @@ -0,0 +1,2185 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi.idl"; +import "d3dcommon.idl"; + +cpp_quote("#ifndef _D3D12_CONSTANTS") +cpp_quote("#define _D3D12_CONSTANTS") + +const UINT D3D12_CS_TGSM_REGISTER_COUNT = 8192; +const UINT D3D12_MAX_ROOT_COST = 64; +const UINT D3D12_VIEWPORT_BOUNDS_MAX = 32767; +const UINT D3D12_VIEWPORT_BOUNDS_MIN = -32768; + +const UINT D3D12_APPEND_ALIGNED_ELEMENT = 0xffffffff; +cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_ALPHA (1.0f)") +cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_BLUE (1.0f)") +cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_GREEN (1.0f)") +cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_RED (1.0f)") +const UINT D3D12_DEFAULT_DEPTH_BIAS = 0; +cpp_quote("#define D3D12_DEFAULT_DEPTH_BIAS_CLAMP (0.0f)") +cpp_quote("#define D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS (0.0f)") +const UINT D3D12_DEFAULT_STENCIL_READ_MASK = 0xff; +const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff; +const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff; +cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)") +const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; +const UINT D3D12_REQ_MIP_LEVELS = 15; +const UINT D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION = 2048; +const UINT D3D12_REQ_TEXTURE1D_U_DIMENSION = 16384; +const UINT D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION = 2048; +const UINT D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION = 16384; +const UINT D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION = 2048; +const UINT D3D12_REQ_TEXTURECUBE_DIMENSION = 16384; +const UINT D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES = 0xffffffff; +const UINT D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT = 8; +const UINT D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT = 256; +const UINT D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT = 65536; +const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256; +const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512; +const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32; +const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; + +cpp_quote("#endif") + +const UINT D3D12_SHADER_COMPONENT_MAPPING_MASK = 0x7; +const UINT D3D12_SHADER_COMPONENT_MAPPING_SHIFT = 3; +const UINT D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES + = 1 << (D3D12_SHADER_COMPONENT_MAPPING_SHIFT * 4); + +typedef enum D3D12_SHADER_MIN_PRECISION_SUPPORT +{ + D3D12_SHADER_MIN_PRECISION_SUPPORT_NONE = 0x0, + D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT = 0x1, + D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT = 0x2, +} D3D12_SHADER_MIN_PRECISION_SUPPORT; + +typedef enum D3D12_TILED_RESOURCES_TIER +{ + D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED = 0, + D3D12_TILED_RESOURCES_TIER_1 = 1, + D3D12_TILED_RESOURCES_TIER_2 = 2, + D3D12_TILED_RESOURCES_TIER_3 = 3, +} D3D12_TILED_RESOURCES_TIER; + +typedef enum D3D12_RESOURCE_BINDING_TIER +{ + D3D12_RESOURCE_BINDING_TIER_1 = 1, + D3D12_RESOURCE_BINDING_TIER_2 = 2, + D3D12_RESOURCE_BINDING_TIER_3 = 3, +} D3D12_RESOURCE_BINDING_TIER; + +typedef enum D3D12_CONSERVATIVE_RASTERIZATION_TIER +{ + D3D12_CONSERVATIVE_RASTERIZATION_TIER_NOT_SUPPORTED = 0, + D3D12_CONSERVATIVE_RASTERIZATION_TIER_1 = 1, + D3D12_CONSERVATIVE_RASTERIZATION_TIER_2 = 2, + D3D12_CONSERVATIVE_RASTERIZATION_TIER_3 = 3, +} D3D12_CONSERVATIVE_RASTERIZATION_TIER; + +typedef enum D3D12_CROSS_NODE_SHARING_TIER +{ + D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED = 0, + D3D12_CROSS_NODE_SHARING_TIER_1_EMULATED = 1, + D3D12_CROSS_NODE_SHARING_TIER_1 = 2, + D3D12_CROSS_NODE_SHARING_TIER_2 = 3, +} D3D12_CROSS_NODE_SHARING_TIER; + +typedef enum D3D12_RESOURCE_HEAP_TIER +{ + D3D12_RESOURCE_HEAP_TIER_1 = 1, + D3D12_RESOURCE_HEAP_TIER_2 = 2, +} D3D12_RESOURCE_HEAP_TIER; + +typedef enum D3D12_FORMAT_SUPPORT1 +{ + D3D12_FORMAT_SUPPORT1_NONE = 0x00000000, + D3D12_FORMAT_SUPPORT1_BUFFER = 0x00000001, + D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER = 0x00000002, + D3D12_FORMAT_SUPPORT1_IA_INDEX_BUFFER = 0x00000004, + D3D12_FORMAT_SUPPORT1_SO_BUFFER = 0x00000008, + D3D12_FORMAT_SUPPORT1_TEXTURE1D = 0x00000010, + D3D12_FORMAT_SUPPORT1_TEXTURE2D = 0x00000020, + D3D12_FORMAT_SUPPORT1_TEXTURE3D = 0x00000040, + D3D12_FORMAT_SUPPORT1_TEXTURECUBE = 0x00000080, + D3D12_FORMAT_SUPPORT1_SHADER_LOAD = 0x00000100, + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE = 0x00000200, + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_COMPARISON = 0x00000400, + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_MONO_TEXT = 0x00000800, + D3D12_FORMAT_SUPPORT1_MIP = 0x00001000, + D3D12_FORMAT_SUPPORT1_RENDER_TARGET = 0x00004000, + D3D12_FORMAT_SUPPORT1_BLENDABLE = 0x00008000, + D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL = 0x00010000, + D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE = 0x00040000, + D3D12_FORMAT_SUPPORT1_DISPLAY = 0x00080000, + D3D12_FORMAT_SUPPORT1_CAST_WITHIN_BIT_LAYOUT = 0x00100000, + D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET = 0x00200000, + D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD = 0x00400000, + D3D12_FORMAT_SUPPORT1_SHADER_GATHER = 0x00800000, + D3D12_FORMAT_SUPPORT1_BACK_BUFFER_CAST = 0x01000000, + D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW = 0x02000000, + D3D12_FORMAT_SUPPORT1_SHADER_GATHER_COMPARISON = 0x04000000, + D3D12_FORMAT_SUPPORT1_DECODER_OUTPUT = 0x08000000, + D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_OUTPUT = 0x10000000, + D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_INPUT = 0x20000000, + D3D12_FORMAT_SUPPORT1_VIDEO_ENCODER = 0x40000000, +} D3D12_FORMAT_SUPPORT1; + +typedef enum D3D12_FORMAT_SUPPORT2 +{ + D3D12_FORMAT_SUPPORT2_NONE = 0x00000000, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD = 0x00000001, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS = 0x00000002, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 0x00000004, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE = 0x00000008, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX = 0x00000010, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 0x00000020, + D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x00000040, + D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x00000080, + D3D12_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x00000100, + D3D12_FORMAT_SUPPORT2_TILED = 0x00000200, + D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x00004000, +} D3D12_FORMAT_SUPPORT2; + +interface ID3D12Fence; +interface ID3D12RootSignature; +interface ID3D12Heap; +interface ID3D12DescriptorHeap; +interface ID3D12Resource; +interface ID3D12CommandAllocator; +interface ID3D12GraphicsCommandList; +interface ID3D12CommandQueue; +interface ID3D12PipelineState; +interface ID3D12Device; + +typedef RECT D3D12_RECT; + +typedef struct D3D12_BOX +{ + UINT left; + UINT top; + UINT front; + UINT right; + UINT bottom; + UINT back; +} D3D12_BOX; + +typedef struct D3D12_VIEWPORT +{ + FLOAT TopLeftX; + FLOAT TopLeftY; + FLOAT Width; + FLOAT Height; + FLOAT MinDepth; + FLOAT MaxDepth; +} D3D12_VIEWPORT; + +typedef struct D3D12_RANGE +{ + SIZE_T Begin; + SIZE_T End; +} D3D12_RANGE; + +typedef struct D3D12_RESOURCE_ALLOCATION_INFO +{ + UINT64 SizeInBytes; + UINT64 Alignment; +} D3D12_RESOURCE_ALLOCATION_INFO; + +typedef struct D3D12_DRAW_ARGUMENTS +{ + UINT VertexCountPerInstance; + UINT InstanceCount; + UINT StartVertexLocation; + UINT StartInstanceLocation; +} D3D12_DRAW_ARGUMENTS; + +typedef struct D3D12_DRAW_INDEXED_ARGUMENTS +{ + UINT IndexCountPerInstance; + UINT InstanceCount; + UINT StartIndexLocation; + INT BaseVertexLocation; + UINT StartInstanceLocation; +} D3D12_DRAW_INDEXED_ARGUMENTS; + +typedef struct D3D12_DISPATCH_ARGUMENTS +{ + UINT ThreadGroupCountX; + UINT ThreadGroupCountY; + UINT ThreadGroupCountZ; +} D3D12_DISPATCH_ARGUMENTS; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS +{ + BOOL DoublePrecisionFloatShaderOps; + BOOL OutputMergerLogicOp; + D3D12_SHADER_MIN_PRECISION_SUPPORT MinPrecisionSupport; + D3D12_TILED_RESOURCES_TIER TiledResourcesTier; + D3D12_RESOURCE_BINDING_TIER ResourceBindingTier; + BOOL PSSpecifiedStencilRefSupported; + BOOL TypedUAVLoadAdditionalFormats; + BOOL ROVsSupported; + D3D12_CONSERVATIVE_RASTERIZATION_TIER ConservativeRasterizationTier; + UINT MaxGPUVirtualAddressBitsPerResource; + BOOL StandardSwizzle64KBSupported; + D3D12_CROSS_NODE_SHARING_TIER CrossNodeSharingTier; + BOOL CrossAdapterRowMajorTextureSupported; + BOOL VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation; + D3D12_RESOURCE_HEAP_TIER ResourceHeapTier; +} D3D12_FEATURE_DATA_D3D12_OPTIONS; + +typedef struct D3D12_FEATURE_DATA_FORMAT_SUPPORT +{ + DXGI_FORMAT Format; + D3D12_FORMAT_SUPPORT1 Support1; + D3D12_FORMAT_SUPPORT2 Support2; +} D3D12_FEATURE_DATA_FORMAT_SUPPORT; + +typedef enum D3D12_HEAP_TYPE +{ + D3D12_HEAP_TYPE_DEFAULT = 1, + D3D12_HEAP_TYPE_UPLOAD = 2, + D3D12_HEAP_TYPE_READBACK = 3, + D3D12_HEAP_TYPE_CUSTOM = 4, +} D3D12_HEAP_TYPE; + +typedef enum D3D12_CPU_PAGE_PROPERTY +{ + D3D12_CPU_PAGE_PROPERTY_UNKNOWN = 0, + D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE = 2, + D3D12_CPU_PAGE_PROPERTY_WRITE_BACK = 3, +} D3D12_CPU_PAGE_PROPERTY; + +typedef enum D3D12_MEMORY_POOL +{ + D3D12_MEMORY_POOL_UNKNOWN = 0, + D3D12_MEMORY_POOL_L0 = 1, + D3D12_MEMORY_POOL_L1 = 2, +} D3D12_MEMORY_POOL; + +typedef struct D3D12_HEAP_PROPERTIES +{ + D3D12_HEAP_TYPE Type; + D3D12_CPU_PAGE_PROPERTY CPUPageProperty; + D3D12_MEMORY_POOL MemoryPoolPreference; + UINT CreationNodeMask; + UINT VisibleNodeMask; +} D3D12_HEAP_PROPERTIES; + +typedef enum D3D12_HEAP_FLAGS +{ + D3D12_HEAP_FLAG_NONE = 0x00, + D3D12_HEAP_FLAG_SHARED = 0x01, + D3D12_HEAP_FLAG_DENY_BUFFERS = 0x04, + D3D12_HEAP_FLAG_ALLOW_DISPLAY = 0x08, + D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER = 0x20, + D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES = 0x40, + D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES = 0x80, + D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES = 0x00, + D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS = 0xc0, + D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES = 0x44, + D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES = 0x84, +} D3D12_HEAP_FLAGS; + +typedef struct D3D12_HEAP_DESC +{ + UINT64 SizeInBytes; + D3D12_HEAP_PROPERTIES Properties; + UINT64 Alignment; + D3D12_HEAP_FLAGS Flags; +} D3D12_HEAP_DESC; + +typedef struct D3D12_TILED_RESOURCE_COORDINATE +{ + UINT X; + UINT Y; + UINT Z; + UINT Subresource; +} D3D12_TILED_RESOURCE_COORDINATE; + +typedef struct D3D12_TILE_REGION_SIZE +{ + UINT NumTiles; + BOOL UseBox; + UINT Width; + UINT16 Height; + UINT16 Depth; +} D3D12_TILE_REGION_SIZE; + +typedef struct D3D12_SUBRESOURCE_TILING +{ + UINT WidthInTiles; + UINT16 HeightInTiles; + UINT16 DepthInTiles; + UINT StartTileIndexInOverallResource; +} D3D12_SUBRESOURCE_TILING; + +typedef struct D3D12_TILE_SHAPE +{ + UINT WidthInTexels; + UINT HeightInTexels; + UINT DepthInTexels; +} D3D12_TILE_SHAPE; + +typedef struct D3D12_SHADER_BYTECODE +{ + const void *pShaderBytecode; + SIZE_T BytecodeLength; +} D3D12_SHADER_BYTECODE; + +typedef struct D3D12_DEPTH_STENCIL_VALUE +{ + FLOAT Depth; + UINT8 Stencil; +} D3D12_DEPTH_STENCIL_VALUE; + +typedef struct D3D12_CLEAR_VALUE +{ + DXGI_FORMAT Format; + union + { + FLOAT Color[4]; + D3D12_DEPTH_STENCIL_VALUE DepthStencil; + }; +} D3D12_CLEAR_VALUE; + +typedef struct D3D12_PACKED_MIP_INFO +{ + UINT8 NumStandardMips; + UINT8 NumPackedMips; + UINT NumTilesForPackedMips; + UINT StartTileIndexInOverallResource; +} D3D12_PACKED_MIP_INFO; + +typedef enum D3D12_RESOURCE_STATES +{ + D3D12_RESOURCE_STATE_COMMON = 0, + D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER = 0x1, + D3D12_RESOURCE_STATE_INDEX_BUFFER = 0x2, + D3D12_RESOURCE_STATE_RENDER_TARGET = 0x4, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS = 0x8, + D3D12_RESOURCE_STATE_DEPTH_WRITE = 0x10, + D3D12_RESOURCE_STATE_DEPTH_READ = 0x20, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE = 0x40, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE = 0x80, + D3D12_RESOURCE_STATE_STREAM_OUT = 0x100, + D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT = 0x200, + D3D12_RESOURCE_STATE_COPY_DEST = 0x400, + D3D12_RESOURCE_STATE_COPY_SOURCE = 0x800, + D3D12_RESOURCE_STATE_RESOLVE_DEST = 0x1000, + D3D12_RESOURCE_STATE_RESOLVE_SOURCE = 0x2000, + D3D12_RESOURCE_STATE_GENERIC_READ = 0x1 | 0x2 | 0x40 | 0x80 | 0x200 | 0x800, + D3D12_RESOURCE_STATE_PRESENT = 0x0, + D3D12_RESOURCE_STATE_PREDICATION = 0x200, +} D3D12_RESOURCE_STATES; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESOURCE_STATES);") + +typedef enum D3D12_RESOURCE_BARRIER_TYPE +{ + D3D12_RESOURCE_BARRIER_TYPE_TRANSITION = 0, + D3D12_RESOURCE_BARRIER_TYPE_ALIASING = 1, + D3D12_RESOURCE_BARRIER_TYPE_UAV = 2, +} D3D12_RESOURCE_BARRIER_TYPE; + +typedef enum D3D12_RESOURCE_BARRIER_FLAGS +{ + D3D12_RESOURCE_BARRIER_FLAG_NONE = 0x0, + D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY = 0x1, + D3D12_RESOURCE_BARRIER_FLAG_END_ONLY = 0x2, +} D3D12_RESOURCE_BARRIER_FLAGS; + +typedef struct D3D12_RESOURCE_TRANSITION_BARRIER +{ + ID3D12Resource *pResource; + UINT Subresource; + D3D12_RESOURCE_STATES StateBefore; + D3D12_RESOURCE_STATES StateAfter; +} D3D12_RESOURCE_TRANSITION_BARRIER; + +typedef struct D3D12_RESOURCE_ALIASING_BARRIER_ALIASING +{ + ID3D12Resource *pResourceBefore; + ID3D12Resource *pResourceAfter; +} D3D12_RESOURCE_ALIASING_BARRIER; + +typedef struct D3D12_RESOURCE_UAV_BARRIER +{ + ID3D12Resource *pResource; +} D3D12_RESOURCE_UAV_BARRIER; + +typedef struct D3D12_RESOURCE_BARRIER +{ + D3D12_RESOURCE_BARRIER_TYPE Type; + D3D12_RESOURCE_BARRIER_FLAGS Flags; + union + { + D3D12_RESOURCE_TRANSITION_BARRIER Transition; + D3D12_RESOURCE_ALIASING_BARRIER Aliasing; + D3D12_RESOURCE_UAV_BARRIER UAV; + }; +} D3D12_RESOURCE_BARRIER; + +typedef enum D3D12_RESOURCE_DIMENSION +{ + D3D12_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D12_RESOURCE_DIMENSION_BUFFER = 1, + D3D12_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D12_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D12_RESOURCE_DIMENSION_TEXTURE3D = 4, +} D3D12_RESOURCE_DIMENSION; + +typedef enum D3D12_TEXTURE_LAYOUT +{ + D3D12_TEXTURE_LAYOUT_UNKNOWN = 0, + D3D12_TEXTURE_LAYOUT_ROW_MAJOR = 1, + D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE = 2, + D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE = 3, +} D3D12_TEXTURE_LAYOUT; + +typedef enum D3D12_RESOURCE_FLAGS +{ + D3D12_RESOURCE_FLAG_NONE = 0x0, + D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET = 0x1, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL = 0x2, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS = 0x4, + D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE = 0x8, + D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER = 0x10, + D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS = 0x20, +} D3D12_RESOURCE_FLAGS; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESOURCE_FLAGS);") + +typedef struct D3D12_RESOURCE_DESC +{ + D3D12_RESOURCE_DIMENSION Dimension; + UINT64 Alignment; + UINT64 Width; + UINT Height; + UINT16 DepthOrArraySize; + UINT16 MipLevels; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D12_TEXTURE_LAYOUT Layout; + D3D12_RESOURCE_FLAGS Flags; +} D3D12_RESOURCE_DESC; + +typedef enum D3D12_TEXTURE_COPY_TYPE +{ + D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX = 0, + D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT = 1, +} D3D12_TEXTURE_COPY_TYPE; + +typedef struct D3D12_SUBRESOURCE_FOOTPRINT +{ + DXGI_FORMAT Format; + UINT Width; + UINT Height; + UINT Depth; + UINT RowPitch; +} D3D12_SUBRESOURCE_FOOTPRINT; + +typedef struct D3D12_PLACED_SUBRESOURCE_FOOTPRINT +{ + UINT64 Offset; + D3D12_SUBRESOURCE_FOOTPRINT Footprint; +} D3D12_PLACED_SUBRESOURCE_FOOTPRINT; + +typedef struct D3D12_TEXTURE_COPY_LOCATION +{ + ID3D12Resource *pResource; + D3D12_TEXTURE_COPY_TYPE Type; + union + { + D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint; + UINT SubresourceIndex; + }; +} D3D12_TEXTURE_COPY_LOCATION; + +typedef enum D3D12_DESCRIPTOR_RANGE_TYPE +{ + D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, + D3D12_DESCRIPTOR_RANGE_TYPE_UAV = 1, + D3D12_DESCRIPTOR_RANGE_TYPE_CBV = 2, + D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3, +} D3D12_DESCRIPTOR_RANGE_TYPE; + +typedef struct D3D12_DESCRIPTOR_RANGE +{ + D3D12_DESCRIPTOR_RANGE_TYPE RangeType; + UINT NumDescriptors; + UINT BaseShaderRegister; + UINT RegisterSpace; + UINT OffsetInDescriptorsFromTableStart; +} D3D12_DESCRIPTOR_RANGE; + +typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS +{ + D3D12_DESCRIPTOR_RANGE_FLAG_NONE = 0, +} D3D12_DESCRIPTOR_RANGE_FLAGS; + +typedef struct D3D12_DESCRIPTOR_RANGE1 +{ + D3D12_DESCRIPTOR_RANGE_TYPE RangeType; + UINT NumDescriptors; + UINT BaseShaderRegister; + UINT RegisterSpace; + D3D12_DESCRIPTOR_RANGE_FLAGS Flags; + UINT OffsetInDescriptorsFromTableStart; +} D3D12_DESCRIPTOR_RANGE1; + +typedef struct D3D12_ROOT_DESCRIPTOR_TABLE +{ + UINT NumDescriptorRanges; + const D3D12_DESCRIPTOR_RANGE *pDescriptorRanges; +} D3D12_ROOT_DESCRIPTOR_TABLE; + +typedef struct D3D12_ROOT_DESCRIPTOR_TABLE1 +{ + UINT NumDescriptorRanges; + const D3D12_DESCRIPTOR_RANGE1 *pDescriptorRanges; +} D3D12_ROOT_DESCRIPTOR_TABLE1; + +typedef struct D3D12_ROOT_CONSTANTS +{ + UINT ShaderRegister; + UINT RegisterSpace; + UINT Num32BitValues; +} D3D12_ROOT_CONSTANTS; + +typedef struct D3D12_ROOT_DESCRIPTOR +{ + UINT ShaderRegister; + UINT RegisterSpace; +} D3D12_ROOT_DESCRIPTOR; + +typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS +{ + D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0, +} D3D12_ROOT_DESCRIPTOR_FLAGS; + +typedef struct D3D12_ROOT_DESCRIPTOR1 +{ + UINT ShaderRegister; + UINT RegisterSpace; + D3D12_ROOT_DESCRIPTOR_FLAGS Flags; +} D3D12_ROOT_DESCRIPTOR1; + +typedef enum D3D12_ROOT_PARAMETER_TYPE +{ + D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE = 0, + D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS = 1, + D3D12_ROOT_PARAMETER_TYPE_CBV = 2, + D3D12_ROOT_PARAMETER_TYPE_SRV = 3, + D3D12_ROOT_PARAMETER_TYPE_UAV = 4, +} D3D12_ROOT_PARAMETER_TYPE; + +typedef enum D3D12_SHADER_VISIBILITY +{ + D3D12_SHADER_VISIBILITY_ALL = 0, + D3D12_SHADER_VISIBILITY_VERTEX = 1, + D3D12_SHADER_VISIBILITY_HULL = 2, + D3D12_SHADER_VISIBILITY_DOMAIN = 3, + D3D12_SHADER_VISIBILITY_GEOMETRY = 4, + D3D12_SHADER_VISIBILITY_PIXEL = 5, +} D3D12_SHADER_VISIBILITY; + +typedef struct D3D12_ROOT_PARAMETER +{ + D3D12_ROOT_PARAMETER_TYPE ParameterType; + union + { + D3D12_ROOT_DESCRIPTOR_TABLE DescriptorTable; + D3D12_ROOT_CONSTANTS Constants; + D3D12_ROOT_DESCRIPTOR Descriptor; + }; + D3D12_SHADER_VISIBILITY ShaderVisibility; +} D3D12_ROOT_PARAMETER; + +typedef struct D3D12_ROOT_PARAMETER1 +{ + D3D12_ROOT_PARAMETER_TYPE ParameterType; + union + { + D3D12_ROOT_DESCRIPTOR_TABLE1 DescriptorTable; + D3D12_ROOT_CONSTANTS Constants; + D3D12_ROOT_DESCRIPTOR1 Descriptor; + }; + D3D12_SHADER_VISIBILITY ShaderVisibility; +} D3D12_ROOT_PARAMETER1; + +typedef enum D3D12_STATIC_BORDER_COLOR +{ + D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK = 0, + D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK = 1, + D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE = 2, +} D3D12_STATIC_BORDER_COLOR; + +typedef enum D3D12_FILTER +{ + D3D12_FILTER_MIN_MAG_MIP_POINT = 0x00, + D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x01, + D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x04, + D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x05, + D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, + D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, + D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, + D3D12_FILTER_MIN_MAG_MIP_LINEAR = 0x15, + D3D12_FILTER_ANISOTROPIC = 0x55, + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, + D3D12_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, + D3D12_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, + D3D12_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, + D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, + D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, + D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, + D3D12_FILTER_COMPARISON_ANISOTROPIC = 0xd5, + D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT = 0x100, + D3D12_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x101, + D3D12_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x104, + D3D12_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x105, + D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x110, + D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x111, + D3D12_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x114, + D3D12_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR = 0x115, + D3D12_FILTER_MINIMUM_ANISOTROPIC = 0x155, + D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT = 0x180, + D3D12_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x181, + D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x184, + D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x185, + D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x190, + D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x191, + D3D12_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x194, + D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR = 0x195, + D3D12_FILTER_MAXIMUM_ANISOTROPIC = 0x1d5, +} D3D12_FILTER; + +typedef enum D3D12_FILTER_TYPE +{ + D3D12_FILTER_TYPE_POINT = 0, + D3D12_FILTER_TYPE_LINEAR = 1, +} D3D12_FILTER_TYPE; + +const UINT D3D12_MIP_FILTER_SHIFT = 0; +const UINT D3D12_MAG_FILTER_SHIFT = 2; +const UINT D3D12_MIN_FILTER_SHIFT = 4; +const UINT D3D12_FILTER_TYPE_MASK = 0x3; + +const UINT D3D12_ANISOTROPIC_FILTERING_BIT = 0x40; + +typedef enum D3D12_FILTER_REDUCTION_TYPE +{ + D3D12_FILTER_REDUCTION_TYPE_STANDARD = 0, + D3D12_FILTER_REDUCTION_TYPE_COMPARISON = 1, + D3D12_FILTER_REDUCTION_TYPE_MINIMUM = 2, + D3D12_FILTER_REDUCTION_TYPE_MAXIMUM = 3, +} D3D12_FILTER_REDUCTION_TYPE; + +const UINT D3D12_FILTER_REDUCTION_TYPE_MASK = 0x3; +const UINT D3D12_FILTER_REDUCTION_TYPE_SHIFT = 7; + +cpp_quote("#define D3D12_DECODE_MAG_FILTER(filter) \\") +cpp_quote(" ((D3D12_FILTER_TYPE)(((filter) >> D3D12_MAG_FILTER_SHIFT) & D3D12_FILTER_TYPE_MASK))") + +cpp_quote("#define D3D12_DECODE_MIN_FILTER(filter) \\") +cpp_quote(" ((D3D12_FILTER_TYPE)(((filter) >> D3D12_MIN_FILTER_SHIFT) & D3D12_FILTER_TYPE_MASK))") + +cpp_quote("#define D3D12_DECODE_MIP_FILTER(filter) \\") +cpp_quote(" ((D3D12_FILTER_TYPE)(((filter) >> D3D12_MIP_FILTER_SHIFT) & D3D12_FILTER_TYPE_MASK))") + +cpp_quote("#define D3D12_DECODE_IS_ANISOTROPIC_FILTER(filter) \\") +cpp_quote(" (((filter) & D3D12_ANISOTROPIC_FILTERING_BIT) \\") +cpp_quote(" && (D3D12_DECODE_MIN_FILTER(filter) == D3D12_FILTER_TYPE_LINEAR) \\") +cpp_quote(" && (D3D12_DECODE_MAG_FILTER(filter) == D3D12_FILTER_TYPE_LINEAR) \\") +cpp_quote(" && (D3D12_DECODE_MIP_FILTER(filter) == D3D12_FILTER_TYPE_LINEAR))") + +cpp_quote("#define D3D12_DECODE_FILTER_REDUCTION(filter) \\") +cpp_quote(" ((D3D12_FILTER_REDUCTION_TYPE)(((filter) >> D3D12_FILTER_REDUCTION_TYPE_SHIFT) \\") +cpp_quote(" & D3D12_FILTER_REDUCTION_TYPE_MASK))") + +cpp_quote("#define D3D12_DECODE_IS_COMPARISON_FILTER(filter) \\") +cpp_quote(" (D3D12_DECODE_FILTER_REDUCTION(filter) == D3D12_FILTER_REDUCTION_TYPE_COMPARISON)") + +typedef enum D3D12_TEXTURE_ADDRESS_MODE +{ + D3D12_TEXTURE_ADDRESS_MODE_WRAP = 1, + D3D12_TEXTURE_ADDRESS_MODE_MIRROR = 2, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP = 3, + D3D12_TEXTURE_ADDRESS_MODE_BORDER = 4, + D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE = 5, +} D3D12_TEXTURE_ADDRESS_MODE; + +typedef enum D3D12_COMPARISON_FUNC +{ + D3D12_COMPARISON_FUNC_NEVER = 1, + D3D12_COMPARISON_FUNC_LESS = 2, + D3D12_COMPARISON_FUNC_EQUAL = 3, + D3D12_COMPARISON_FUNC_LESS_EQUAL = 4, + D3D12_COMPARISON_FUNC_GREATER = 5, + D3D12_COMPARISON_FUNC_NOT_EQUAL = 6, + D3D12_COMPARISON_FUNC_GREATER_EQUAL = 7, + D3D12_COMPARISON_FUNC_ALWAYS = 8, +} D3D12_COMPARISON_FUNC; + +typedef struct D3D12_STATIC_SAMPLER_DESC +{ + D3D12_FILTER Filter; + D3D12_TEXTURE_ADDRESS_MODE AddressU; + D3D12_TEXTURE_ADDRESS_MODE AddressV; + D3D12_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D12_COMPARISON_FUNC ComparisonFunc; + D3D12_STATIC_BORDER_COLOR BorderColor; + FLOAT MinLOD; + FLOAT MaxLOD; + UINT ShaderRegister; + UINT RegisterSpace; + D3D12_SHADER_VISIBILITY ShaderVisibility; +} D3D12_STATIC_SAMPLER_DESC; + +typedef enum D3D12_ROOT_SIGNATURE_FLAGS +{ + D3D12_ROOT_SIGNATURE_FLAG_NONE = 0x00, + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT = 0x01, + D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS = 0x02, + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS = 0x04, + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS = 0x08, + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS = 0x10, + D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20, + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40, +} D3D12_ROOT_SIGNATURE_FLAGS; + +typedef struct D3D12_ROOT_SIGNATURE_DESC +{ + UINT NumParameters; + const D3D12_ROOT_PARAMETER *pParameters; + UINT NumStaticSamplers; + const D3D12_STATIC_SAMPLER_DESC *pStaticSamplers; + D3D12_ROOT_SIGNATURE_FLAGS Flags; +} D3D12_ROOT_SIGNATURE_DESC; + +typedef struct D3D12_ROOT_SIGNATURE_DESC1 +{ + UINT NumParameters; + const D3D12_ROOT_PARAMETER1 *pParameters; + UINT NumStaticSamplers; + const D3D12_STATIC_SAMPLER_DESC *pStaticSamplers; + D3D12_ROOT_SIGNATURE_FLAGS Flags; +} D3D12_ROOT_SIGNATURE_DESC1; + +typedef enum D3D_ROOT_SIGNATURE_VERSION +{ + D3D_ROOT_SIGNATURE_VERSION_1 = 0x1, + D3D_ROOT_SIGNATURE_VERSION_1_0 = 0x1, + D3D_ROOT_SIGNATURE_VERSION_1_1 = 0x2, +} D3D_ROOT_SIGNATURE_VERSION; + +typedef struct D3D12_VERSIONED_ROOT_SIGNATURE_DESC +{ + D3D_ROOT_SIGNATURE_VERSION Version; + union + { + D3D12_ROOT_SIGNATURE_DESC Desc_1_0; + D3D12_ROOT_SIGNATURE_DESC1 Desc_1_1; + }; +} D3D12_VERSIONED_ROOT_SIGNATURE_DESC; + +typedef enum D3D12_DESCRIPTOR_HEAP_TYPE +{ + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, + D3D12_DESCRIPTOR_HEAP_TYPE_RTV, + D3D12_DESCRIPTOR_HEAP_TYPE_DSV, + D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, +} D3D12_DESCRIPTOR_HEAP_TYPE; + +typedef enum D3D12_DESCRIPTOR_HEAP_FLAGS +{ + D3D12_DESCRIPTOR_HEAP_FLAG_NONE = 0x0, + D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE = 0x1, +} D3D12_DESCRIPTOR_HEAP_FLAGS; + +typedef struct D3D12_DESCRIPTOR_HEAP_DESC +{ + D3D12_DESCRIPTOR_HEAP_TYPE Type; + UINT NumDescriptors; + D3D12_DESCRIPTOR_HEAP_FLAGS Flags; + UINT NodeMask; +} D3D12_DESCRIPTOR_HEAP_DESC; + +typedef UINT64 D3D12_GPU_VIRTUAL_ADDRESS; + +typedef struct D3D12_CONSTANT_BUFFER_VIEW_DESC +{ + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT SizeInBytes; +} D3D12_CONSTANT_BUFFER_VIEW_DESC; + +typedef enum D3D12_SRV_DIMENSION +{ + D3D12_SRV_DIMENSION_UNKNOWN = 0, + D3D12_SRV_DIMENSION_BUFFER = 1, + D3D12_SRV_DIMENSION_TEXTURE1D = 2, + D3D12_SRV_DIMENSION_TEXTURE1DARRAY = 3, + D3D12_SRV_DIMENSION_TEXTURE2D = 4, + D3D12_SRV_DIMENSION_TEXTURE2DARRAY = 5, + D3D12_SRV_DIMENSION_TEXTURE2DMS = 6, + D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D12_SRV_DIMENSION_TEXTURE3D = 8, + D3D12_SRV_DIMENSION_TEXTURECUBE = 9, + D3D12_SRV_DIMENSION_TEXTURECUBEARRAY = 10, +} D3D12_SRV_DIMENSION; + +typedef enum D3D12_BUFFER_SRV_FLAGS +{ + D3D12_BUFFER_SRV_FLAG_NONE = 0x0, + D3D12_BUFFER_SRV_FLAG_RAW = 0x1, +} D3D12_BUFFER_SRV_FLAGS; + +typedef enum D3D12_SHADER_COMPONENT_MAPPING +{ + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0 = 0, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1 = 1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2 = 2, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3 = 3, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0 = 4, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1 = 5, +} D3D12_SHADER_COMPONENT_MAPPING; + +cpp_quote("#define D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(x, y, z, w) \\") +cpp_quote(" (((x) & D3D12_SHADER_COMPONENT_MAPPING_MASK) \\") +cpp_quote(" | (((y) & D3D12_SHADER_COMPONENT_MAPPING_MASK) << D3D12_SHADER_COMPONENT_MAPPING_SHIFT) \\") +cpp_quote(" | (((z) & D3D12_SHADER_COMPONENT_MAPPING_MASK) << (D3D12_SHADER_COMPONENT_MAPPING_SHIFT * 2)) \\") +cpp_quote(" | (((w) & D3D12_SHADER_COMPONENT_MAPPING_MASK) << (D3D12_SHADER_COMPONENT_MAPPING_SHIFT * 3)) \\") +cpp_quote(" | D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES)") +cpp_quote("#define D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(0, 1, 2, 3)") + +typedef struct D3D12_BUFFER_SRV +{ + UINT64 FirstElement; + UINT NumElements; + UINT StructureByteStride; + D3D12_BUFFER_SRV_FLAGS Flags; +} D3D12_BUFFER_SRV; + +typedef struct D3D12_TEX1D_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + FLOAT ResourceMinLODClamp; +} D3D12_TEX1D_SRV; + +typedef struct D3D12_TEX1D_ARRAY_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + FLOAT ResourceMinLODClamp; +} D3D12_TEX1D_ARRAY_SRV; + +typedef struct D3D12_TEX2D_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT PlaneSlice; + FLOAT ResourceMinLODClamp; +} D3D12_TEX2D_SRV; + +typedef struct D3D12_TEX2D_ARRAY_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; + FLOAT ResourceMinLODClamp; +} D3D12_TEX2D_ARRAY_SRV; + +typedef struct D3D12_TEX2DMS_SRV +{ + UINT UnusedField_NothingToDefine; +} D3D12_TEX2DMS_SRV; + +typedef struct D3D12_TEX2DMS_ARRAY_SRV +{ + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX2DMS_ARRAY_SRV; + +typedef struct D3D12_TEX3D_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + FLOAT ResourceMinLODClamp; +} D3D12_TEX3D_SRV; + +typedef struct D3D12_TEXCUBE_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + FLOAT ResourceMinLODClamp; +} D3D12_TEXCUBE_SRV; + +typedef struct D3D12_TEXCUBE_ARRAY_SRV +{ + UINT MostDetailedMip; + UINT MipLevels; + UINT First2DArrayFace; + UINT NumCubes; + FLOAT ResourceMinLODClamp; +} D3D12_TEXCUBE_ARRAY_SRV; + +typedef struct D3D12_SHADER_RESOURCE_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D12_SRV_DIMENSION ViewDimension; + UINT Shader4ComponentMapping; + union + { + D3D12_BUFFER_SRV Buffer; + D3D12_TEX1D_SRV Texture1D; + D3D12_TEX1D_ARRAY_SRV Texture1DArray; + D3D12_TEX2D_SRV Texture2D; + D3D12_TEX2D_ARRAY_SRV Texture2DArray; + D3D12_TEX2DMS_SRV Texture2DMS; + D3D12_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D12_TEX3D_SRV Texture3D; + D3D12_TEXCUBE_SRV TextureCube; + D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray; + }; +} D3D12_SHADER_RESOURCE_VIEW_DESC; + +typedef enum D3D12_UAV_DIMENSION +{ + D3D12_UAV_DIMENSION_UNKNOWN = 0, + D3D12_UAV_DIMENSION_BUFFER = 1, + D3D12_UAV_DIMENSION_TEXTURE1D = 2, + D3D12_UAV_DIMENSION_TEXTURE1DARRAY = 3, + D3D12_UAV_DIMENSION_TEXTURE2D = 4, + D3D12_UAV_DIMENSION_TEXTURE2DARRAY = 5, + D3D12_UAV_DIMENSION_TEXTURE3D = 8, +} D3D12_UAV_DIMENSION; + +typedef enum D3D12_BUFFER_UAV_FLAGS +{ + D3D12_BUFFER_UAV_FLAG_NONE = 0x0, + D3D12_BUFFER_UAV_FLAG_RAW = 0x1, +} D3D12_BUFFER_UAV_FLAGS; + +typedef struct D3D12_BUFFER_UAV +{ + UINT64 FirstElement; + UINT NumElements; + UINT StructureByteStride; + UINT64 CounterOffsetInBytes; + D3D12_BUFFER_UAV_FLAGS Flags; +} D3D12_BUFFER_UAV; + +typedef struct D3D12_TEX1D_UAV +{ + UINT MipSlice; +} D3D12_TEX1D_UAV; + +typedef struct D3D12_TEX1D_ARRAY_UAV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX1D_ARRAY_UAV; + +typedef struct D3D12_TEX2D_UAV +{ + UINT MipSlice; + UINT PlaneSlice; +} D3D12_TEX2D_UAV; + +typedef struct D3D12_TEX2D_ARRAY_UAV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; +} D3D12_TEX2D_ARRAY_UAV; + +typedef struct D3D12_TEX3D_UAV +{ + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; +} D3D12_TEX3D_UAV; + +typedef struct D3D12_UNORDERED_ACCESS_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D12_UAV_DIMENSION ViewDimension; + union + { + D3D12_BUFFER_UAV Buffer; + D3D12_TEX1D_UAV Texture1D; + D3D12_TEX1D_ARRAY_UAV Texture1DArray; + D3D12_TEX2D_UAV Texture2D; + D3D12_TEX2D_ARRAY_UAV Texture2DArray; + D3D12_TEX3D_UAV Texture3D; + }; +} D3D12_UNORDERED_ACCESS_VIEW_DESC; + +typedef enum D3D12_RTV_DIMENSION +{ + D3D12_RTV_DIMENSION_UNKNOWN = 0, + D3D12_RTV_DIMENSION_BUFFER = 1, + D3D12_RTV_DIMENSION_TEXTURE1D = 2, + D3D12_RTV_DIMENSION_TEXTURE1DARRAY = 3, + D3D12_RTV_DIMENSION_TEXTURE2D = 4, + D3D12_RTV_DIMENSION_TEXTURE2DARRAY = 5, + D3D12_RTV_DIMENSION_TEXTURE2DMS = 6, + D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D12_RTV_DIMENSION_TEXTURE3D = 8, +} D3D12_RTV_DIMENSION; + +typedef struct D3D12_BUFFER_RTV +{ + UINT64 FirstElement; + UINT NumElements; +} D3D12_BUFFER_RTV; + +typedef struct D3D12_TEX1D_RTV +{ + UINT MipSlice; +} D3D12_TEX1D_RTV; + +typedef struct D3D12_TEX1D_ARRAY_RTV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX1D_ARRAY_RTV; + +typedef struct D3D12_TEX2D_RTV +{ + UINT MipSlice; + UINT PlaneSlice; +} D3D12_TEX2D_RTV; + +typedef struct D3D12_TEX2D_ARRAY_RTV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; +} D3D12_TEX2D_ARRAY_RTV; + +typedef struct D3D12_TEX2DMS_RTV +{ + UINT UnusedField_NothingToDefine; +} D3D12_TEX2DMS_RTV; + +typedef struct D3D12_TEX2DMS_ARRAY_RTV +{ + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX2DMS_ARRAY_RTV; + +typedef struct D3D12_TEX3D_RTV +{ + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; +} D3D12_TEX3D_RTV; + +typedef struct D3D12_RENDER_TARGET_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D12_RTV_DIMENSION ViewDimension; + union + { + D3D12_BUFFER_RTV Buffer; + D3D12_TEX1D_RTV Texture1D; + D3D12_TEX1D_ARRAY_RTV Texture1DArray; + D3D12_TEX2D_RTV Texture2D; + D3D12_TEX2D_ARRAY_RTV Texture2DArray; + D3D12_TEX2DMS_RTV Texture2DMS; + D3D12_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D12_TEX3D_RTV Texture3D; + }; +} D3D12_RENDER_TARGET_VIEW_DESC; + +typedef enum D3D12_DSV_DIMENSION +{ + D3D12_DSV_DIMENSION_UNKNOWN = 0, + D3D12_DSV_DIMENSION_TEXTURE1D = 1, + D3D12_DSV_DIMENSION_TEXTURE1DARRAY = 2, + D3D12_DSV_DIMENSION_TEXTURE2D = 3, + D3D12_DSV_DIMENSION_TEXTURE2DARRAY = 4, + D3D12_DSV_DIMENSION_TEXTURE2DMS = 5, + D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY = 6, +} D3D12_DSV_DIMENSION; + +typedef enum D3D12_DSV_FLAGS +{ + D3D12_DSV_FLAG_NONE = 0x0, + D3D12_DSV_FLAG_READ_ONLY_DEPTH = 0x1, + D3D12_DSV_FLAG_READ_ONLY_STENCIL = 0x2, +} D3D12_DSV_FLAGS; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DSV_FLAGS);") + +typedef struct D3D12_TEX1D_DSV +{ + UINT MipSlice; +} D3D12_TEX1D_DSV; + +typedef struct D3D12_TEX1D_ARRAY_DSV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX1D_ARRAY_DSV; + +typedef struct D3D12_TEX2D_DSV +{ + UINT MipSlice; +} D3D12_TEX2D_DSV; + +typedef struct D3D12_TEX2D_ARRAY_DSV +{ + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX2D_ARRAY_DSV; + +typedef struct D3D12_TEX2DMS_DSV +{ + UINT UnusedField_NothingToDefine; +} D3D12_TEX2DMS_DSV; + +typedef struct D3D12_TEX2DMS_ARRAY_DSV +{ + UINT FirstArraySlice; + UINT ArraySize; +} D3D12_TEX2DMS_ARRAY_DSV; + +typedef struct D3D12_DEPTH_STENCIL_VIEW_DESC +{ + DXGI_FORMAT Format; + D3D12_DSV_DIMENSION ViewDimension; + D3D12_DSV_FLAGS Flags; + union + { + D3D12_TEX1D_DSV Texture1D; + D3D12_TEX1D_ARRAY_DSV Texture1DArray; + D3D12_TEX2D_DSV Texture2D; + D3D12_TEX2D_ARRAY_DSV Texture2DArray; + D3D12_TEX2DMS_DSV Texture2DMS; + D3D12_TEX2DMS_ARRAY_DSV Texture2DMSArray; + }; +} D3D12_DEPTH_STENCIL_VIEW_DESC; + +typedef struct D3D12_SAMPLER_DESC +{ + D3D12_FILTER Filter; + D3D12_TEXTURE_ADDRESS_MODE AddressU; + D3D12_TEXTURE_ADDRESS_MODE AddressV; + D3D12_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D12_COMPARISON_FUNC ComparisonFunc; + FLOAT BorderColor[4]; + FLOAT MinLOD; + FLOAT MaxLOD; +} D3D12_SAMPLER_DESC; + +typedef struct D3D12_CPU_DESCRIPTOR_HANDLE +{ + SIZE_T ptr; +} D3D12_CPU_DESCRIPTOR_HANDLE; + +typedef struct D3D12_GPU_DESCRIPTOR_HANDLE +{ + UINT64 ptr; +} D3D12_GPU_DESCRIPTOR_HANDLE; + +typedef enum D3D12_STENCIL_OP +{ + D3D12_STENCIL_OP_KEEP = 1, + D3D12_STENCIL_OP_ZERO = 2, + D3D12_STENCIL_OP_REPLACE = 3, + D3D12_STENCIL_OP_INCR_SAT = 4, + D3D12_STENCIL_OP_DECR_SAT = 5, + D3D12_STENCIL_OP_INVERT = 6, + D3D12_STENCIL_OP_INCR = 7, + D3D12_STENCIL_OP_DECR = 8, +} D3D12_STENCIL_OP; + +typedef struct D3D12_DEPTH_STENCILOP_DESC +{ + D3D12_STENCIL_OP StencilFailOp; + D3D12_STENCIL_OP StencilDepthFailOp; + D3D12_STENCIL_OP StencilPassOp; + D3D12_COMPARISON_FUNC StencilFunc; +} D3D12_DEPTH_STENCILOP_DESC; + +typedef enum D3D12_DEPTH_WRITE_MASK +{ + D3D12_DEPTH_WRITE_MASK_ZERO = 0, + D3D12_DEPTH_WRITE_MASK_ALL = 1, +} D3D12_DEPTH_WRITE_MASK; + +typedef struct D3D12_DEPTH_STENCIL_DESC +{ + BOOL DepthEnable; + D3D12_DEPTH_WRITE_MASK DepthWriteMask; + D3D12_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D12_DEPTH_STENCILOP_DESC FrontFace; + D3D12_DEPTH_STENCILOP_DESC BackFace; +} D3D12_DEPTH_STENCIL_DESC; + +typedef enum D3D12_BLEND +{ + D3D12_BLEND_ZERO = 1, + D3D12_BLEND_ONE = 2, + D3D12_BLEND_SRC_COLOR = 3, + D3D12_BLEND_INV_SRC_COLOR = 4, + D3D12_BLEND_SRC_ALPHA = 5, + D3D12_BLEND_INV_SRC_ALPHA = 6, + D3D12_BLEND_DEST_ALPHA = 7, + D3D12_BLEND_INV_DEST_ALPHA = 8, + D3D12_BLEND_DEST_COLOR = 9, + D3D12_BLEND_INV_DEST_COLOR = 10, + D3D12_BLEND_SRC_ALPHA_SAT = 11, + D3D12_BLEND_BLEND_FACTOR = 14, + D3D12_BLEND_INV_BLEND_FACTOR = 15, + D3D12_BLEND_SRC1_COLOR = 16, + D3D12_BLEND_INV_SRC1_COLOR = 17, + D3D12_BLEND_SRC1_ALPHA = 18, + D3D12_BLEND_INV_SRC1_ALPHA = 19, +} D3D12_BLEND; + +typedef enum D3D12_BLEND_OP +{ + D3D12_BLEND_OP_ADD = 1, + D3D12_BLEND_OP_SUBTRACT = 2, + D3D12_BLEND_OP_REV_SUBTRACT = 3, + D3D12_BLEND_OP_MIN = 4, + D3D12_BLEND_OP_MAX = 5, +} D3D12_BLEND_OP; + +typedef enum D3D12_LOGIC_OP +{ + D3D12_LOGIC_OP_CLEAR = 0, + D3D12_LOGIC_OP_SET = 1, + D3D12_LOGIC_OP_COPY = 2, + D3D12_LOGIC_OP_COPY_INVERTED = 3, + D3D12_LOGIC_OP_NOOP = 4, +} D3D12_LOGIC_OP; + +typedef enum D3D12_COLOR_WRITE_ENABLE +{ + D3D12_COLOR_WRITE_ENABLE_RED = 0x1, + D3D12_COLOR_WRITE_ENABLE_GREEN = 0x2, + D3D12_COLOR_WRITE_ENABLE_BLUE = 0x4, + D3D12_COLOR_WRITE_ENABLE_ALPHA = 0x8, + D3D12_COLOR_WRITE_ENABLE_ALL = (D3D12_COLOR_WRITE_ENABLE_RED + | D3D12_COLOR_WRITE_ENABLE_GREEN | D3D12_COLOR_WRITE_ENABLE_BLUE + | D3D12_COLOR_WRITE_ENABLE_ALPHA), +} D3D12_COLOR_WRITE_ENABLE; + +typedef struct D3D12_RENDER_TARGET_BLEND_DESC +{ + BOOL BlendEnable; + BOOL LogicOpEnable; + D3D12_BLEND SrcBlend; + D3D12_BLEND DestBlend; + D3D12_BLEND_OP BlendOp; + D3D12_BLEND SrcBlendAlpha; + D3D12_BLEND DestBlendAlpha; + D3D12_BLEND_OP BlendOpAlpha; + D3D12_LOGIC_OP LogicOp; + UINT8 RenderTargetWriteMask; +} D3D12_RENDER_TARGET_BLEND_DESC; + +typedef struct D3D12_BLEND_DESC +{ + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D12_RENDER_TARGET_BLEND_DESC RenderTarget[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; +} D3D12_BLEND_DESC; + +typedef enum D3D12_FILL_MODE +{ + D3D12_FILL_MODE_WIREFRAME = 2, + D3D12_FILL_MODE_SOLID = 3, +} D3D12_FILL_MODE; + +typedef enum D3D12_CULL_MODE +{ + D3D12_CULL_MODE_NONE = 1, + D3D12_CULL_MODE_FRONT = 2, + D3D12_CULL_MODE_BACK = 3, +} D3D12_CULL_MODE; + +typedef enum D3D12_CONSERVATIVE_RASTERIZATION_MODE +{ + D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF = 0, + D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON = 1, +} D3D12_CONSERVATIVE_RASTERIZATION_MODE; + +typedef struct D3D12_RASTERIZER_DESC +{ + D3D12_FILL_MODE FillMode; + D3D12_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; + UINT ForcedSampleCount; + D3D12_CONSERVATIVE_RASTERIZATION_MODE ConservativeRaster; +} D3D12_RASTERIZER_DESC; + +typedef struct D3D12_SO_DECLARATION_ENTRY +{ + UINT Stream; + const char *SemanticName; + UINT SemanticIndex; + BYTE StartComponent; + BYTE ComponentCount; + BYTE OutputSlot; +} D3D12_SO_DECLARATION_ENTRY; + +typedef struct D3D12_STREAM_OUTPUT_DESC +{ + const D3D12_SO_DECLARATION_ENTRY *pSODeclaration; + UINT NumEntries; + const UINT *pBufferStrides; + UINT NumStrides; + UINT RasterizedStream; +} D3D12_STREAM_OUTPUT_DESC; + +typedef enum D3D12_INPUT_CLASSIFICATION +{ + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA = 0, + D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA = 1, +} D3D12_INPUT_CLASSIFICATION; + +typedef struct D3D12_INPUT_ELEMENT_DESC +{ + const char *SemanticName; + UINT SemanticIndex; + DXGI_FORMAT Format; + UINT InputSlot; + UINT AlignedByteOffset; + D3D12_INPUT_CLASSIFICATION InputSlotClass; + UINT InstanceDataStepRate; +} D3D12_INPUT_ELEMENT_DESC; + +typedef struct D3D12_INPUT_LAYOUT_DESC +{ + const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs; + UINT NumElements; +} D3D12_INPUT_LAYOUT_DESC; + +typedef enum D3D12_INDEX_BUFFER_STRIP_CUT_VALUE +{ + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED = 0, + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF = 1, + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF = 2, +} D3D12_INDEX_BUFFER_STRIP_CUT_VALUE; + +typedef D3D_PRIMITIVE_TOPOLOGY D3D12_PRIMITIVE_TOPOLOGY; + +typedef enum D3D12_PRIMITIVE_TOPOLOGY_TYPE +{ + D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED = 0, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT = 1, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE = 2, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE = 3, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH = 4, +} D3D12_PRIMITIVE_TOPOLOGY_TYPE; + +typedef struct D3D12_CACHED_PIPELINE_STATE +{ + const void *pCachedBlob; + SIZE_T CachedBlobSizeInBytes; +} D3D12_CACHED_PIPELINE_STATE; + +typedef enum D3D12_PIPELINE_STATE_FLAGS +{ + D3D12_PIPELINE_STATE_FLAG_NONE = 0x0, + D3D12_PIPELINE_STATE_FLAG_DEBUG = 0x1, +} D3D12_PIPELINE_STATE_FLAGS; + +typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC +{ + ID3D12RootSignature *pRootSignature; + D3D12_SHADER_BYTECODE VS; + D3D12_SHADER_BYTECODE PS; + D3D12_SHADER_BYTECODE DS; + D3D12_SHADER_BYTECODE HS; + D3D12_SHADER_BYTECODE GS; + D3D12_STREAM_OUTPUT_DESC StreamOutput; + D3D12_BLEND_DESC BlendState; + UINT SampleMask; + D3D12_RASTERIZER_DESC RasterizerState; + D3D12_DEPTH_STENCIL_DESC DepthStencilState; + D3D12_INPUT_LAYOUT_DESC InputLayout; + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; + D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; + UINT NumRenderTargets; + DXGI_FORMAT RTVFormats[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; + DXGI_FORMAT DSVFormat; + DXGI_SAMPLE_DESC SampleDesc; + UINT NodeMask; + D3D12_CACHED_PIPELINE_STATE CachedPSO; + D3D12_PIPELINE_STATE_FLAGS Flags; +} D3D12_GRAPHICS_PIPELINE_STATE_DESC; + +typedef struct D3D12_COMPUTE_PIPELINE_STATE_DESC +{ + ID3D12RootSignature *pRootSignature; + D3D12_SHADER_BYTECODE CS; + UINT NodeMask; + D3D12_CACHED_PIPELINE_STATE CachedPSO; + D3D12_PIPELINE_STATE_FLAGS Flags; +} D3D12_COMPUTE_PIPELINE_STATE_DESC; + +typedef enum D3D12_COMMAND_LIST_TYPE +{ + D3D12_COMMAND_LIST_TYPE_DIRECT = 0, + D3D12_COMMAND_LIST_TYPE_BUNDLE = 1, + D3D12_COMMAND_LIST_TYPE_COMPUTE = 2, + D3D12_COMMAND_LIST_TYPE_COPY = 3, +} D3D12_COMMAND_LIST_TYPE; + +typedef enum D3D12_COMMAND_QUEUE_PRIORITY +{ + D3D12_COMMAND_QUEUE_PRIORITY_NORMAL = 0, + D3D12_COMMAND_QUEUE_PRIORITY_HIGH = 100, +} D3D12_COMMAND_QUEUE_PRIORITY; + +typedef enum D3D12_COMMAND_QUEUE_FLAGS +{ + D3D12_COMMAND_QUEUE_FLAG_NONE = 0x0, + D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT = 0x1, +} D3D12_COMMAND_QUEUE_FLAGS; + +typedef struct D3D12_COMMAND_QUEUE_DESC +{ + D3D12_COMMAND_LIST_TYPE Type; + INT Priority; + D3D12_COMMAND_QUEUE_FLAGS Flags; + UINT NodeMask; +} D3D12_COMMAND_QUEUE_DESC; + +typedef struct D3D12_FEATURE_DATA_ARCHITECTURE +{ + UINT NodeIndex; + BOOL TileBasedRenderer; + BOOL UMA; + BOOL CacheCoherentUMA; +} D3D12_FEATURE_DATA_ARCHITECTURE; + +typedef struct D3D12_FEATURE_DATA_FORMAT_INFO +{ + DXGI_FORMAT Format; + UINT8 PlaneCount; +} D3D12_FEATURE_DATA_FORMAT_INFO; + +typedef struct D3D12_FEATURE_DATA_FEATURE_LEVELS +{ + UINT NumFeatureLevels; + const D3D_FEATURE_LEVEL *pFeatureLevelsRequested; + D3D_FEATURE_LEVEL MaxSupportedFeatureLevel; +} D3D12_FEATURE_DATA_FEATURE_LEVELS; + +typedef enum D3D12_FEATURE +{ + D3D12_FEATURE_D3D12_OPTIONS = 0, + D3D12_FEATURE_ARCHITECTURE = 1, + D3D12_FEATURE_FEATURE_LEVELS = 2, + D3D12_FEATURE_FORMAT_SUPPORT = 3, + D3D12_FEATURE_FORMAT_INFO = 4, + D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT = 5, +} D3D12_FEATURE; + +typedef struct D3D12_MEMCPY_DEST +{ + void *pData; + SIZE_T RowPitch; + SIZE_T SlicePitch; +} D3D12_MEMCPY_DEST; + +typedef struct D3D12_SUBRESOURCE_DATA +{ + const void *pData; + LONG_PTR RowPitch; + LONG_PTR SlicePitch; +} D3D12_SUBRESOURCE_DATA; + +[ + uuid(c4fec28f-7966-4e95-9f94-f431cb56c3b8), + object, + local, + pointer_default(unique) +] +interface ID3D12Object : IUnknown +{ + HRESULT GetPrivateData(REFGUID guid, UINT *data_size, void *data); + HRESULT SetPrivateData(REFGUID guid, UINT data_size, const void *data); + HRESULT SetPrivateDataInterface(REFGUID guid, const IUnknown *data); + HRESULT SetName(const WCHAR *name); +} + +[ + uuid(905db94b-a00c-4140-9df5-2b64ca9ea357), + object, + local, + pointer_default(unique) +] +interface ID3D12DeviceChild : ID3D12Object +{ + HRESULT GetDevice(REFIID riid, void **device); +} + +[ + uuid(63ee58fb-1268-4835-86da-f008ce62f0d6), + object, + local, + pointer_default(unique) +] +interface ID3D12Pageable : ID3D12DeviceChild +{ +} + +[ + uuid(696442be-a72e-4059-bc79-5b5c98040fad), + object, + local, + pointer_default(unique) +] +interface ID3D12Resource : ID3D12Pageable +{ + HRESULT Map(UINT sub_resource, const D3D12_RANGE *read_range, void **data); + void Unmap(UINT sub_resource, const D3D12_RANGE *written_range); + + D3D12_RESOURCE_DESC GetDesc(); + + D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress(); + + HRESULT WriteToSubresource(UINT dst_sub_resource, const D3D12_BOX *dst_box, + const void *src_data, UINT src_row_pitch, UINT src_slice_pitch); + HRESULT ReadFromSubresource(void *dst_data, UINT dst_row_pitch, UINT dst_slice_pitch, + UINT src_sub_resource, const D3D12_BOX *src_box); + + HRESULT GetHeapProperties(D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS *flags); +} + +[ + uuid(7116d91c-e7e4-47ce-b8c6-ec8168f437e5), + object, + local, + pointer_default(unique) +] +interface ID3D12CommandList : ID3D12DeviceChild +{ + D3D12_COMMAND_LIST_TYPE GetType(); +} + +typedef enum D3D12_TILE_COPY_FLAGS +{ + D3D12_TILE_COPY_FLAG_NONE = 0x0, + D3D12_TILE_COPY_FLAG_NO_HAZARD = 0x1, + D3D12_TILE_COPY_FLAG_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2, + D3D12_TILE_COPY_FLAG_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4, +} D3D12_TILE_COPY_FLAGS; + +typedef struct D3D12_INDEX_BUFFER_VIEW +{ + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT SizeInBytes; + DXGI_FORMAT Format; +} D3D12_INDEX_BUFFER_VIEW; + +typedef struct D3D12_VERTEX_BUFFER_VIEW +{ + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT SizeInBytes; + UINT StrideInBytes; +} D3D12_VERTEX_BUFFER_VIEW; + +typedef struct D3D12_STREAM_OUTPUT_BUFFER_VIEW +{ + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT64 SizeInBytes; + D3D12_GPU_VIRTUAL_ADDRESS BufferFilledSizeLocation; +} D3D12_STREAM_OUTPUT_BUFFER_VIEW; + +typedef enum D3D12_CLEAR_FLAGS +{ + D3D12_CLEAR_FLAG_DEPTH = 0x1, + D3D12_CLEAR_FLAG_STENCIL = 0x2, +} D3D12_CLEAR_FLAGS; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_CLEAR_FLAGS);") + +typedef struct D3D12_DISCARD_REGION +{ + UINT NumRects; + const D3D12_RECT *pRects; + UINT FirstSubresource; + UINT NumSubresources; +} D3D12_DISCARD_REGION; + +typedef enum D3D12_QUERY_TYPE +{ + D3D12_QUERY_TYPE_OCCLUSION = 0, + D3D12_QUERY_TYPE_BINARY_OCCLUSION = 1, + D3D12_QUERY_TYPE_TIMESTAMP = 2, + D3D12_QUERY_TYPE_PIPELINE_STATISTICS = 3, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 = 4, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 = 5, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 = 6, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 = 7, +} D3D12_QUERY_TYPE; + +typedef struct D3D12_QUERY_DATA_PIPELINE_STATISTICS +{ + UINT64 IAVertices; + UINT64 IAPrimitives; + UINT64 VSInvocations; + UINT64 GSInvocations; + UINT64 GSPrimitives; + UINT64 CInvocations; + UINT64 CPrimitives; + UINT64 PSInvocations; + UINT64 HSInvocations; + UINT64 DSInvocations; + UINT64 CSInvocations; +} D3D12_QUERY_DATA_PIPELINE_STATISTICS; + +typedef enum D3D12_PREDICATION_OP +{ + D3D12_PREDICATION_OP_EQUAL_ZERO = 0, + D3D12_PREDICATION_OP_NOT_EQUAL_ZERO = 1, +} D3D12_PREDICATION_OP; + +[ + uuid(8efb471d-616c-4f49-90f7-127bb763fa51), + object, + local, + pointer_default(unique) +] +interface ID3D12DescriptorHeap : ID3D12Pageable +{ + D3D12_DESCRIPTOR_HEAP_DESC GetDesc(); + + D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandleForHeapStart(); + D3D12_GPU_DESCRIPTOR_HANDLE GetGPUDescriptorHandleForHeapStart(); +} + +[ + uuid(0d9658ae-ed45-469e-a61d-970ec583cab4), + object, + local, + pointer_default(unique) +] +interface ID3D12QueryHeap : ID3D12Pageable +{ +} + +[ + uuid(c36a797c-ec80-4f0a-8985-a7b2475082d1), + object, + local, + pointer_default(unique) +] +interface ID3D12CommandSignature : ID3D12Pageable +{ +} + +[ + uuid(5b160d0f-ac1b-4185-8ba8-b3ae42a5a455), + object, + local, + pointer_default(unique) +] +interface ID3D12GraphicsCommandList : ID3D12CommandList +{ + HRESULT Close(); + + HRESULT Reset(ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_state); + + HRESULT ClearState(ID3D12PipelineState *pipeline_state); + + void DrawInstanced(UINT vertex_count_per_instance, UINT instance_count, + UINT start_vertex_location, UINT start_instance_location); + void DrawIndexedInstanced(UINT index_count_per_instance, UINT instance_count, + UINT start_vertex_location, INT base_vertex_location, UINT start_instance_location); + + void Dispatch(UINT x, UINT u, UINT z); + + void CopyBufferRegion(ID3D12Resource *dst_buffer, UINT64 dst_offset, + ID3D12Resource *src_buffer, UINT64 src_offset, UINT64 byte_count); + void CopyTextureRegion(const D3D12_TEXTURE_COPY_LOCATION *dst, + UINT dst_x, UINT dst_y, UINT dst_z, + const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box); + void CopyResource(ID3D12Resource *dst_resource, ID3D12Resource *src_resource); + + void CopyTiles(ID3D12Resource *tiled_resource, + const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, + const D3D12_TILE_REGION_SIZE *tile_region_size, + ID3D12Resource *buffer, + UINT64 buffer_offset, + D3D12_TILE_COPY_FLAGS flags); + + void ResolveSubresource(ID3D12Resource *dst_resource, UINT dst_sub_resource, + ID3D12Resource *src_resource, UINT src_sub_resource, + DXGI_FORMAT format); + + void IASetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology); + + void RSSetViewports(UINT viewport_count, const D3D12_VIEWPORT *viewports); + void RSSetScissorRects(UINT rect_count, const D3D12_RECT *rects); + + void OMSetBlendFactor(const FLOAT blend_factor[4]); + void OMSetStencilRef(UINT stencil_ref); + + void SetPipelineState(ID3D12PipelineState *pipeline_state); + + void ResourceBarrier(UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers); + + void ExecuteBundle(ID3D12GraphicsCommandList *command_list); + + void SetDescriptorHeaps(UINT heap_count, ID3D12DescriptorHeap * const *heaps); + + void SetComputeRootSignature(ID3D12RootSignature *root_signature); + void SetGraphicsRootSignature(ID3D12RootSignature *root_signature); + + void SetComputeRootDescriptorTable(UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor); + void SetGraphicsRootDescriptorTable(UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor); + + void SetComputeRoot32BitConstant(UINT root_parameter_index, UINT data, UINT dst_offset); + void SetGraphicsRoot32BitConstant(UINT root_parameter_index, UINT data, UINT dst_offset); + + void SetComputeRoot32BitConstants(UINT root_parameter_index, UINT constant_count, const void *data, + UINT dst_offset); + void SetGraphicsRoot32BitConstants(UINT root_parameter_index, UINT constant_count, const void *data, + UINT dst_offset); + + void SetComputeRootConstantBufferView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); + void SetGraphicsRootConstantBufferView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); + + void SetComputeRootShaderResourceView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); + void SetGraphicsRootShaderResourceView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); + + void SetComputeRootUnorderedAccessView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); + void SetGraphicsRootUnorderedAccessView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); + + void IASetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW *view); + void IASetVertexBuffers(UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views); + + void SOSetTargets(UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views); + + void OMSetRenderTargets(UINT render_target_descriptor_count, + const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors, + BOOL single_descriptor_handle, + const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor); + + void ClearDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, + FLOAT depth, UINT8 stencil, UINT rect_count, const D3D12_RECT *rects); + void ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], + UINT rect_count, const D3D12_RECT *rects); + void ClearUnorderedAccessViewUint(D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const UINT values[4], + UINT rect_count, const D3D12_RECT *rects); + void ClearUnorderedAccessViewFloat(D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const float values[4], + UINT rect_count, const D3D12_RECT *rects); + + void DiscardResource(ID3D12Resource *resource, const D3D12_DISCARD_REGION *region); + + void BeginQuery(ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index); + void EndQuery(ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index); + void ResolveQueryData(ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, + UINT start_index, UINT query_count, + ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset); + + void SetPredication(ID3D12Resource *buffer, UINT64 aligned_buffer_offset, + D3D12_PREDICATION_OP operation); + + void SetMarker(UINT metadata, const void *data, UINT size); + void BeginEvent(UINT metadata, const void *data, UINT size); + void EndEvent(); + + void ExecuteIndirect(ID3D12CommandSignature *command_signature, + UINT max_command_count, ID3D12Resource *arg_buffer, UINT64 arg_buffer_offset, + ID3D12Resource *count_buffer, UINT64 count_buffer_offset); +} + +typedef enum D3D12_TILE_RANGE_FLAGS +{ + D3D12_TILE_RANGE_FLAG_NONE = 0x0, + D3D12_TILE_RANGE_FLAG_NULL = 0x1, + D3D12_TILE_RANGE_FLAG_SKIP = 0x2, + D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE = 0x4 +} D3D12_TILE_RANGE_FLAGS; + +typedef enum D3D12_TILE_MAPPING_FLAGS +{ + D3D12_TILE_MAPPING_FLAG_NONE = 0x0, + D3D12_TILE_MAPPING_FLAG_NO_HAZARD = 0x1, +} D3D12_TILE_MAPPING_FLAGS; + +[ + uuid(0ec870a6-5d7e-4c22-8cfc-5baae07616ed), + object, + local, + pointer_default(unique) +] +interface ID3D12CommandQueue : ID3D12Pageable +{ + void UpdateTileMappings(ID3D12Resource *resource, UINT region_count, + const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates, + const D3D12_TILE_REGION_SIZE *region_sizes, + UINT range_count, + const D3D12_TILE_RANGE_FLAGS *range_flags, + UINT *heap_range_offsets, + UINT *range_tile_counts, + D3D12_TILE_MAPPING_FLAGS flags); + + void CopyTileMappings(ID3D12Resource *dst_resource, + const D3D12_TILED_RESOURCE_COORDINATE *dst_region_start_coordinate, + ID3D12Resource *src_resource, + const D3D12_TILED_RESOURCE_COORDINATE *src_region_start_coordinate, + const D3D12_TILE_REGION_SIZE *region_size, + D3D12_TILE_MAPPING_FLAGS flags); + + void ExecuteCommandLists(UINT command_list_count, + ID3D12CommandList * const * command_lists); + + void SetMarker(UINT metadata, const void *data, UINT size); + void BeginEvent(UINT metadata, const void *data, UINT size); + void EndEvent(); + + HRESULT Signal(ID3D12Fence *fence, UINT64 value); + HRESULT Wait(ID3D12Fence *fence, UINT64 value); + + HRESULT GetTimestampFrequency(UINT64 *frequency); + HRESULT GetClockCalibration(UINT64 *gpu_timestamp, UINT64 *cpu_timestamp); + + D3D12_COMMAND_QUEUE_DESC GetDesc(); +} + +typedef enum D3D12_FENCE_FLAGS +{ + D3D12_FENCE_FLAG_NONE = 0x0, + D3D12_FENCE_FLAG_SHARED = 0x1, + D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x2, +} D3D12_FENCE_FLAGS; + +typedef enum D3D12_QUERY_HEAP_TYPE +{ + D3D12_QUERY_HEAP_TYPE_OCCLUSION = 0, + D3D12_QUERY_HEAP_TYPE_TIMESTAMP = 1, + D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS = 2, + D3D12_QUERY_HEAP_TYPE_SO_STATISTICS = 3, +} D3D12_QUERY_HEAP_TYPE; + +typedef struct D3D12_QUERY_HEAP_DESC +{ + D3D12_QUERY_HEAP_TYPE Type; + UINT Count; + UINT NodeMask; +} D3D12_QUERY_HEAP_DESC; + +typedef enum D3D12_INDIRECT_ARGUMENT_TYPE +{ + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW, + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED, + D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH, + D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW, + D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW, + D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT, + D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW, + D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW, + D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW, +} D3D12_INDIRECT_ARGUMENT_TYPE; + +typedef struct D3D12_INDIRECT_ARGUMENT_DESC +{ + D3D12_INDIRECT_ARGUMENT_TYPE Type; + union + { + struct + { + UINT Slot; + } VertexBuffer; + struct + { + UINT RootParameterIndex; + UINT DestOffsetIn32BitValues; + UINT Num32BitValuesToSet; + } Constant; + struct + { + UINT RootParameterIndex; + } ConstantBufferView; + struct + { + UINT RootParameterIndex; + } ShaderResourceView; + struct + { + UINT RootParameterIndex; + } UnorderedAccessView; + }; +} D3D12_INDIRECT_ARGUMENT_DESC; + +typedef struct D3D12_COMMAND_SIGNATURE_DESC +{ + UINT ByteStride; + UINT NumArgumentDescs; + const D3D12_INDIRECT_ARGUMENT_DESC *pArgumentDescs; + UINT NodeMask; +} D3D12_COMMAND_SIGNATURE_DESC; + +[ + uuid(c54a6b66-72df-4ee8-8be5-a946a1429214), + object, + local, + pointer_default(unique) +] +interface ID3D12RootSignature : ID3D12DeviceChild +{ +} + +[ + uuid(765a30f3-f624-4c6f-a828-ace948622445), + object, + local, + pointer_default(unique) +] +interface ID3D12PipelineState : ID3D12Pageable +{ + HRESULT GetCachedBlob(ID3DBlob **blob); +} + +[ + uuid(0a753dcf-c4d8-4b91-adf6-be5a60d95a76), + object, + local, + pointer_default(unique) +] +interface ID3D12Fence : ID3D12Pageable +{ + UINT64 GetCompletedValue(); + HRESULT SetEventOnCompletion(UINT64 value, HANDLE event); + HRESULT Signal(UINT64 value); +} + +[ + uuid(6102dee4-af59-4b09-b999-b44d73f09b24), + object, + local, + pointer_default(unique) +] +interface ID3D12CommandAllocator : ID3D12Pageable +{ + HRESULT Reset(); +} + +[ + uuid(189819f1-1db6-4b57-be54-1821339b85f7), + object, + local, + pointer_default(unique) +] +interface ID3D12Device : ID3D12Object +{ + UINT GetNodeCount(); + + HRESULT CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC *desc, + REFIID riid, void **command_queue); + HRESULT CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, + REFIID riid, void **command_allocator); + HRESULT CreateGraphicsPipelineState(const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, + REFIID riid, void **pipeline_state); + HRESULT CreateComputePipelineState(const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, + REFIID riid, void **pipeline_state); + HRESULT CreateCommandList(UINT node_mask, + D3D12_COMMAND_LIST_TYPE type, + ID3D12CommandAllocator *command_allocator, + ID3D12PipelineState *initial_pipeline_state, + REFIID riid, void **command_list); + + HRESULT CheckFeatureSupport(D3D12_FEATURE feature, + void *feature_data, UINT feature_data_size); + + HRESULT CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DESC *desc, + REFIID riid, void **descriptor_heap); + UINT GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type); + + HRESULT CreateRootSignature(UINT node_mask, + const void *bytecode, SIZE_T bytecode_length, + REFIID riid, void **root_signature); + + void CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor); + void CreateShaderResourceView(ID3D12Resource *resource, + const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor); + void CreateUnorderedAccessView(ID3D12Resource *resource, ID3D12Resource *counter_resource, + const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor); + void CreateRenderTargetView(ID3D12Resource *resource, + const D3D12_RENDER_TARGET_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor); + void CreateDepthStencilView(ID3D12Resource *resource, + const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor); + void CreateSampler(const D3D12_SAMPLER_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor); + + void CopyDescriptors(UINT dst_descriptor_range_count, + const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, + const UINT *dst_descriptor_range_sizes, + UINT src_descriptor_range_count, + const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets, + const UINT *src_descriptor_range_sizes, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type); + void CopyDescriptorsSimple(UINT descriptor_count, + const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset, + const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type); + + D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo(UINT visible_mask, + UINT reource_desc_count, const D3D12_RESOURCE_DESC *resource_descs); + + D3D12_HEAP_PROPERTIES GetCustomHeapProperties(UINT node_mask, + D3D12_HEAP_TYPE heap_type); + + HRESULT CreateCommittedResource(const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, + REFIID riid, void **resource); + + HRESULT CreateHeap(const D3D12_HEAP_DESC *desc, REFIID riid, void **heap); + + HRESULT CreatePlacedResource(ID3D12Heap *heap, UINT64 heap_offset, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, + REFIID riid, void **resource); + HRESULT CreateReservedResource(const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, + REFIID riid, void **resource); + + HRESULT CreateSharedHandle(ID3D12DeviceChild *object, + const SECURITY_ATTRIBUTES *attributes, DWORD access, + const WCHAR *name, HANDLE *handle); + HRESULT OpenSharedHandle(HANDLE handle, + REFIID riid, void **object); + HRESULT OpenSharedHandleByName(const WCHAR *name, DWORD access, HANDLE *handle); + + HRESULT MakeResident(UINT object_count, ID3D12Pageable * const *objects); + HRESULT Evict(UINT object_count, ID3D12Pageable * const *objects); + + HRESULT CreateFence(UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence); + + HRESULT GetDeviceRemovedReason(); + + void GetCopyableFootprints(const D3D12_RESOURCE_DESC *desc, + UINT first_sub_resource, + UINT sub_resource_count, + UINT64 base_offset, + D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, + UINT *row_count, + UINT64 *row_size, + UINT64 *total_bytes); + + HRESULT CreateQueryHeap(const D3D12_QUERY_HEAP_DESC *desc, + REFIID riid, void **heap); + + HRESULT SetStablePowerState(BOOL enable); + + HRESULT CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC *desc, + ID3D12RootSignature *root_signature, + REFIID riid, void **command_signature); + + void GetResourceTiling(ID3D12Resource *resource, + UINT *total_tile_count, + D3D12_PACKED_MIP_INFO *packed_mip_info, + D3D12_TILE_SHAPE *standard_tile_shape, + UINT *sub_resource_tiling_count, + UINT first_sub_resource_tiling, + D3D12_SUBRESOURCE_TILING *sub_resource_tilings); + + LUID GetAdapterLuid(); +} + +[ + uuid(344488b7-6846-474b-b989-f027448245e0), + object, + local, + pointer_default(unique) +] +interface ID3D12Debug : IUnknown +{ + void EnableDebugLayer(); +} + +[ + uuid(34ab647b-3cc8-46ac-841b-c0965645c046), + object, + local, + pointer_default(unique) +] +interface ID3D12RootSignatureDeserializer : IUnknown +{ + const D3D12_ROOT_SIGNATURE_DESC *GetRootSignatureDesc(); +} + +[local] HRESULT __stdcall D3D12CreateRootSignatureDeserializer( + const void *data, SIZE_T data_size, REFIID iid, void **deserializer); + +[local] HRESULT __stdcall D3D12SerializeRootSignature( + const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc, + D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); + +[local] HRESULT __stdcall D3D12SerializeVersionedRootSignature( + const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *root_signature_desc, + ID3DBlob **blob, ID3DBlob **error_blob); + +typedef HRESULT (__stdcall *PFN_D3D12_CREATE_DEVICE)(IUnknown *adapter, + D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device); + +[local] HRESULT __stdcall D3D12CreateDevice(IUnknown *adapter, + D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device); + +typedef HRESULT (__stdcall *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID iid, void **debug); + +[local] HRESULT __stdcall D3D12GetDebugInterface(REFIID iid, void **debug); + +[local] HRESULT __stdcall D3D12EnableExperimentalFeatures(UINT feature_count, + const IID *iids, void *configurations, UINT *configurations_sizes); diff --git a/sdk/include/psdk/d3d8.h b/sdk/include/psdk/d3d8.h index 8e709753879..69424dd6d6c 100644 --- a/sdk/include/psdk/d3d8.h +++ b/sdk/include/psdk/d3d8.h @@ -1018,7 +1018,7 @@ DECLARE_INTERFACE_(IDirect3DDevice8,IUnknown) #define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e) #define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) #define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) -#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->processVertices(p,a,b,c,d,e) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e) #define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) #define IDirect3DDevice8_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) #define IDirect3DDevice8_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) diff --git a/sdk/include/psdk/d3d9.h b/sdk/include/psdk/d3d9.h index 1bc5887fe08..a99adf8bdff 100644 --- a/sdk/include/psdk/d3d9.h +++ b/sdk/include/psdk/d3d9.h @@ -69,8 +69,10 @@ #define D3DPRESENT_DONOTWAIT 1L #define D3DPRESENT_LINEAR_CONTENT 2L #define D3DPRESENT_BACK_BUFFERS_MAX 3L +#define D3DPRESENT_BACK_BUFFERS_MAX_EX 30L #define D3DSGR_NO_CALIBRATION 0x00000000L #define D3DSGR_CALIBRATE 0x00000001L +#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L #define _FACD3D 0x876 #define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) @@ -292,7 +294,8 @@ DECLARE_INTERFACE_(IDirect3D9Ex,IDirect3D9) STDMETHOD_(UINT, GetAdapterModeCountEx)(THIS_ UINT adapter_idx, const D3DDISPLAYMODEFILTER *filter) PURE; STDMETHOD(EnumAdapterModesEx)(THIS_ UINT adapter_idx, const D3DDISPLAYMODEFILTER *filter, UINT mode_idx, D3DDISPLAYMODEEX *mode) PURE; - STDMETHOD(GetAdapterDisplayModeEx)(THIS_ UINT Adapter, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation); + STDMETHOD(GetAdapterDisplayModeEx)(THIS_ UINT adapter_idx, + D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation) PURE; STDMETHOD(CreateDeviceEx)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, struct IDirect3DDevice9Ex **ppReturnedDeviceInterface) PURE; STDMETHOD(GetAdapterLUID)(THIS_ UINT Adatper, LUID *pLUID) PURE; }; diff --git a/sdk/include/psdk/d3dcommon.idl b/sdk/include/psdk/d3dcommon.idl index c7e3b4d236c..5e38658f89b 100644 --- a/sdk/include/psdk/d3dcommon.idl +++ b/sdk/include/psdk/d3dcommon.idl @@ -86,7 +86,9 @@ typedef enum D3D_FEATURE_LEVEL D3D_FEATURE_LEVEL_10_0 = 0xa000, D3D_FEATURE_LEVEL_10_1 = 0xa100, D3D_FEATURE_LEVEL_11_0 = 0xb000, - D3D_FEATURE_LEVEL_11_1 = 0xb100 + D3D_FEATURE_LEVEL_11_1 = 0xb100, + D3D_FEATURE_LEVEL_12_0 = 0xc000, + D3D_FEATURE_LEVEL_12_1 = 0xc100, } D3D_FEATURE_LEVEL; cpp_quote("#define D3D_FL9_1_REQ_TEXTURE1D_U_DIMENSION 2048") diff --git a/sdk/include/psdk/d3dx10.h b/sdk/include/psdk/d3dx10.h new file mode 100644 index 00000000000..7062d24ea09 --- /dev/null +++ b/sdk/include/psdk/d3dx10.h @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Andrey Gusev + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __D3DX10_H__ +#define __D3DX10_H__ + +#include +#include + +#define D3DX10_DEFAULT (0xffffffffu) +#define D3DX10_FROM_FILE (0xfffffffdu) +#define DXGI_FORMAT_FROM_FILE ((DXGI_FORMAT)0xfffffffdu) + +#include "d3d10.h" +#include "d3dx10math.h" +#include "d3dx10core.h" +#include "d3dx10async.h" +#include "d3dx10tex.h" + +#define _FACDD 0x876 +#define MAKE_DDHRESULT(code) MAKE_HRESULT(1, _FACDD, code) + +enum _D3DX10_ERR +{ + D3DX10_ERR_CANNOT_MODIFY_INDEX_BUFFER = MAKE_DDHRESULT(2900), + D3DX10_ERR_INVALID_MESH = MAKE_DDHRESULT(2901), + D3DX10_ERR_CANNOT_ATTR_SORT = MAKE_DDHRESULT(2902), + D3DX10_ERR_SKINNING_NOT_SUPPORTED = MAKE_DDHRESULT(2903), + D3DX10_ERR_TOO_MANY_INFLUENCES = MAKE_DDHRESULT(2904), + D3DX10_ERR_INVALID_DATA = MAKE_DDHRESULT(2905), + D3DX10_ERR_LOADED_MESH_HAS_NO_DATA = MAKE_DDHRESULT(2906), + D3DX10_ERR_DUPLICATE_NAMED_FRAGMENT = MAKE_DDHRESULT(2907), + D3DX10_ERR_CANNOT_REMOVE_LAST_ITEM = MAKE_DDHRESULT(2908) +}; + +#endif diff --git a/sdk/include/psdk/d3dx10async.h b/sdk/include/psdk/d3dx10async.h new file mode 100644 index 00000000000..c8204bc7798 --- /dev/null +++ b/sdk/include/psdk/d3dx10async.h @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __D3DX10ASYNC_H__ +#define __D3DX10ASYNC_H__ + +#include "d3dx10.h" + +HRESULT WINAPI D3DX10CompileFromMemory(const char *data, SIZE_T data_size, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entry_point, + const char *target, UINT sflags, UINT eflags, ID3DX10ThreadPump *pump, ID3D10Blob **shader, + ID3D10Blob **error_messages, HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateEffectFromFileA(const char *filename, const D3D10_SHADER_MACRO *defines, + ID3D10Include *include, const char *profile, UINT hlslflags, UINT fxflags, ID3D10Device *device, + ID3D10EffectPool *effectpool, ID3DX10ThreadPump *pump, ID3D10Effect **effect, ID3D10Blob **errors, + HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateEffectFromFileW(const WCHAR *filename, const D3D10_SHADER_MACRO *defines, + ID3D10Include *include, const char *profile, UINT hlslflags, UINT fxflags, ID3D10Device *device, + ID3D10EffectPool *effectpool, ID3DX10ThreadPump *pump, ID3D10Effect **effect, ID3D10Blob **errors, + HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateEffectFromMemory(const void *data, SIZE_T datasize, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *profile, UINT hlslflags, + UINT fxflags, ID3D10Device *device, ID3D10EffectPool *effectpool, ID3DX10ThreadPump *pump, + ID3D10Effect **effect, ID3D10Blob **errors, HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromFileA(const char *filename, const D3D10_SHADER_MACRO *defines, + ID3D10Include *include, const char *profile, UINT hlslflags, UINT fxflags, ID3D10Device *device, + ID3DX10ThreadPump *pump, ID3D10EffectPool **effectpool, ID3D10Blob **errors, HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromFileW(const WCHAR *filename, const D3D10_SHADER_MACRO *defines, + ID3D10Include *include, const char *profile, UINT hlslflags, UINT fxflags, ID3D10Device *device, + ID3DX10ThreadPump *pump, ID3D10EffectPool **effectpool, ID3D10Blob **errors, HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateEffectPoolFromMemory(const void *data, SIZE_T datasize, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *profile, UINT hlslflags, + UINT fxflags, ID3D10Device *device, ID3DX10ThreadPump *pump, ID3D10EffectPool **effectpool, + ID3D10Blob **errors, HRESULT *hresult); + +HRESULT WINAPI D3DX10PreprocessShaderFromMemory(const char *data, SIZE_T data_size, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3DInclude *include, ID3DX10ThreadPump *pump, ID3D10Blob **shader_text, + ID3D10Blob **errors, HRESULT *hresult); + +HRESULT WINAPI D3DX10CreateAsyncFileLoaderW(const WCHAR *filename, ID3DX10DataLoader **loader); +HRESULT WINAPI D3DX10CreateAsyncFileLoaderA(const char *filename, ID3DX10DataLoader **loader); +HRESULT WINAPI D3DX10CreateAsyncMemoryLoader(const void *data, SIZE_T datasize, ID3DX10DataLoader **loader); +HRESULT WINAPI D3DX10CreateAsyncResourceLoaderA(HMODULE module, const char *resource, ID3DX10DataLoader **loader); +HRESULT WINAPI D3DX10CreateAsyncResourceLoaderW(HMODULE module, const WCHAR *resource, ID3DX10DataLoader **loader); + +#endif diff --git a/sdk/include/psdk/d3dx10core.idl b/sdk/include/psdk/d3dx10core.idl new file mode 100644 index 00000000000..c99ab82eb71 --- /dev/null +++ b/sdk/include/psdk/d3dx10core.idl @@ -0,0 +1,74 @@ +/* + * Copyright 2015 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi.idl"; +import "d3dcommon.idl"; + +[ + object, + local, + pointer_default(unique) +] +interface ID3DX10DataLoader +{ + HRESULT Load(); + HRESULT Decompress([out] void **data, [in] SIZE_T *bytes); + HRESULT Destroy(); +} + +[ + object, + local, + pointer_default(unique) +] +interface ID3DX10DataProcessor +{ + HRESULT Process([in] void *data, [in] SIZE_T bytes); + HRESULT CreateDeviceObject([out] void **dataobject); + HRESULT Destroy(); +} + + +[ + object, + local, + pointer_default(unique), + uuid(c93fecfa-6967-478a-abbc-402d90621fcb) +] +interface ID3DX10ThreadPump : IUnknown +{ + HRESULT AddWorkItem([in] ID3DX10DataLoader *loader, [in] ID3DX10DataProcessor *processor, + [in] HRESULT *result, [out] void **object); + UINT GetWorkItemCount(); + + HRESULT WaitForAllItems(); + HRESULT ProcessDeviceWorkItems([in] UINT count); + + HRESULT PurgeAllItems(); + HRESULT GetQueueStatus([in] UINT *queue, [in] UINT *processqueue, [in] UINT *devicequeue); +} + +cpp_quote("HRESULT WINAPI D3DX10UnsetAllDeviceObjects(ID3D10Device *device);") +cpp_quote("HRESULT WINAPI D3DX10CreateDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type,") +cpp_quote(" HMODULE swrast, unsigned int flags, ID3D10Device **device);") +cpp_quote("HRESULT WINAPI D3DX10CreateDeviceAndSwapChain(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type,") +cpp_quote(" HMODULE swrast, unsigned int flags, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain,") +cpp_quote(" ID3D10Device **device);") +cpp_quote("HRESULT WINAPI D3DX10GetFeatureLevel1(ID3D10Device *device, ID3D10Device1 **device1);") diff --git a/sdk/include/psdk/d3dx10math.h b/sdk/include/psdk/d3dx10math.h new file mode 100644 index 00000000000..a96784b1089 --- /dev/null +++ b/sdk/include/psdk/d3dx10math.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "d3dx10.h" + +/* This guard is the same as D3DX9 to prevent double-inclusion */ +#ifndef __D3DX9MATH_H__ +#define __D3DX9MATH_H__ + +#include + +typedef enum _D3DX_CPU_OPTIMIZATION +{ + D3DX_NOT_OPTIMIZED, + D3DX_3DNOW_OPTIMIZED, + D3DX_SSE2_OPTIMIZED, + D3DX_SSE_OPTIMIZED +} D3DX_CPU_OPTIMIZATION; + +#ifdef __cplusplus +extern "C" { +#endif + +D3DX_CPU_OPTIMIZATION WINAPI D3DXCpuOptimizations(BOOL enable); + +#ifdef __cplusplus +} +#endif + +#endif /* __D3DX9MATH_H__ */ diff --git a/sdk/include/psdk/d3dx10tex.h b/sdk/include/psdk/d3dx10tex.h new file mode 100644 index 00000000000..25ad490949a --- /dev/null +++ b/sdk/include/psdk/d3dx10tex.h @@ -0,0 +1,122 @@ +/* + * Copyright 2016 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "d3dx10.h" + +#ifndef __D3DX10TEX_H__ +#define __D3DX10TEX_H__ + +typedef enum D3DX10_FILTER_FLAG +{ + D3DX10_FILTER_NONE = 0x00000001, + D3DX10_FILTER_POINT = 0x00000002, + D3DX10_FILTER_LINEAR = 0x00000003, + D3DX10_FILTER_TRIANGLE = 0x00000004, + D3DX10_FILTER_BOX = 0x00000005, + + D3DX10_FILTER_MIRROR_U = 0x00010000, + D3DX10_FILTER_MIRROR_V = 0x00020000, + D3DX10_FILTER_MIRROR_W = 0x00040000, + D3DX10_FILTER_MIRROR = 0x00070000, + + D3DX10_FILTER_DITHER = 0x00080000, + D3DX10_FILTER_DITHER_DIFFUSION = 0x00100000, + + D3DX10_FILTER_SRGB_IN = 0x00200000, + D3DX10_FILTER_SRGB_OUT = 0x00400000, + D3DX10_FILTER_SRGB = 0x00600000, +} D3DX10_FILTER_FLAG; + +typedef enum D3DX10_IMAGE_FILE_FORMAT +{ + D3DX10_IFF_BMP = 0, + D3DX10_IFF_JPG = 1, + D3DX10_IFF_PNG = 3, + D3DX10_IFF_DDS = 4, + D3DX10_IFF_TIFF = 10, + D3DX10_IFF_GIF = 11, + D3DX10_IFF_WMP = 12, + D3DX10_IFF_FORCE_DWORD = 0x7fffffff +} D3DX10_IMAGE_FILE_FORMAT; + +typedef struct D3DX10_IMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT ArraySize; + UINT MipLevels; + UINT MiscFlags; + DXGI_FORMAT Format; + D3D10_RESOURCE_DIMENSION ResourceDimension; + D3DX10_IMAGE_FILE_FORMAT ImageFileFormat; +} D3DX10_IMAGE_INFO; + +typedef struct D3DX10_IMAGE_LOAD_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT FirstMipLevel; + UINT MipLevels; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CpuAccessFlags; + UINT MiscFlags; + DXGI_FORMAT Format; + UINT Filter; + UINT MipFilter; + D3DX10_IMAGE_INFO *pSrcInfo; + +#ifdef __cplusplus + D3DX10_IMAGE_LOAD_INFO() + { + Width = D3DX10_DEFAULT; + Height = D3DX10_DEFAULT; + Depth = D3DX10_DEFAULT; + FirstMipLevel = D3DX10_DEFAULT; + MipLevels = D3DX10_DEFAULT; + Usage = (D3D10_USAGE)D3DX10_DEFAULT; + BindFlags = D3DX10_DEFAULT; + CpuAccessFlags = D3DX10_DEFAULT; + MiscFlags = D3DX10_DEFAULT; + Format = DXGI_FORMAT_FROM_FILE; + Filter = D3DX10_DEFAULT; + MipFilter = D3DX10_DEFAULT; + pSrcInfo = NULL; + } +#endif +} D3DX10_IMAGE_LOAD_INFO; + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *src_data, SIZE_T src_data_size, + D3DX10_IMAGE_LOAD_INFO *loadinfo, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult); + +HRESULT WINAPI D3DX10FilterTexture(ID3D10Resource *texture, UINT src_level, UINT filter); + +HRESULT WINAPI D3DX10GetImageInfoFromMemory(const void *src_data, SIZE_T src_data_size, ID3DX10ThreadPump *pump, + D3DX10_IMAGE_INFO *img_info, HRESULT *hresult); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/include/psdk/d3dx11.h b/sdk/include/psdk/d3dx11.h new file mode 100644 index 00000000000..e1557857ffa --- /dev/null +++ b/sdk/include/psdk/d3dx11.h @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Andrey Gusev + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __D3DX11_H__ +#define __D3DX11_H__ + +#include +#include + +#define D3DX11_DEFAULT (0xffffffffu) +#define D3DX11_FROM_FILE (0xfffffffdu) +#define DXGI_FORMAT_FROM_FILE ((DXGI_FORMAT)0xfffffffdu) + +#include "d3d11.h" +#include "d3dx11core.h" +#include "d3dx11async.h" +#include "d3dx11tex.h" + +#define _FACDD 0x876 +#define MAKE_DDHRESULT(code) MAKE_HRESULT(SEVERITY_ERROR, _FACDD, code) + +enum _D3DX11_ERR +{ + D3DX11_ERR_CANNOT_MODIFY_INDEX_BUFFER = MAKE_DDHRESULT(2900), + D3DX11_ERR_INVALID_MESH = MAKE_DDHRESULT(2901), + D3DX11_ERR_CANNOT_ATTR_SORT = MAKE_DDHRESULT(2902), + D3DX11_ERR_SKINNING_NOT_SUPPORTED = MAKE_DDHRESULT(2903), + D3DX11_ERR_TOO_MANY_INFLUENCES = MAKE_DDHRESULT(2904), + D3DX11_ERR_INVALID_DATA = MAKE_DDHRESULT(2905), + D3DX11_ERR_LOADED_MESH_HAS_NO_DATA = MAKE_DDHRESULT(2906), + D3DX11_ERR_DUPLICATE_NAMED_FRAGMENT = MAKE_DDHRESULT(2907), + D3DX11_ERR_CANNOT_REMOVE_LAST_ITEM = MAKE_DDHRESULT(2908) +}; + +#endif diff --git a/sdk/include/psdk/d3dx11async.h b/sdk/include/psdk/d3dx11async.h new file mode 100644 index 00000000000..2d85e4aa46f --- /dev/null +++ b/sdk/include/psdk/d3dx11async.h @@ -0,0 +1,51 @@ +/* + * Copyright 2016 Matteo Bruni for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __D3DX11ASYNC_H__ +#define __D3DX11ASYNC_H__ + +#include "d3dx11.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI D3DX11CreateAsyncFileLoaderA(const char *file_name, ID3DX11DataLoader **loader); +HRESULT WINAPI D3DX11CreateAsyncFileLoaderW(const WCHAR *file_name, ID3DX11DataLoader **loader); +HRESULT WINAPI D3DX11CreateAsyncResourceLoaderA(HMODULE module, const char *resource, ID3DX11DataLoader **loader); +HRESULT WINAPI D3DX11CreateAsyncResourceLoaderW(HMODULE module, const WCHAR *resource, ID3DX11DataLoader **loader); +HRESULT WINAPI D3DX11CreateAsyncMemoryLoader(const void *data, SIZE_T data_size, ID3DX11DataLoader **loader); + +HRESULT WINAPI D3DX11CompileFromMemory(const char *data, SIZE_T data_size, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entry_point, + const char *target, UINT sflags, UINT eflags, ID3DX11ThreadPump *pump, ID3D10Blob **shader, + ID3D10Blob **error_messages, HRESULT *hresult); + +HRESULT WINAPI D3DX11CompileFromFileA(const char *filename, const D3D10_SHADER_MACRO *defines, + ID3D10Include *include, const char *entry_point, const char *target, UINT sflags, UINT eflags, + ID3DX11ThreadPump *pump, ID3D10Blob **shader, ID3D10Blob **error_messages, HRESULT *hresult); + +HRESULT WINAPI D3DX11CompileFromFileW(const WCHAR *filename, const D3D10_SHADER_MACRO *defines, + ID3D10Include *include, const char *entry_point, const char *target, UINT sflags, UINT eflags, + ID3DX11ThreadPump *pump, ID3D10Blob **shader, ID3D10Blob **error_messages, HRESULT *hresult); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/include/psdk/d3dx11core.idl b/sdk/include/psdk/d3dx11core.idl new file mode 100644 index 00000000000..f619e3b1b02 --- /dev/null +++ b/sdk/include/psdk/d3dx11core.idl @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Andrey Gusev + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi.idl"; +import "d3dcommon.idl"; + +[ + object, + local, + pointer_default(unique) +] +interface ID3DX11DataLoader +{ + HRESULT Load(); + HRESULT Decompress([out] void **data, [in] SIZE_T *bytes); + HRESULT Destroy(); +} + +[ + object, + local, + pointer_default(unique) +] +interface ID3DX11DataProcessor +{ + HRESULT Process([in] void *data, [in] SIZE_T bytes); + HRESULT CreateDeviceObject([out] void **data_object); + HRESULT Destroy(); +} + +[ + object, + local, + pointer_default(unique), + uuid(c93fecfa-6967-478a-abbc-402d90621fcb) +] +interface ID3DX11ThreadPump : IUnknown +{ + HRESULT AddWorkItem([in] ID3DX11DataLoader *loader, [in] ID3DX11DataProcessor *processor, + [in] HRESULT *hresult, [out] void **device_object); + UINT GetWorkItemCount(); + + HRESULT WaitForAllItems(); + HRESULT ProcessDeviceWorkItems([in] UINT count); + + HRESULT PurgeAllItems(); + HRESULT GetQueueStatus([in] UINT *io_queue, [in] UINT *process_queue, [in] UINT *device_queue); +} diff --git a/sdk/include/psdk/d3dx11tex.h b/sdk/include/psdk/d3dx11tex.h new file mode 100644 index 00000000000..4f792ec13ef --- /dev/null +++ b/sdk/include/psdk/d3dx11tex.h @@ -0,0 +1,137 @@ +/* + * Copyright 2016 Andrey Gusev + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "d3dx11.h" + +#ifndef __D3DX11TEX_H__ +#define __D3DX11TEX_H__ + +typedef enum D3DX11_FILTER_FLAG +{ + D3DX11_FILTER_NONE = 0x00000001, + D3DX11_FILTER_POINT = 0x00000002, + D3DX11_FILTER_LINEAR = 0x00000003, + D3DX11_FILTER_TRIANGLE = 0x00000004, + D3DX11_FILTER_BOX = 0x00000005, + + D3DX11_FILTER_MIRROR_U = 0x00010000, + D3DX11_FILTER_MIRROR_V = 0x00020000, + D3DX11_FILTER_MIRROR_W = 0x00040000, + D3DX11_FILTER_MIRROR = 0x00070000, + + D3DX11_FILTER_DITHER = 0x00080000, + D3DX11_FILTER_DITHER_DIFFUSION = 0x00100000, + + D3DX11_FILTER_SRGB_IN = 0x00200000, + D3DX11_FILTER_SRGB_OUT = 0x00400000, + D3DX11_FILTER_SRGB = 0x00600000, +} D3DX11_FILTER_FLAG; + +typedef enum D3DX11_IMAGE_FILE_FORMAT +{ + D3DX11_IFF_BMP = 0, + D3DX11_IFF_JPG = 1, + D3DX11_IFF_PNG = 3, + D3DX11_IFF_DDS = 4, + D3DX11_IFF_TIFF = 10, + D3DX11_IFF_GIF = 11, + D3DX11_IFF_WMP = 12, + D3DX11_IFF_FORCE_DWORD = 0x7fffffff +} D3DX11_IMAGE_FILE_FORMAT; + +typedef struct D3DX11_IMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT ArraySize; + UINT MipLevels; + UINT MiscFlags; + DXGI_FORMAT Format; + D3D11_RESOURCE_DIMENSION ResourceDimension; + D3DX11_IMAGE_FILE_FORMAT ImageFileFormat; +} D3DX11_IMAGE_INFO; + +typedef struct D3DX11_IMAGE_LOAD_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT FirstMipLevel; + UINT MipLevels; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CpuAccessFlags; + UINT MiscFlags; + DXGI_FORMAT Format; + UINT Filter; + UINT MipFilter; + D3DX11_IMAGE_INFO *pSrcInfo; + +#ifdef __cplusplus + D3DX11_IMAGE_LOAD_INFO() + { + Width = D3DX11_DEFAULT; + Height = D3DX11_DEFAULT; + Depth = D3DX11_DEFAULT; + FirstMipLevel = D3DX11_DEFAULT; + MipLevels = D3DX11_DEFAULT; + Usage = (D3D11_USAGE)D3DX11_DEFAULT; + BindFlags = D3DX11_DEFAULT; + CpuAccessFlags = D3DX11_DEFAULT; + MiscFlags = D3DX11_DEFAULT; + Format = DXGI_FORMAT_FROM_FILE; + Filter = D3DX11_DEFAULT; + MipFilter = D3DX11_DEFAULT; + pSrcInfo = NULL; + } +#endif +} D3DX11_IMAGE_LOAD_INFO; + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI D3DX11CreateShaderResourceViewFromMemory(ID3D11Device *device, const void *data, + SIZE_T data_size, D3DX11_IMAGE_LOAD_INFO *load_info, ID3DX11ThreadPump *pump, + ID3D11ShaderResourceView **view, HRESULT *hresult); + +HRESULT WINAPI D3DX11CreateTextureFromFileA(ID3D11Device *device, const char *filename, + D3DX11_IMAGE_LOAD_INFO *load_info, ID3DX11ThreadPump *pump, ID3D11Resource **texture, + HRESULT *hresult); + +HRESULT WINAPI D3DX11CreateTextureFromFileW(ID3D11Device *device, const WCHAR *filename, + D3DX11_IMAGE_LOAD_INFO *load_info, ID3DX11ThreadPump *pump, ID3D11Resource **texture, + HRESULT *hresult); + +HRESULT WINAPI D3DX11CreateTextureFromMemory(ID3D11Device *device, const void *src_data, SIZE_T src_data_size, + D3DX11_IMAGE_LOAD_INFO *loadinfo, ID3DX11ThreadPump *pump, ID3D11Resource **texture, HRESULT *hresult); + +HRESULT WINAPI D3DX11FilterTexture(ID3D11DeviceContext *context, ID3D11Resource *texture, UINT src_level, UINT filter); + +HRESULT WINAPI D3DX11GetImageInfoFromMemory(const void *src_data, SIZE_T src_data_size, ID3DX11ThreadPump *pump, + D3DX11_IMAGE_INFO *img_info, HRESULT *hresult); + +HRESULT WINAPI D3DX11SaveTextureToMemory(ID3D11DeviceContext *context, ID3D11Resource *texture, + D3DX11_IMAGE_FILE_FORMAT format, ID3D10Blob **buffer, UINT flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/include/psdk/dcommon.idl b/sdk/include/psdk/dcommon.idl new file mode 100644 index 00000000000..53281bd487a --- /dev/null +++ b/sdk/include/psdk/dcommon.idl @@ -0,0 +1,92 @@ +/* + * Copyright 2012 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgiformat.idl"; + +cpp_quote("#if 0") +typedef struct +{ + long x, y; +} POINT; +typedef unsigned int UINT32; +cpp_quote("#endif") + +typedef enum DWRITE_MEASURING_MODE +{ + DWRITE_MEASURING_MODE_NATURAL, + DWRITE_MEASURING_MODE_GDI_CLASSIC, + DWRITE_MEASURING_MODE_GDI_NATURAL +} DWRITE_MEASURING_MODE; + +typedef enum DWRITE_GLYPH_IMAGE_FORMATS +{ + DWRITE_GLYPH_IMAGE_FORMATS_NONE = 0, + DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE = 1 << 0, + DWRITE_GLYPH_IMAGE_FORMATS_CFF = 1 << 1, + DWRITE_GLYPH_IMAGE_FORMATS_COLR = 1 << 2, + DWRITE_GLYPH_IMAGE_FORMATS_SVG = 1 << 3, + DWRITE_GLYPH_IMAGE_FORMATS_PNG = 1 << 4, + DWRITE_GLYPH_IMAGE_FORMATS_JPEG = 1 << 5, + DWRITE_GLYPH_IMAGE_FORMATS_TIFF = 1 << 6, + DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8 = 1 << 7 +} DWRITE_GLYPH_IMAGE_FORMATS; + +typedef enum D2D1_ALPHA_MODE +{ + D2D1_ALPHA_MODE_UNKNOWN = 0, + D2D1_ALPHA_MODE_PREMULTIPLIED = 1, + D2D1_ALPHA_MODE_STRAIGHT = 2, + D2D1_ALPHA_MODE_IGNORE = 3, + D2D1_ALPHA_MODE_FORCE_DWORD = 0xffffffff, +} D2D1_ALPHA_MODE; + +typedef struct D2D1_PIXEL_FORMAT +{ + DXGI_FORMAT format; + D2D1_ALPHA_MODE alphaMode; +} D2D1_PIXEL_FORMAT; + +typedef struct D2D_POINT_2F +{ + float x; + float y; +} D2D_POINT_2F, D2D1_POINT_2F; + +typedef POINT D2D_POINT_2L, D2D1_POINT_2L; + +typedef struct D2D_SIZE_U +{ + UINT32 width; + UINT32 height; +} D2D_SIZE_U, D2D1_SIZE_U; + +typedef struct D2D_MATRIX_4X4_F +{ + union + { + struct + { + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; + }; + + float m[4][4]; + }; +} D2D_MATRIX_4X4_F; diff --git a/sdk/include/psdk/dwrite.idl b/sdk/include/psdk/dwrite.idl new file mode 100644 index 00000000000..bfb2c1b37d5 --- /dev/null +++ b/sdk/include/psdk/dwrite.idl @@ -0,0 +1,1453 @@ +/* + * Copyright 2012 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "unknwn.idl"; +import "dcommon.idl"; + +interface IDWriteFactory; +interface IDWriteFontCollection; +interface IDWriteFontFamily; +interface IDWriteFontFace; +interface IDWriteInlineObject; + +interface ID2D1SimplifiedGeometrySink; +typedef ID2D1SimplifiedGeometrySink IDWriteGeometrySink; + +cpp_quote("#ifndef _WINDEF_") +/* already defined in windef.h but needed for WIDL */ +typedef void *HMONITOR; +cpp_quote("#endif /* _WINDEF_ */") + +cpp_quote("#ifdef WINE_NO_UNICODE_MACROS") +cpp_quote("#undef GetGlyphIndices") +cpp_quote("#endif") + +typedef enum DWRITE_FACTORY_TYPE +{ + DWRITE_FACTORY_TYPE_SHARED, + DWRITE_FACTORY_TYPE_ISOLATED +} DWRITE_FACTORY_TYPE; + +typedef enum DWRITE_FONT_FILE_TYPE +{ + DWRITE_FONT_FILE_TYPE_UNKNOWN, + DWRITE_FONT_FILE_TYPE_CFF, + DWRITE_FONT_FILE_TYPE_TRUETYPE, + DWRITE_FONT_FILE_TYPE_OPENTYPE_COLLECTION, + DWRITE_FONT_FILE_TYPE_TYPE1_PFM, + DWRITE_FONT_FILE_TYPE_TYPE1_PFB, + DWRITE_FONT_FILE_TYPE_VECTOR, + DWRITE_FONT_FILE_TYPE_BITMAP, + DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION = DWRITE_FONT_FILE_TYPE_OPENTYPE_COLLECTION +} DWRITE_FONT_FILE_TYPE; + +typedef enum DWRITE_FONT_FACE_TYPE +{ + DWRITE_FONT_FACE_TYPE_CFF, + DWRITE_FONT_FACE_TYPE_TRUETYPE, + DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION, + DWRITE_FONT_FACE_TYPE_TYPE1, + DWRITE_FONT_FACE_TYPE_VECTOR, + DWRITE_FONT_FACE_TYPE_BITMAP, + DWRITE_FONT_FACE_TYPE_UNKNOWN, + DWRITE_FONT_FACE_TYPE_RAW_CFF, + DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION = DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION +} DWRITE_FONT_FACE_TYPE; + +typedef enum DWRITE_FONT_WEIGHT +{ + DWRITE_FONT_WEIGHT_THIN = 100, + DWRITE_FONT_WEIGHT_EXTRA_LIGHT = 200, + DWRITE_FONT_WEIGHT_ULTRA_LIGHT = 200, + DWRITE_FONT_WEIGHT_LIGHT = 300, + DWRITE_FONT_WEIGHT_SEMI_LIGHT = 350, + DWRITE_FONT_WEIGHT_NORMAL = 400, + DWRITE_FONT_WEIGHT_REGULAR = 400, + DWRITE_FONT_WEIGHT_MEDIUM = 500, + DWRITE_FONT_WEIGHT_DEMI_BOLD = 600, + DWRITE_FONT_WEIGHT_SEMI_BOLD = 600, + DWRITE_FONT_WEIGHT_BOLD = 700, + DWRITE_FONT_WEIGHT_EXTRA_BOLD = 800, + DWRITE_FONT_WEIGHT_ULTRA_BOLD = 800, + DWRITE_FONT_WEIGHT_BLACK = 900, + DWRITE_FONT_WEIGHT_HEAVY = 900, + DWRITE_FONT_WEIGHT_EXTRA_BLACK = 950, + DWRITE_FONT_WEIGHT_ULTRA_BLACK = 950 +} DWRITE_FONT_WEIGHT; + +typedef enum DWRITE_FONT_STRETCH +{ + DWRITE_FONT_STRETCH_UNDEFINED = 0, + DWRITE_FONT_STRETCH_ULTRA_CONDENSED = 1, + DWRITE_FONT_STRETCH_EXTRA_CONDENSED = 2, + DWRITE_FONT_STRETCH_CONDENSED = 3, + DWRITE_FONT_STRETCH_SEMI_CONDENSED = 4, + DWRITE_FONT_STRETCH_NORMAL = 5, + DWRITE_FONT_STRETCH_MEDIUM = 5, + DWRITE_FONT_STRETCH_SEMI_EXPANDED = 6, + DWRITE_FONT_STRETCH_EXPANDED = 7, + DWRITE_FONT_STRETCH_EXTRA_EXPANDED = 8, + DWRITE_FONT_STRETCH_ULTRA_EXPANDED = 9 +} DWRITE_FONT_STRETCH; + +typedef enum DWRITE_FONT_STYLE +{ + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STYLE_OBLIQUE, + DWRITE_FONT_STYLE_ITALIC +} DWRITE_FONT_STYLE; + +typedef enum DWRITE_INFORMATIONAL_STRING_ID +{ + DWRITE_INFORMATIONAL_STRING_NONE, + DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE, + DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS, + DWRITE_INFORMATIONAL_STRING_TRADEMARK, + DWRITE_INFORMATIONAL_STRING_MANUFACTURER, + DWRITE_INFORMATIONAL_STRING_DESIGNER, + DWRITE_INFORMATIONAL_STRING_DESIGNER_URL, + DWRITE_INFORMATIONAL_STRING_DESCRIPTION, + DWRITE_INFORMATIONAL_STRING_FONT_VENDOR_URL, + DWRITE_INFORMATIONAL_STRING_LICENSE_DESCRIPTION, + DWRITE_INFORMATIONAL_STRING_LICENSE_INFO_URL, + DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, + DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES, + DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES, + DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES, + DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT, + DWRITE_INFORMATIONAL_STRING_FULL_NAME, + DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, + DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME +} DWRITE_INFORMATIONAL_STRING_ID; + +typedef enum DWRITE_FONT_SIMULATIONS +{ + DWRITE_FONT_SIMULATIONS_NONE, + DWRITE_FONT_SIMULATIONS_BOLD, + DWRITE_FONT_SIMULATIONS_OBLIQUE +} DWRITE_FONT_SIMULATIONS; + +typedef enum DWRITE_PIXEL_GEOMETRY +{ + DWRITE_PIXEL_GEOMETRY_FLAT, + DWRITE_PIXEL_GEOMETRY_RGB, + DWRITE_PIXEL_GEOMETRY_BGR +} DWRITE_PIXEL_GEOMETRY; + +typedef enum DWRITE_RENDERING_MODE +{ + DWRITE_RENDERING_MODE_DEFAULT, + DWRITE_RENDERING_MODE_ALIASED, + DWRITE_RENDERING_MODE_GDI_CLASSIC, + DWRITE_RENDERING_MODE_GDI_NATURAL, + DWRITE_RENDERING_MODE_NATURAL, + DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC, + DWRITE_RENDERING_MODE_OUTLINE, + DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC = DWRITE_RENDERING_MODE_GDI_CLASSIC, + DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL = DWRITE_RENDERING_MODE_GDI_NATURAL, + DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL = DWRITE_RENDERING_MODE_NATURAL, + DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC = DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC +} DWRITE_RENDERING_MODE; + +typedef enum DWRITE_TEXT_ALIGNMENT +{ + DWRITE_TEXT_ALIGNMENT_LEADING, + DWRITE_TEXT_ALIGNMENT_TRAILING, + DWRITE_TEXT_ALIGNMENT_CENTER, + DWRITE_TEXT_ALIGNMENT_JUSTIFIED +} DWRITE_TEXT_ALIGNMENT; + +typedef enum DWRITE_PARAGRAPH_ALIGNMENT +{ + DWRITE_PARAGRAPH_ALIGNMENT_NEAR, + DWRITE_PARAGRAPH_ALIGNMENT_FAR, + DWRITE_PARAGRAPH_ALIGNMENT_CENTER +} DWRITE_PARAGRAPH_ALIGNMENT; + +typedef enum DWRITE_WORD_WRAPPING +{ + DWRITE_WORD_WRAPPING_WRAP, + DWRITE_WORD_WRAPPING_NO_WRAP, + DWRITE_WORD_WRAPPING_EMERGENCY_BREAK, + DWRITE_WORD_WRAPPING_WHOLE_WORD, + DWRITE_WORD_WRAPPING_CHARACTER +} DWRITE_WORD_WRAPPING; + +typedef enum DWRITE_READING_DIRECTION +{ + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT, + DWRITE_READING_DIRECTION_RIGHT_TO_LEFT, + DWRITE_READING_DIRECTION_TOP_TO_BOTTOM, + DWRITE_READING_DIRECTION_BOTTOM_TO_TOP +} DWRITE_READING_DIRECTION; + +typedef enum DWRITE_FLOW_DIRECTION +{ + DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM, + DWRITE_FLOW_DIRECTION_BOTTOM_TO_TOP, + DWRITE_FLOW_DIRECTION_LEFT_TO_RIGHT, + DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT +} DWRITE_FLOW_DIRECTION; + +typedef enum DWRITE_TRIMMING_GRANULARITY +{ + DWRITE_TRIMMING_GRANULARITY_NONE, + DWRITE_TRIMMING_GRANULARITY_CHARACTER, + DWRITE_TRIMMING_GRANULARITY_WORD +} DWRITE_TRIMMING_GRANULARITY; + +typedef enum DWRITE_BREAK_CONDITION +{ + DWRITE_BREAK_CONDITION_NEUTRAL, + DWRITE_BREAK_CONDITION_CAN_BREAK, + DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, + DWRITE_BREAK_CONDITION_MUST_BREAK +} DWRITE_BREAK_CONDITION; + +typedef enum DWRITE_LINE_SPACING_METHOD +{ + DWRITE_LINE_SPACING_METHOD_DEFAULT, + DWRITE_LINE_SPACING_METHOD_UNIFORM, + DWRITE_LINE_SPACING_METHOD_PROPORTIONAL +} DWRITE_LINE_SPACING_METHOD; + +cpp_quote("#define DWRITE_MAKE_OPENTYPE_TAG(a,b,c,d) ( \\") +cpp_quote(" ((UINT32)(UINT8)(d) << 24) | \\") +cpp_quote(" ((UINT32)(UINT8)(c) << 16) | \\") +cpp_quote(" ((UINT32)(UINT8)(b) << 8) | \\") +cpp_quote(" (UINT32)(UINT8)(a))") + +typedef enum DWRITE_FONT_FEATURE_TAG +{ + DWRITE_FONT_FEATURE_TAG_ALTERNATIVE_FRACTIONS = 0x63726661, /* 'afrc' */ + DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS_FROM_CAPITALS = 0x63703263, /* 'c2pc' */ + DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS_FROM_CAPITALS = 0x63733263, /* 'c2sc' */ + DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_ALTERNATES = 0x746c6163, /* 'calt' */ + DWRITE_FONT_FEATURE_TAG_CASE_SENSITIVE_FORMS = 0x65736163, /* 'case' */ + DWRITE_FONT_FEATURE_TAG_GLYPH_COMPOSITION_DECOMPOSITION = 0x706d6363, /* 'ccmp' */ + DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_LIGATURES = 0x67696c63, /* 'clig' */ + DWRITE_FONT_FEATURE_TAG_CAPITAL_SPACING = 0x70737063, /* 'cpsp' */ + DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_SWASH = 0x68777363, /* 'cswh' */ + DWRITE_FONT_FEATURE_TAG_CURSIVE_POSITIONING = 0x73727563, /* 'curs' */ + DWRITE_FONT_FEATURE_TAG_DEFAULT = 0x746c6664, /* 'dflt' */ + DWRITE_FONT_FEATURE_TAG_DISCRETIONARY_LIGATURES = 0x67696c64, /* 'dlig' */ + DWRITE_FONT_FEATURE_TAG_EXPERT_FORMS = 0x74707865, /* 'expt' */ + DWRITE_FONT_FEATURE_TAG_FRACTIONS = 0x63617266, /* 'frac' */ + DWRITE_FONT_FEATURE_TAG_FULL_WIDTH = 0x64697766, /* 'fwid' */ + DWRITE_FONT_FEATURE_TAG_HALF_FORMS = 0x666c6168, /* 'half' */ + DWRITE_FONT_FEATURE_TAG_HALANT_FORMS = 0x6e6c6168, /* 'haln' */ + DWRITE_FONT_FEATURE_TAG_ALTERNATE_HALF_WIDTH = 0x746c6168, /* 'halt' */ + DWRITE_FONT_FEATURE_TAG_HISTORICAL_FORMS = 0x74736968, /* 'hist' */ + DWRITE_FONT_FEATURE_TAG_HORIZONTAL_KANA_ALTERNATES = 0x616e6b68, /* 'hkna' */ + DWRITE_FONT_FEATURE_TAG_HISTORICAL_LIGATURES = 0x67696c68, /* 'hlig' */ + DWRITE_FONT_FEATURE_TAG_HALF_WIDTH = 0x64697768, /* 'hwid' */ + DWRITE_FONT_FEATURE_TAG_HOJO_KANJI_FORMS = 0x6f6a6f68, /* 'hojo' */ + DWRITE_FONT_FEATURE_TAG_JIS04_FORMS = 0x3430706a, /* 'jp04' */ + DWRITE_FONT_FEATURE_TAG_JIS78_FORMS = 0x3837706a, /* 'jp78' */ + DWRITE_FONT_FEATURE_TAG_JIS83_FORMS = 0x3338706a, /* 'jp83' */ + DWRITE_FONT_FEATURE_TAG_JIS90_FORMS = 0x3039706a, /* 'jp90' */ + DWRITE_FONT_FEATURE_TAG_KERNING = 0x6e72656b, /* 'kern' */ + DWRITE_FONT_FEATURE_TAG_STANDARD_LIGATURES = 0x6167696c, /* 'liga' */ + DWRITE_FONT_FEATURE_TAG_LINING_FIGURES = 0x6d756e6c, /* 'lnum' */ + DWRITE_FONT_FEATURE_TAG_LOCALIZED_FORMS = 0x6c636f6c, /* 'locl' */ + DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING = 0x6b72616d, /* 'mark' */ + DWRITE_FONT_FEATURE_TAG_MATHEMATICAL_GREEK = 0x6b72676d, /* 'mgrk' */ + DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING = 0x6b6d6b6d, /* 'mkmk' */ + DWRITE_FONT_FEATURE_TAG_ALTERNATE_ANNOTATION_FORMS = 0x746c616e, /* 'nalt' */ + DWRITE_FONT_FEATURE_TAG_NLC_KANJI_FORMS = 0x6b636c6e, /* 'nlck' */ + DWRITE_FONT_FEATURE_TAG_OLD_STYLE_FIGURES = 0x6d756e6f, /* 'onum' */ + DWRITE_FONT_FEATURE_TAG_ORDINALS = 0x6e64726f, /* 'ordn' */ + DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_ALTERNATE_WIDTH = 0x746c6170, /* 'palt' */ + DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS = 0x70616370, /* 'pcap' */ + DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_FIGURES = 0x6d756e70, /* 'pnum' */ + DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_WIDTHS = 0x64697770, /* 'pwid' */ + DWRITE_FONT_FEATURE_TAG_QUARTER_WIDTHS = 0x64697771, /* 'qwid' */ + DWRITE_FONT_FEATURE_TAG_REQUIRED_LIGATURES = 0x67696c72, /* 'rlig' */ + DWRITE_FONT_FEATURE_TAG_RUBY_NOTATION_FORMS = 0x79627572, /* 'ruby' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_ALTERNATES = 0x746c6173, /* 'salt' */ + DWRITE_FONT_FEATURE_TAG_SCIENTIFIC_INFERIORS = 0x666e6973, /* 'sinf' */ + DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS = 0x70636d73, /* 'smcp' */ + DWRITE_FONT_FEATURE_TAG_SIMPLIFIED_FORMS = 0x6c706d73, /* 'smpl' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_1 = 0x31307373, /* 'ss01' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_2 = 0x32307373, /* 'ss02' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_3 = 0x33307373, /* 'ss03' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_4 = 0x34307373, /* 'ss04' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_5 = 0x35307373, /* 'ss05' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6 = 0x36307373, /* 'ss06' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7 = 0x37307373, /* 'ss07' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_8 = 0x38307373, /* 'ss08' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_9 = 0x39307373, /* 'ss09' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_10 = 0x30317373, /* 'ss10' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_11 = 0x31317373, /* 'ss11' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_12 = 0x32317373, /* 'ss12' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_13 = 0x33317373, /* 'ss13' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_14 = 0x34317373, /* 'ss14' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_15 = 0x35317373, /* 'ss15' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_16 = 0x36317373, /* 'ss16' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_17 = 0x37317373, /* 'ss17' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_18 = 0x38317373, /* 'ss18' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_19 = 0x39317373, /* 'ss19' */ + DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_20 = 0x30327373, /* 'ss20' */ + DWRITE_FONT_FEATURE_TAG_SUBSCRIPT = 0x73627573, /* 'subs' */ + DWRITE_FONT_FEATURE_TAG_SUPERSCRIPT = 0x73707573, /* 'sups' */ + DWRITE_FONT_FEATURE_TAG_SWASH = 0x68737773, /* 'swsh' */ + DWRITE_FONT_FEATURE_TAG_TITLING = 0x6c746974, /* 'titl' */ + DWRITE_FONT_FEATURE_TAG_TRADITIONAL_NAME_FORMS = 0x6d616e74, /* 'tnam' */ + DWRITE_FONT_FEATURE_TAG_TABULAR_FIGURES = 0x6d756e74, /* 'tnum' */ + DWRITE_FONT_FEATURE_TAG_TRADITIONAL_FORMS = 0x64617274, /* 'trad' */ + DWRITE_FONT_FEATURE_TAG_THIRD_WIDTHS = 0x64697774, /* 'twid' */ + DWRITE_FONT_FEATURE_TAG_UNICASE = 0x63696e75, /* 'unic' */ + DWRITE_FONT_FEATURE_TAG_VERTICAL_WRITING = 0x74726576, /* 'vert' */ + DWRITE_FONT_FEATURE_TAG_VERTICAL_ALTERNATES_AND_ROTATION= 0x32747276, /* 'vrt2' */ + DWRITE_FONT_FEATURE_TAG_SLASHED_ZERO = 0x6f72657a, /* 'zero' */ +} DWRITE_FONT_FEATURE_TAG; + +typedef enum DWRITE_SCRIPT_SHAPES +{ + DWRITE_SCRIPT_SHAPES_DEFAULT = 0, + DWRITE_SCRIPT_SHAPES_NO_VISUAL = 1 +} DWRITE_SCRIPT_SHAPES; + +typedef enum DWRITE_NUMBER_SUBSTITUTION_METHOD +{ + DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE, + DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL, + DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, + DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL, + DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL +} DWRITE_NUMBER_SUBSTITUTION_METHOD; + +cpp_quote("#define DWRITE_ALPHA_MAX 255") + +typedef enum DWRITE_TEXTURE_TYPE +{ + DWRITE_TEXTURE_ALIASED_1x1, + DWRITE_TEXTURE_CLEARTYPE_3x1 +} DWRITE_TEXTURE_TYPE; + +typedef struct DWRITE_FONT_METRICS +{ + UINT16 designUnitsPerEm; + UINT16 ascent; + UINT16 descent; + INT16 lineGap; + UINT16 capHeight; + UINT16 xHeight; + INT16 underlinePosition; + UINT16 underlineThickness; + INT16 strikethroughPosition; + UINT16 strikethroughThickness; +} DWRITE_FONT_METRICS; + +typedef struct DWRITE_GLYPH_METRICS +{ + INT32 leftSideBearing; + UINT32 advanceWidth; + INT32 rightSideBearing; + INT32 topSideBearing; + UINT32 advanceHeight; + INT32 bottomSideBearing; + INT32 verticalOriginY; +} DWRITE_GLYPH_METRICS; + +typedef struct DWRITE_GLYPH_OFFSET +{ + FLOAT advanceOffset; + FLOAT ascenderOffset; +} DWRITE_GLYPH_OFFSET; + +typedef struct DWRITE_MATRIX +{ + FLOAT m11; + FLOAT m12; + FLOAT m21; + FLOAT m22; + FLOAT dx; + FLOAT dy; +} DWRITE_MATRIX; + +typedef struct DWRITE_TRIMMING +{ + DWRITE_TRIMMING_GRANULARITY granularity; + UINT32 delimiter; + UINT32 delimiterCount; +} DWRITE_TRIMMING; + +cpp_quote("#ifndef __d2d1_h__") +typedef struct DWRITE_GLYPH_RUN DWRITE_GLYPH_RUN; +cpp_quote("#endif /* __d2d1_h__ */") + +struct DWRITE_GLYPH_RUN +{ + IDWriteFontFace* fontFace; + FLOAT fontEmSize; + UINT32 glyphCount; + UINT16 const* glyphIndices; + FLOAT const* glyphAdvances; + DWRITE_GLYPH_OFFSET const* glyphOffsets; + BOOL isSideways; + UINT32 bidiLevel; +}; + +cpp_quote("#ifndef __d2d1_1_h__") +typedef struct DWRITE_GLYPH_RUN_DESCRIPTION DWRITE_GLYPH_RUN_DESCRIPTION; +cpp_quote("#endif /* __d2d1_1_h__ */") + +struct DWRITE_GLYPH_RUN_DESCRIPTION +{ + WCHAR const* localeName; + WCHAR const* string; + UINT32 stringLength; + UINT16 const* clusterMap; + UINT32 textPosition; +}; + +typedef struct DWRITE_UNDERLINE +{ + FLOAT width; + FLOAT thickness; + FLOAT offset; + FLOAT runHeight; + DWRITE_READING_DIRECTION readingDirection; + DWRITE_FLOW_DIRECTION flowDirection; + WCHAR const* localeName; + DWRITE_MEASURING_MODE measuringMode; +} DWRITE_UNDERLINE; + +typedef struct DWRITE_STRIKETHROUGH +{ + FLOAT width; + FLOAT thickness; + FLOAT offset; + DWRITE_READING_DIRECTION readingDirection; + DWRITE_FLOW_DIRECTION flowDirection; + WCHAR const* localeName; + DWRITE_MEASURING_MODE measuringMode; +} DWRITE_STRIKETHROUGH; + +typedef struct DWRITE_INLINE_OBJECT_METRICS +{ + FLOAT width; + FLOAT height; + FLOAT baseline; + BOOL supportsSideways; +} DWRITE_INLINE_OBJECT_METRICS; + +typedef struct DWRITE_OVERHANG_METRICS +{ + FLOAT left; + FLOAT top; + FLOAT right; + FLOAT bottom; +} DWRITE_OVERHANG_METRICS; + +typedef struct DWRITE_FONT_FEATURE +{ + DWRITE_FONT_FEATURE_TAG nameTag; + UINT32 parameter; +} DWRITE_FONT_FEATURE; + +typedef struct DWRITE_TEXT_RANGE +{ + UINT32 startPosition; + UINT32 length; +} DWRITE_TEXT_RANGE; + +typedef struct DWRITE_LINE_METRICS +{ + UINT32 length; + UINT32 trailingWhitespaceLength; + UINT32 newlineLength; + FLOAT height; + FLOAT baseline; + BOOL isTrimmed; +} DWRITE_LINE_METRICS; + +typedef struct DWRITE_TEXT_METRICS +{ + FLOAT left; + FLOAT top; + FLOAT width; + FLOAT widthIncludingTrailingWhitespace; + FLOAT height; + FLOAT layoutWidth; + FLOAT layoutHeight; + UINT32 maxBidiReorderingDepth; + UINT32 lineCount; +} DWRITE_TEXT_METRICS; + +typedef struct DWRITE_CLUSTER_METRICS +{ + FLOAT width; + UINT16 length; + UINT16 canWrapLineAfter : 1; + UINT16 isWhitespace : 1; + UINT16 isNewline : 1; + UINT16 isSoftHyphen : 1; + UINT16 isRightToLeft : 1; + UINT16 padding : 11; +} DWRITE_CLUSTER_METRICS; + +typedef struct DWRITE_HIT_TEST_METRICS +{ + UINT32 textPosition; + UINT32 length; + FLOAT left; + FLOAT top; + FLOAT width; + FLOAT height; + UINT32 bidiLevel; + BOOL isText; + BOOL isTrimmed; +} DWRITE_HIT_TEST_METRICS; + +typedef struct DWRITE_SCRIPT_ANALYSIS +{ + UINT16 script; + DWRITE_SCRIPT_SHAPES shapes; +} DWRITE_SCRIPT_ANALYSIS; + +typedef struct DWRITE_LINE_BREAKPOINT +{ + UINT8 breakConditionBefore : 2; + UINT8 breakConditionAfter : 2; + UINT8 isWhitespace : 1; + UINT8 isSoftHyphen : 1; + UINT8 padding : 2; +} DWRITE_LINE_BREAKPOINT; + +typedef struct DWRITE_TYPOGRAPHIC_FEATURES +{ + DWRITE_FONT_FEATURE* features; + UINT32 featureCount; +} DWRITE_TYPOGRAPHIC_FEATURES; + +typedef struct DWRITE_SHAPING_TEXT_PROPERTIES +{ + UINT16 isShapedAlone : 1; + UINT16 reserved : 15; +} DWRITE_SHAPING_TEXT_PROPERTIES; + +typedef struct DWRITE_SHAPING_GLYPH_PROPERTIES +{ + UINT16 justification : 4; + UINT16 isClusterStart : 1; + UINT16 isDiacritic : 1; + UINT16 isZeroWidthSpace : 1; + UINT16 reserved : 9; +} DWRITE_SHAPING_GLYPH_PROPERTIES; + +[ +local, +object, +uuid(6d4865fe-0ab8-4d91-8f62-5dd6be34a3e0) +] +interface IDWriteFontFileStream : IUnknown +{ + HRESULT ReadFileFragment( + void const **fragment_start, + UINT64 offset, + UINT64 fragment_size, + void **fragment_context); + + void ReleaseFileFragment(void *fragment_context); + HRESULT GetFileSize(UINT64 *size); + HRESULT GetLastWriteTime(UINT64 *last_writetime); +} + +[ +local, +object, +uuid(727cad4e-d6af-4c9e-8a08-d695b11caa49) +] +interface IDWriteFontFileLoader : IUnknown +{ + HRESULT CreateStreamFromKey( + void const *key, + UINT32 key_size, + IDWriteFontFileStream **stream); +} + +[ +local, +object, +uuid(b2d9f3ec-c9fe-4a11-a2ec-d86208f7c0a2) +] +interface IDWriteLocalFontFileLoader : IDWriteFontFileLoader +{ + HRESULT GetFilePathLengthFromKey(void const *key, UINT32 key_size, UINT32 *length); + HRESULT GetFilePathFromKey(void const *key, UINT32 key_size, WCHAR *path, UINT32 length); + HRESULT GetLastWriteTimeFromKey(void const *key, UINT32 key_size, FILETIME *writetime); +} + +[ +local, +object, +uuid(739d886a-cef5-47dc-8769-1a8b41bebbb0) +] +interface IDWriteFontFile : IUnknown +{ + HRESULT GetReferenceKey( + void const **key, + UINT32 *key_size); + + HRESULT GetLoader(IDWriteFontFileLoader **loader); + + HRESULT Analyze( + BOOL *is_supported_fonttype, + DWRITE_FONT_FILE_TYPE *file_type, + DWRITE_FONT_FACE_TYPE *face_type, + UINT32 *faces_num); +} + +[ +local, +object, +uuid(72755049-5ff7-435d-8348-4be97cfa6c7c) +] +interface IDWriteFontFileEnumerator : IUnknown +{ + HRESULT MoveNext(BOOL *has_current_file); + HRESULT GetCurrentFontFile(IDWriteFontFile **font_file); +} + +[ +local, +object, +uuid(cca920e4-52f0-492b-bfa8-29c72ee0a468) +] +interface IDWriteFontCollectionLoader : IUnknown +{ + HRESULT CreateEnumeratorFromKey( + IDWriteFactory* factory, + void const* key, + UINT32 key_size, + IDWriteFontFileEnumerator **enumerator); +} + +[ +local, +object, +uuid(08256209-099a-4b34-b86d-c22b110e7771) +] +interface IDWriteLocalizedStrings : IUnknown +{ + UINT32 GetCount(); + + HRESULT FindLocaleName( + WCHAR const *locale_name, + UINT32 *index, + BOOL *exists); + + HRESULT GetLocaleNameLength(UINT32 index, UINT32 *length); + HRESULT GetLocaleName(UINT32 index, WCHAR *locale_name, UINT32 size); + HRESULT GetStringLength(UINT32 index, UINT32 *length); + HRESULT GetString(UINT32 index, WCHAR *buffer, UINT32 size); +} + +[ +local, +object, +uuid(2f0da53a-2add-47cd-82ee-d9ec34688e75) +] +interface IDWriteRenderingParams : IUnknown +{ + FLOAT GetGamma(); + FLOAT GetEnhancedContrast(); + FLOAT GetClearTypeLevel(); + DWRITE_PIXEL_GEOMETRY GetPixelGeometry(); + DWRITE_RENDERING_MODE GetRenderingMode(); +} + +[ +local, +object, +uuid(5f49804d-7024-4d43-bfa9-d25984f53849) +] +interface IDWriteFontFace : IUnknown +{ + DWRITE_FONT_FACE_TYPE GetType(); + HRESULT GetFiles(UINT32 *number_of_files, IDWriteFontFile **fontfiles); + UINT32 GetIndex(); + DWRITE_FONT_SIMULATIONS GetSimulations(); + BOOL IsSymbolFont(); + void GetMetrics(DWRITE_FONT_METRICS *metrics); + UINT16 GetGlyphCount(); + + HRESULT GetDesignGlyphMetrics( + UINT16 const *glyph_indices, + UINT32 glyph_count, + DWRITE_GLYPH_METRICS *metrics, + [defaultvalue(FALSE)] BOOL is_sideways); + + HRESULT GetGlyphIndices( + UINT32 const *codepoints, + UINT32 count, + UINT16 *glyph_indices); + + HRESULT TryGetFontTable( + UINT32 table_tag, + const void **table_data, + UINT32 *table_size, + void **context, + BOOL *exists); + + void ReleaseFontTable(void *table_context); + + HRESULT GetGlyphRunOutline( + FLOAT emSize, + UINT16 const *glyph_indices, + FLOAT const* glyph_advances, + DWRITE_GLYPH_OFFSET const *glyph_offsets, + UINT32 glyph_count, + BOOL is_sideways, + BOOL is_rtl, + IDWriteGeometrySink *geometrysink); + + HRESULT GetRecommendedRenderingMode( + FLOAT emSize, + FLOAT pixels_per_dip, + DWRITE_MEASURING_MODE mode, + IDWriteRenderingParams* params, + DWRITE_RENDERING_MODE* rendering_mode); + + HRESULT GetGdiCompatibleMetrics( + FLOAT emSize, + FLOAT pixels_per_dip, + DWRITE_MATRIX const *transform, + DWRITE_FONT_METRICS *metrics); + + HRESULT GetGdiCompatibleGlyphMetrics( + FLOAT emSize, + FLOAT pixels_per_dip, + DWRITE_MATRIX const *transform, + BOOL use_gdi_natural, + UINT16 const *glyph_indices, + UINT32 glyph_count, + DWRITE_GLYPH_METRICS *metrics, + [defaultvalue(FALSE)] BOOL is_sideways); +} + +[ +local, +object, +uuid(acd16696-8c14-4f5d-877e-fe3fc1d32737) +] +interface IDWriteFont : IUnknown +{ + HRESULT GetFontFamily(IDWriteFontFamily **family); + DWRITE_FONT_WEIGHT GetWeight(); + DWRITE_FONT_STRETCH GetStretch(); + DWRITE_FONT_STYLE GetStyle(); + BOOL IsSymbolFont(); + + HRESULT GetFaceNames(IDWriteLocalizedStrings **names); + HRESULT GetInformationalStrings( + DWRITE_INFORMATIONAL_STRING_ID stringid, + IDWriteLocalizedStrings **strings, + BOOL *exists); + + DWRITE_FONT_SIMULATIONS GetSimulations(); + void GetMetrics(DWRITE_FONT_METRICS *metrics); + HRESULT HasCharacter(UINT32 value, BOOL *exists); + HRESULT CreateFontFace(IDWriteFontFace **face); +} + +[ +local, +object, +uuid(1a0d8438-1d97-4ec1-aef9-a2fb86ed6acb) +] +interface IDWriteFontList : IUnknown +{ + HRESULT GetFontCollection(IDWriteFontCollection **collection); + UINT32 GetFontCount(); + HRESULT GetFont(UINT32 index, IDWriteFont **font); +} + +[ +local, +object, +uuid(da20d8ef-812a-4c43-9802-62ec4abd7add) +] +interface IDWriteFontFamily : IDWriteFontList +{ + HRESULT GetFamilyNames(IDWriteLocalizedStrings **names); + + HRESULT GetFirstMatchingFont( + DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STRETCH stretch, + DWRITE_FONT_STYLE style, + IDWriteFont **font); + + HRESULT GetMatchingFonts( + DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STRETCH stretch, + DWRITE_FONT_STYLE style, + IDWriteFontList **fonts); +} + +[ +local, +object, +uuid(a84cee02-3eea-4eee-a827-87c1a02a0fcc) +] +interface IDWriteFontCollection : IUnknown +{ + UINT32 GetFontFamilyCount(); + HRESULT GetFontFamily(UINT32 index, IDWriteFontFamily **family); + HRESULT FindFamilyName(WCHAR const *name, UINT32 *index, BOOL *exists); + HRESULT GetFontFromFontFace(IDWriteFontFace *face, IDWriteFont **font); +} + +[ +local, +object, +uuid(eaf3a2da-ecf4-4d24-b644-b34f6842024b) +] +interface IDWritePixelSnapping : IUnknown +{ + HRESULT IsPixelSnappingDisabled( + void *client_drawingcontext, + BOOL *disabled); + + HRESULT GetCurrentTransform( + void *client_drawingcontext, + DWRITE_MATRIX *transform); + + HRESULT GetPixelsPerDip( + void *client_drawingcontext, + FLOAT *pixels_per_dip); +} + +[ +local, +object, +uuid(ef8a8135-5cc6-45fe-8825-c5a0724eb819) +] +interface IDWriteTextRenderer : IDWritePixelSnapping +{ + HRESULT DrawGlyphRun( + void* client_drawingcontext, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_MEASURING_MODE mode, + DWRITE_GLYPH_RUN const *glyph_run, + DWRITE_GLYPH_RUN_DESCRIPTION const *run_descr, + IUnknown *drawing_effect); + + HRESULT DrawUnderline( + void *client_drawingcontext, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_UNDERLINE const* underline, + IUnknown *drawing_effect); + + HRESULT DrawStrikethrough( + void *client_drawingcontext, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_STRIKETHROUGH const* strikethrough, + IUnknown *drawing_effect); + + HRESULT DrawInlineObject( + void *client_drawingcontext, + FLOAT originX, + FLOAT originY, + IDWriteInlineObject *object, + BOOL is_sideways, + BOOL is_rtl, + IUnknown *drawing_effect); +} + +[ +local, +object, +uuid(8339fde3-106f-47ab-8373-1c6295eb10b3) +] +interface IDWriteInlineObject : IUnknown +{ + HRESULT Draw( + void* client_drawingontext, + IDWriteTextRenderer* renderer, + FLOAT originX, + FLOAT originY, + BOOL is_sideways, + BOOL is_rtl, + IUnknown *drawing_effect); + + HRESULT GetMetrics(DWRITE_INLINE_OBJECT_METRICS *metrics); + HRESULT GetOverhangMetrics(DWRITE_OVERHANG_METRICS *overhangs); + HRESULT GetBreakConditions( + DWRITE_BREAK_CONDITION* condition_before, + DWRITE_BREAK_CONDITION* condition_after); +} + +[ +local, +object, +uuid(9c906818-31d7-4fd3-a151-7c5e225db55a) +] +interface IDWriteTextFormat : IUnknown +{ + HRESULT SetTextAlignment(DWRITE_TEXT_ALIGNMENT alignment); + HRESULT SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT alignment); + HRESULT SetWordWrapping(DWRITE_WORD_WRAPPING wrapping); + HRESULT SetReadingDirection(DWRITE_READING_DIRECTION direction); + HRESULT SetFlowDirection(DWRITE_FLOW_DIRECTION direction); + HRESULT SetIncrementalTabStop(FLOAT tabstop); + HRESULT SetTrimming(DWRITE_TRIMMING const *trimming, IDWriteInlineObject *trimming_sign); + HRESULT SetLineSpacing(DWRITE_LINE_SPACING_METHOD spacing, FLOAT line_spacing, FLOAT baseline); + DWRITE_TEXT_ALIGNMENT GetTextAlignment(); + DWRITE_PARAGRAPH_ALIGNMENT GetParagraphAlignment(); + DWRITE_WORD_WRAPPING GetWordWrapping(); + DWRITE_READING_DIRECTION GetReadingDirection(); + DWRITE_FLOW_DIRECTION GetFlowDirection(); + FLOAT GetIncrementalTabStop(); + HRESULT GetTrimming(DWRITE_TRIMMING *options, IDWriteInlineObject **trimming_sign); + + HRESULT GetLineSpacing( + DWRITE_LINE_SPACING_METHOD *method, + FLOAT *spacing, + FLOAT *baseline); + + HRESULT GetFontCollection(IDWriteFontCollection **collection); + UINT32 GetFontFamilyNameLength(); + HRESULT GetFontFamilyName(WCHAR *name, UINT32 size); + DWRITE_FONT_WEIGHT GetFontWeight(); + DWRITE_FONT_STYLE GetFontStyle(); + DWRITE_FONT_STRETCH GetFontStretch(); + FLOAT GetFontSize(); + UINT32 GetLocaleNameLength(); + HRESULT GetLocaleName(WCHAR *name, UINT32 size); +} + +[ +local, +object, +uuid(55f1112b-1dc2-4b3c-9541-f46894ed85b6) +] +interface IDWriteTypography : IUnknown +{ + HRESULT AddFontFeature(DWRITE_FONT_FEATURE feature); + UINT32 GetFontFeatureCount(); + HRESULT GetFontFeature(UINT32 index, DWRITE_FONT_FEATURE *feature); +} + +[ +local, +object, +uuid(5e5a32a3-8dff-4773-9ff6-0696eab77267) +] +interface IDWriteBitmapRenderTarget : IUnknown +{ + HRESULT DrawGlyphRun( + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_MEASURING_MODE measuring_mode, + DWRITE_GLYPH_RUN const* glyph_run, + IDWriteRenderingParams* params, + COLORREF textColor, + [defaultvalue(NULL)] RECT *blackbox_rect); + + HDC GetMemoryDC(); + FLOAT GetPixelsPerDip(); + HRESULT SetPixelsPerDip(FLOAT pixels_per_dip); + HRESULT GetCurrentTransform(DWRITE_MATRIX *transform); + HRESULT SetCurrentTransform(DWRITE_MATRIX const *transform); + HRESULT GetSize(SIZE *size); + HRESULT Resize(UINT32 width, UINT32 height); +} + +cpp_quote("#ifndef _WINGDI_") +/* already defined in wingdi.h but needed for WIDL */ +#define LF_FACESIZE 32 + + typedef struct tagLOGFONTW + { + LONG lfHeight; + LONG lfWidth; + LONG lfEscapement; + LONG lfOrientation; + LONG lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + WCHAR lfFaceName[LF_FACESIZE]; + } LOGFONTW, *PLOGFONTW, *LPLOGFONTW; +cpp_quote("#endif /* _WINGDI_ */") + +[ +local, +object, +uuid(1edd9491-9853-4299-898f-6432983b6f3a) +] +interface IDWriteGdiInterop : IUnknown +{ + HRESULT CreateFontFromLOGFONT(LOGFONTW const *logfont, IDWriteFont **font); + HRESULT ConvertFontToLOGFONT( + IDWriteFont* font, + LOGFONTW* logfont, + BOOL *is_systemfont); + + HRESULT ConvertFontFaceToLOGFONT(IDWriteFontFace* font, LOGFONTW* logfont); + HRESULT CreateFontFaceFromHdc(HDC hdc, IDWriteFontFace **fontface); + HRESULT CreateBitmapRenderTarget(HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **target); +} + +[ +local, +object, +uuid(53737037-6d14-410b-9bfe-0b182bb70961) +] +interface IDWriteTextLayout : IDWriteTextFormat +{ + HRESULT SetMaxWidth(FLOAT maxWidth); + HRESULT SetMaxHeight(FLOAT maxHeight); + HRESULT SetFontCollection(IDWriteFontCollection* collection, DWRITE_TEXT_RANGE range); + HRESULT SetFontFamilyName(WCHAR const *name, DWRITE_TEXT_RANGE range); + HRESULT SetFontWeight(DWRITE_FONT_WEIGHT weight, DWRITE_TEXT_RANGE range); + HRESULT SetFontStyle(DWRITE_FONT_STYLE style, DWRITE_TEXT_RANGE range); + HRESULT SetFontStretch(DWRITE_FONT_STRETCH stretch, DWRITE_TEXT_RANGE range); + HRESULT SetFontSize(FLOAT size, DWRITE_TEXT_RANGE range); + HRESULT SetUnderline(BOOL underline, DWRITE_TEXT_RANGE range); + HRESULT SetStrikethrough(BOOL strikethrough, DWRITE_TEXT_RANGE range); + HRESULT SetDrawingEffect(IUnknown* effect, DWRITE_TEXT_RANGE range); + HRESULT SetInlineObject(IDWriteInlineObject *object, DWRITE_TEXT_RANGE range); + HRESULT SetTypography(IDWriteTypography* typography, DWRITE_TEXT_RANGE range); + HRESULT SetLocaleName(WCHAR const* locale, DWRITE_TEXT_RANGE range); + + FLOAT GetMaxWidth(); + FLOAT GetMaxHeight(); + HRESULT GetFontCollection( + UINT32 pos, + IDWriteFontCollection** collection, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetFontFamilyNameLength( + UINT32 pos, + UINT32* len, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetFontFamilyName( + UINT32 position, + WCHAR* name, + UINT32 name_size, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetFontWeight( + UINT32 position, + DWRITE_FONT_WEIGHT *weight, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetFontStyle( + UINT32 currentPosition, + DWRITE_FONT_STYLE *style, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetFontStretch( + UINT32 position, + DWRITE_FONT_STRETCH *stretch, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetFontSize( + UINT32 position, + FLOAT *size, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetUnderline( + UINT32 position, + BOOL *has_underline, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetStrikethrough( + UINT32 position, + BOOL *has_strikethrough, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetDrawingEffect( + UINT32 position, + IUnknown **effect, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetInlineObject( + UINT32 position, + IDWriteInlineObject **object, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetTypography( + UINT32 position, + IDWriteTypography** typography, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetLocaleNameLength( + UINT32 position, + UINT32* length, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT GetLocaleName( + UINT32 position, + WCHAR* name, + UINT32 name_size, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); + + HRESULT Draw( + void *context, + IDWriteTextRenderer* renderer, + FLOAT originX, + FLOAT originY); + + HRESULT GetLineMetrics( + DWRITE_LINE_METRICS *metrics, + UINT32 max_count, + UINT32 *actual_count); + + HRESULT GetMetrics(DWRITE_TEXT_METRICS *metrics); + HRESULT GetOverhangMetrics(DWRITE_OVERHANG_METRICS *overhangs); + HRESULT GetClusterMetrics( + DWRITE_CLUSTER_METRICS *metrics, + UINT32 max_count, + UINT32* act_count); + + HRESULT DetermineMinWidth(FLOAT* min_width); + HRESULT HitTestPoint( + FLOAT pointX, + FLOAT pointY, + BOOL* is_trailinghit, + BOOL* is_inside, + DWRITE_HIT_TEST_METRICS *metrics); + + HRESULT HitTestTextPosition( + UINT32 textPosition, + BOOL is_trailinghit, + FLOAT* pointX, + FLOAT* pointY, + DWRITE_HIT_TEST_METRICS *metrics); + + HRESULT HitTestTextRange( + UINT32 textPosition, + UINT32 textLength, + FLOAT originX, + FLOAT originY, + DWRITE_HIT_TEST_METRICS *metrics, + UINT32 max_metricscount, + UINT32* actual_metricscount); +} + +[ +local, +object, +uuid(14885cc9-bab0-4f90-b6ed-5c366a2cd03d) +] +interface IDWriteNumberSubstitution : IUnknown +{ +} + +[ +local, +object, +uuid(688e1a58-5094-47c8-adc8-fbcea60ae92b) +] +interface IDWriteTextAnalysisSource : IUnknown +{ + HRESULT GetTextAtPosition( + UINT32 position, + WCHAR const** text, + UINT32* text_len); + + HRESULT GetTextBeforePosition( + UINT32 position, + WCHAR const** text, + UINT32* text_len); + + DWRITE_READING_DIRECTION GetParagraphReadingDirection(); + HRESULT GetLocaleName( + UINT32 position, + UINT32* text_len, + WCHAR const** locale); + + HRESULT GetNumberSubstitution( + UINT32 position, + UINT32* text_len, + IDWriteNumberSubstitution **substitution); +} + +[ +local, +object, +uuid(5810cd44-0ca0-4701-b3fa-bec5182ae4f6) +] +interface IDWriteTextAnalysisSink : IUnknown +{ + HRESULT SetScriptAnalysis( + UINT32 position, + UINT32 length, + DWRITE_SCRIPT_ANALYSIS const* scriptanalysis); + + HRESULT SetLineBreakpoints( + UINT32 position, + UINT32 length, + DWRITE_LINE_BREAKPOINT const* breakpoints); + + HRESULT SetBidiLevel( + UINT32 position, + UINT32 length, + UINT8 explicitLevel, + UINT8 resolvedLevel); + + HRESULT SetNumberSubstitution( + UINT32 position, + UINT32 length, + IDWriteNumberSubstitution* substitution); +} + +[ +local, +object, +uuid(b7e6163e-7f46-43b4-84b3-e4e6249c365d) +] +interface IDWriteTextAnalyzer : IUnknown +{ + HRESULT AnalyzeScript( + IDWriteTextAnalysisSource* source, + UINT32 position, + UINT32 length, + IDWriteTextAnalysisSink* sink); + + HRESULT AnalyzeBidi( + IDWriteTextAnalysisSource* source, + UINT32 position, + UINT32 length, + IDWriteTextAnalysisSink* sink); + + HRESULT AnalyzeNumberSubstitution( + IDWriteTextAnalysisSource* source, + UINT32 position, + UINT32 length, + IDWriteTextAnalysisSink* sink); + + HRESULT AnalyzeLineBreakpoints( + IDWriteTextAnalysisSource* source, + UINT32 position, + UINT32 length, + IDWriteTextAnalysisSink* sink); + + HRESULT GetGlyphs( + WCHAR const* text, + UINT32 length, + IDWriteFontFace* font_face, + BOOL is_sideways, + BOOL is_rtl, + DWRITE_SCRIPT_ANALYSIS const* analysis, + WCHAR const* locale, + IDWriteNumberSubstitution* substitution, + DWRITE_TYPOGRAPHIC_FEATURES const** features, + UINT32 const* feature_range_len, + UINT32 feature_ranges, + UINT32 max_glyph_count, + UINT16* clustermap, + DWRITE_SHAPING_TEXT_PROPERTIES* text_props, + UINT16* glyph_indices, + DWRITE_SHAPING_GLYPH_PROPERTIES* glyph_props, + UINT32* actual_glyph_count); + + HRESULT GetGlyphPlacements( + WCHAR const* text, + UINT16 const* clustermap, + DWRITE_SHAPING_TEXT_PROPERTIES* props, + UINT32 text_len, + UINT16 const* glyph_indices, + DWRITE_SHAPING_GLYPH_PROPERTIES const* glyph_props, + UINT32 glyph_count, + IDWriteFontFace * font_face, + FLOAT fontEmSize, + BOOL is_sideways, + BOOL is_rtl, + DWRITE_SCRIPT_ANALYSIS const* analysis, + WCHAR const* locale, + DWRITE_TYPOGRAPHIC_FEATURES const** features, + UINT32 const* feature_range_len, + UINT32 feature_ranges, + FLOAT* glyph_advances, + DWRITE_GLYPH_OFFSET* glyph_offsets); + + HRESULT GetGdiCompatibleGlyphPlacements( + WCHAR const* text, + UINT16 const* clustermap, + DWRITE_SHAPING_TEXT_PROPERTIES* props, + UINT32 text_len, + UINT16 const* glyph_indices, + DWRITE_SHAPING_GLYPH_PROPERTIES const* glyph_props, + UINT32 glyph_count, + IDWriteFontFace * font_face, + FLOAT fontEmSize, + FLOAT pixels_per_dip, + DWRITE_MATRIX const* transform, + BOOL use_gdi_natural, + BOOL is_sideways, + BOOL is_rtl, + DWRITE_SCRIPT_ANALYSIS const* analysis, + WCHAR const* locale, + DWRITE_TYPOGRAPHIC_FEATURES const** features, + UINT32 const* feature_range_lengths, + UINT32 feature_ranges, + FLOAT* glyph_advances, + DWRITE_GLYPH_OFFSET* glyph_offsets); +} + +[ +local, +object, +uuid(7d97dbf7-e085-42d4-81e3-6a883bded118) +] +interface IDWriteGlyphRunAnalysis : IUnknown +{ + HRESULT GetAlphaTextureBounds(DWRITE_TEXTURE_TYPE type, RECT* bounds); + HRESULT CreateAlphaTexture(DWRITE_TEXTURE_TYPE type, RECT const* bounds, BYTE* alphaValues, UINT32 bufferSize); + HRESULT GetAlphaBlendParams( + IDWriteRenderingParams* renderingParams, + FLOAT* blendGamma, + FLOAT* blendEnhancedContrast, + FLOAT* blendClearTypeLevel); +} + +[ +local, +object, +uuid(b859ee5a-d838-4b5b-a2e8-1adc7d93db48) +] +interface IDWriteFactory : IUnknown +{ + HRESULT GetSystemFontCollection(IDWriteFontCollection **collection, + [defaultvalue(FALSE)] BOOL check_for_updates); + + HRESULT CreateCustomFontCollection( + IDWriteFontCollectionLoader *loader, + void const *key, + UINT32 key_size, + IDWriteFontCollection **collection); + + HRESULT RegisterFontCollectionLoader(IDWriteFontCollectionLoader *loader); + + HRESULT UnregisterFontCollectionLoader(IDWriteFontCollectionLoader *loader); + + HRESULT CreateFontFileReference( + WCHAR const *path, + FILETIME const *writetime, + IDWriteFontFile **font_file); + + HRESULT CreateCustomFontFileReference( + void const *reference_key, + UINT32 key_size, + IDWriteFontFileLoader *loader, + IDWriteFontFile **font_file); + + HRESULT CreateFontFace( + DWRITE_FONT_FACE_TYPE facetype, + UINT32 files_number, + IDWriteFontFile* const* font_files, + UINT32 index, + DWRITE_FONT_SIMULATIONS sim_flags, + IDWriteFontFace **font_face); + + HRESULT CreateRenderingParams(IDWriteRenderingParams **params); + + HRESULT CreateMonitorRenderingParams( + HMONITOR monitor, + IDWriteRenderingParams **params); + + HRESULT CreateCustomRenderingParams( + FLOAT gamma, + FLOAT enhancedContrast, + FLOAT cleartype_level, + DWRITE_PIXEL_GEOMETRY geometry, + DWRITE_RENDERING_MODE mode, + IDWriteRenderingParams **params); + + HRESULT RegisterFontFileLoader(IDWriteFontFileLoader *loader); + + HRESULT UnregisterFontFileLoader(IDWriteFontFileLoader *loader); + + HRESULT CreateTextFormat( + WCHAR const* family_name, + IDWriteFontCollection *collection, + DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STYLE style, + DWRITE_FONT_STRETCH stretch, + FLOAT size, + WCHAR const *locale, + IDWriteTextFormat **format); + + HRESULT CreateTypography(IDWriteTypography **typography); + + HRESULT GetGdiInterop(IDWriteGdiInterop **gdi_interop); + + HRESULT CreateTextLayout( + WCHAR const* string, + UINT32 len, + IDWriteTextFormat *format, + FLOAT max_width, + FLOAT max_height, + IDWriteTextLayout **layout); + + HRESULT CreateGdiCompatibleTextLayout( + WCHAR const* string, + UINT32 len, + IDWriteTextFormat *format, + FLOAT layout_width, + FLOAT layout_height, + FLOAT pixels_per_dip, + DWRITE_MATRIX const* transform, + BOOL use_gdi_natural, + IDWriteTextLayout **layout); + + HRESULT CreateEllipsisTrimmingSign( + IDWriteTextFormat *format, + IDWriteInlineObject **trimming_sign); + + HRESULT CreateTextAnalyzer(IDWriteTextAnalyzer **analyzer); + + HRESULT CreateNumberSubstitution( + DWRITE_NUMBER_SUBSTITUTION_METHOD method, + WCHAR const* locale, + BOOL ignore_user_override, + IDWriteNumberSubstitution **substitution); + + HRESULT CreateGlyphRunAnalysis( + DWRITE_GLYPH_RUN const *glyph_run, + FLOAT pixels_per_dip, + DWRITE_MATRIX const* transform, + DWRITE_RENDERING_MODE rendering_mode, + DWRITE_MEASURING_MODE measuring_mode, + FLOAT baseline_x, + FLOAT baseline_y, + IDWriteGlyphRunAnalysis **analysis); +} + +cpp_quote("HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE,REFIID,IUnknown**);") + +/* error codes */ +cpp_quote("#define FACILITY_DWRITE 0x898") +cpp_quote("#define DWRITE_ERR_BASE 0x5000") +cpp_quote("#define MAKE_DWRITE_HR(severity, code) MAKE_HRESULT(severity, FACILITY_DWRITE, (DWRITE_ERR_BASE + code))") +cpp_quote("#define MAKE_DWRITE_HR_ERR(code) MAKE_DWRITE_HR(SEVERITY_ERROR, code)") diff --git a/sdk/include/psdk/dwrite_1.idl b/sdk/include/psdk/dwrite_1.idl new file mode 100644 index 00000000000..c00e922076f --- /dev/null +++ b/sdk/include/psdk/dwrite_1.idl @@ -0,0 +1,824 @@ +/* + * Copyright 2013 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dwrite.idl"; + +typedef enum DWRITE_PANOSE_FAMILY +{ + DWRITE_PANOSE_FAMILY_ANY, + DWRITE_PANOSE_FAMILY_NO_FIT, + DWRITE_PANOSE_FAMILY_TEXT_DISPLAY, + DWRITE_PANOSE_FAMILY_SCRIPT, + DWRITE_PANOSE_FAMILY_DECORATIVE, + DWRITE_PANOSE_FAMILY_SYMBOL, + DWRITE_PANOSE_FAMILY_PICTORIAL = DWRITE_PANOSE_FAMILY_SYMBOL +} DWRITE_PANOSE_FAMILY; + +typedef enum DWRITE_PANOSE_SERIF_STYLE +{ + DWRITE_PANOSE_SERIF_STYLE_ANY, + DWRITE_PANOSE_SERIF_STYLE_NO_FIT, + DWRITE_PANOSE_SERIF_STYLE_COVE, + DWRITE_PANOSE_SERIF_STYLE_OBTUSE_COVE, + DWRITE_PANOSE_SERIF_STYLE_SQUARE_COVE, + DWRITE_PANOSE_SERIF_STYLE_OBTUSE_SQUARE_COVE, + DWRITE_PANOSE_SERIF_STYLE_SQUARE, + DWRITE_PANOSE_SERIF_STYLE_THIN, + DWRITE_PANOSE_SERIF_STYLE_OVAL, + DWRITE_PANOSE_SERIF_STYLE_EXAGGERATED, + DWRITE_PANOSE_SERIF_STYLE_TRIANGLE, + DWRITE_PANOSE_SERIF_STYLE_NORMAL_SANS, + DWRITE_PANOSE_SERIF_STYLE_OBTUSE_SANS, + DWRITE_PANOSE_SERIF_STYLE_PERPENDICULAR_SANS, + DWRITE_PANOSE_SERIF_STYLE_FLARED, + DWRITE_PANOSE_SERIF_STYLE_ROUNDED, + DWRITE_PANOSE_SERIF_STYLE_SCRIPT, + DWRITE_PANOSE_SERIF_STYLE_PERP_SANS = DWRITE_PANOSE_SERIF_STYLE_PERPENDICULAR_SANS, + DWRITE_PANOSE_SERIF_STYLE_BONE = DWRITE_PANOSE_SERIF_STYLE_OVAL +} DWRITE_PANOSE_SERIF_STYLE; + +typedef enum DWRITE_PANOSE_WEIGHT +{ + DWRITE_PANOSE_WEIGHT_ANY, + DWRITE_PANOSE_WEIGHT_NO_FIT, + DWRITE_PANOSE_WEIGHT_VERY_LIGHT, + DWRITE_PANOSE_WEIGHT_LIGHT, + DWRITE_PANOSE_WEIGHT_THIN, + DWRITE_PANOSE_WEIGHT_BOOK, + DWRITE_PANOSE_WEIGHT_MEDIUM, + DWRITE_PANOSE_WEIGHT_DEMI, + DWRITE_PANOSE_WEIGHT_BOLD, + DWRITE_PANOSE_WEIGHT_HEAVY, + DWRITE_PANOSE_WEIGHT_BLACK, + DWRITE_PANOSE_WEIGHT_EXTRA_BLACK, + DWRITE_PANOSE_WEIGHT_NORD = DWRITE_PANOSE_WEIGHT_EXTRA_BLACK +} DWRITE_PANOSE_WEIGHT; + +typedef enum DWRITE_PANOSE_PROPORTION +{ + DWRITE_PANOSE_PROPORTION_ANY, + DWRITE_PANOSE_PROPORTION_NO_FIT, + DWRITE_PANOSE_PROPORTION_OLD_STYLE, + DWRITE_PANOSE_PROPORTION_MODERN, + DWRITE_PANOSE_PROPORTION_EVEN_WIDTH, + DWRITE_PANOSE_PROPORTION_EXPANDED, + DWRITE_PANOSE_PROPORTION_CONDENSED, + DWRITE_PANOSE_PROPORTION_VERY_EXPANDED, + DWRITE_PANOSE_PROPORTION_VERY_CONDENSED, + DWRITE_PANOSE_PROPORTION_MONOSPACED +} DWRITE_PANOSE_PROPORTION; + +typedef enum DWRITE_PANOSE_CONTRAST +{ + DWRITE_PANOSE_CONTRAST_ANY, + DWRITE_PANOSE_CONTRAST_NO_FIT, + DWRITE_PANOSE_CONTRAST_NONE, + DWRITE_PANOSE_CONTRAST_VERY_LOW, + DWRITE_PANOSE_CONTRAST_LOW, + DWRITE_PANOSE_CONTRAST_MEDIUM_LOW, + DWRITE_PANOSE_CONTRAST_MEDIUM, + DWRITE_PANOSE_CONTRAST_MEDIUM_HIGH, + DWRITE_PANOSE_CONTRAST_HIGH, + DWRITE_PANOSE_CONTRAST_VERY_HIGH, + DWRITE_PANOSE_CONTRAST_HORIZONTAL_LOW, + DWRITE_PANOSE_CONTRAST_HORIZONTAL_MEDIUM, + DWRITE_PANOSE_CONTRAST_HORIZONTAL_HIGH, + DWRITE_PANOSE_CONTRAST_BROKEN +} DWRITE_PANOSE_CONTRAST; + +typedef enum DWRITE_PANOSE_STROKE_VARIATION +{ + DWRITE_PANOSE_STROKE_VARIATION_ANY, + DWRITE_PANOSE_STROKE_VARIATION_NO_FIT, + DWRITE_PANOSE_STROKE_VARIATION_NO_VARIATION, + DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_DIAGONAL, + DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_TRANSITIONAL, + DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_VERTICAL, + DWRITE_PANOSE_STROKE_VARIATION_GRADUAL_HORIZONTAL, + DWRITE_PANOSE_STROKE_VARIATION_RAPID_VERTICAL, + DWRITE_PANOSE_STROKE_VARIATION_RAPID_HORIZONTAL, + DWRITE_PANOSE_STROKE_VARIATION_INSTANT_VERTICAL, + DWRITE_PANOSE_STROKE_VARIATION_INSTANT_HORIZONTAL +} DWRITE_PANOSE_STROKE_VARIANTION; + +typedef enum DWRITE_PANOSE_ARM_STYLE +{ + DWRITE_PANOSE_ARM_STYLE_ANY, + DWRITE_PANOSE_ARM_STYLE_NO_FIT, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_HORIZONTAL, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_WEDGE, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERTICAL, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_SINGLE_SERIF, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_DOUBLE_SERIF, + DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_HORIZONTAL, + DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_WEDGE, + DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_VERTICAL, + DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_SINGLE_SERIF, + DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_DOUBLE_SERIF, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_HORZ = DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_HORIZONTAL, + DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERT = DWRITE_PANOSE_ARM_STYLE_STRAIGHT_ARMS_VERTICAL, + DWRITE_PANOSE_ARM_STYLE_BENT_ARMS_HORZ = DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_HORIZONTAL, + DWRITE_PANOSE_ARM_STYLE_BENT_ARMS_WEDGE = DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_WEDGE, + DWRITE_PANOSE_ARM_STYLE_BENT_ARMS_VERT = DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_VERTICAL, + DWRITE_PANOSE_ARM_STYLE_BENT_ARMS_SINGLE_SERIF = DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_SINGLE_SERIF, + DWRITE_PANOSE_ARM_STYLE_BENT_ARMS_DOUBLE_SERIF = DWRITE_PANOSE_ARM_STYLE_NONSTRAIGHT_ARMS_DOUBLE_SERIF +} DWRITE_PANOSE_ARM_STYLE; + +typedef enum DWRITE_PANOSE_LETTERFORM +{ + DWRITE_PANOSE_LETTERFORM_ANY, + DWRITE_PANOSE_LETTERFORM_NO_FIT, + DWRITE_PANOSE_LETTERFORM_NORMAL_CONTACT, + DWRITE_PANOSE_LETTERFORM_NORMAL_WEIGHTED, + DWRITE_PANOSE_LETTERFORM_NORMAL_BOXED, + DWRITE_PANOSE_LETTERFORM_NORMAL_FLATTENED, + DWRITE_PANOSE_LETTERFORM_NORMAL_ROUNDED, + DWRITE_PANOSE_LETTERFORM_NORMAL_OFF_CENTER, + DWRITE_PANOSE_LETTERFORM_NORMAL_SQUARE, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_CONTACT, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_WEIGHTED, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_BOXED, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_FLATTENED, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_ROUNDED, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_OFF_CENTER, + DWRITE_PANOSE_LETTERFORM_OBLIQUE_SQUARE +} DWRITE_PANOSE_LETTERFORM; + +typedef enum DWRITE_PANOSE_MIDLINE +{ + DWRITE_PANOSE_MIDLINE_ANY, + DWRITE_PANOSE_MIDLINE_NO_FIT, + DWRITE_PANOSE_MIDLINE_STANDARD_TRIMMED, + DWRITE_PANOSE_MIDLINE_STANDARD_POINTED, + DWRITE_PANOSE_MIDLINE_STANDARD_SERIFED, + DWRITE_PANOSE_MIDLINE_HIGH_TRIMMED, + DWRITE_PANOSE_MIDLINE_HIGH_POINTED, + DWRITE_PANOSE_MIDLINE_HIGH_SERIFED, + DWRITE_PANOSE_MIDLINE_CONSTANT_TRIMMED, + DWRITE_PANOSE_MIDLINE_CONSTANT_POINTED, + DWRITE_PANOSE_MIDLINE_CONSTANT_SERIFED, + DWRITE_PANOSE_MIDLINE_LOW_TRIMMED, + DWRITE_PANOSE_MIDLINE_LOW_POINTED, + DWRITE_PANOSE_MIDLINE_LOW_SERIFED +} DWRITE_PANOSE_MIDLINE; + +typedef enum DWRITE_PANOSE_XHEIGHT +{ + DWRITE_PANOSE_XHEIGHT_ANY, + DWRITE_PANOSE_XHEIGHT_NO_FIT, + DWRITE_PANOSE_XHEIGHT_CONSTANT_SMALL, + DWRITE_PANOSE_XHEIGHT_CONSTANT_STANDARD, + DWRITE_PANOSE_XHEIGHT_CONSTANT_LARGE, + DWRITE_PANOSE_XHEIGHT_DUCKING_SMALL, + DWRITE_PANOSE_XHEIGHT_DUCKING_STANDARD, + DWRITE_PANOSE_XHEIGHT_DUCKING_LARGE, + DWRITE_PANOSE_XHEIGHT_CONSTANT_STD = DWRITE_PANOSE_XHEIGHT_CONSTANT_STANDARD, + DWRITE_PANOSE_XHEIGHT_DUCKING_STD = DWRITE_PANOSE_XHEIGHT_DUCKING_STANDARD +} DWRITE_PANOSE_XHEIGHT; + +typedef enum DWRITE_PANOSE_TOOL_KIND +{ + DWRITE_PANOSE_TOOL_KIND_ANY, + DWRITE_PANOSE_TOOL_KIND_NO_FIT, + DWRITE_PANOSE_TOOL_KIND_FLAT_NIB, + DWRITE_PANOSE_TOOL_KIND_PRESSURE_POINT, + DWRITE_PANOSE_TOOL_KIND_ENGRAVED, + DWRITE_PANOSE_TOOL_KIND_BALL, + DWRITE_PANOSE_TOOL_KIND_BRUSH, + DWRITE_PANOSE_TOOL_KIND_ROUGH, + DWRITE_PANOSE_TOOL_KIND_FELT_PEN_BRUSH_TIP, + DWRITE_PANOSE_TOOL_KIND_WILD_BRUSH +} DWRITE_PANOSE_TOOL_KIND; + +typedef enum DWRITE_PANOSE_SPACING +{ + DWRITE_PANOSE_SPACING_ANY, + DWRITE_PANOSE_SPACING_NO_FIT, + DWRITE_PANOSE_SPACING_PROPORTIONAL_SPACED, + DWRITE_PANOSE_SPACING_MONOSPACED +} DWRITE_PANOSE_SPACING; + +typedef enum DWRITE_PANOSE_ASPECT_RATIO +{ + DWRITE_PANOSE_ASPECT_RATIO_ANY, + DWRITE_PANOSE_ASPECT_RATIO_NO_FIT, + DWRITE_PANOSE_ASPECT_RATIO_VERY_CONDENSED, + DWRITE_PANOSE_ASPECT_RATIO_CONDENSED, + DWRITE_PANOSE_ASPECT_RATIO_NORMAL, + DWRITE_PANOSE_ASPECT_RATIO_EXPANDED, + DWRITE_PANOSE_ASPECT_RATIO_VERY_EXPANDED +} DWRITE_PANOSE_ASPECT_RATIO; + +typedef enum DWRITE_PANOSE_SCRIPT_TOPOLOGY +{ + DWRITE_PANOSE_SCRIPT_TOPOLOGY_ANY, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_NO_FIT, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_ROMAN_DISCONNECTED, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_ROMAN_TRAILING, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_ROMAN_CONNECTED, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_CURSIVE_DISCONNECTED, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_CURSIVE_TRAILING, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_CURSIVE_CONNECTED, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_BLACKLETTER_DISCONNECTED, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_BLACKLETTER_TRAILING, + DWRITE_PANOSE_SCRIPT_TOPOLOGY_BLACKLETTER_CONNECTED +} DWRITE_PANOSE_SCRIPT_TOPOLOGY; + +typedef enum DWRITE_PANOSE_SCRIPT_FORM +{ + DWRITE_PANOSE_SCRIPT_FORM_ANY, + DWRITE_PANOSE_SCRIPT_FORM_NO_FIT, + DWRITE_PANOSE_SCRIPT_FORM_UPRIGHT_NO_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_UPRIGHT_SOME_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_UPRIGHT_MORE_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_UPRIGHT_EXTREME_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_OBLIQUE_NO_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_OBLIQUE_SOME_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_OBLIQUE_MORE_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_OBLIQUE_EXTREME_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_EXAGGERATED_NO_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_EXAGGERATED_SOME_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_EXAGGERATED_MORE_WRAPPING, + DWRITE_PANOSE_SCRIPT_FORM_EXAGGERATED_EXTREME_WRAPPING +} DWRITE_PANOSE_SCRIPT_FORM; + +typedef enum DWRITE_PANOSE_FINIALS +{ + DWRITE_PANOSE_FINIALS_ANY, + DWRITE_PANOSE_FINIALS_NO_FIT, + DWRITE_PANOSE_FINIALS_NONE_NO_LOOPS, + DWRITE_PANOSE_FINIALS_NONE_CLOSED_LOOPS, + DWRITE_PANOSE_FINIALS_NONE_OPEN_LOOPS, + DWRITE_PANOSE_FINIALS_SHARP_NO_LOOPS, + DWRITE_PANOSE_FINIALS_SHARP_CLOSED_LOOPS, + DWRITE_PANOSE_FINIALS_SHARP_OPEN_LOOPS, + DWRITE_PANOSE_FINIALS_TAPERED_NO_LOOPS, + DWRITE_PANOSE_FINIALS_TAPERED_CLOSED_LOOPS, + DWRITE_PANOSE_FINIALS_TAPERED_OPEN_LOOPS, + DWRITE_PANOSE_FINIALS_ROUND_NO_LOOPS, + DWRITE_PANOSE_FINIALS_ROUND_CLOSED_LOOPS, + DWRITE_PANOSE_FINIALS_ROUND_OPEN_LOOPS +} DWRITE_PANOSE_FINIALS; + +typedef enum DWRITE_PANOSE_XASCENT +{ + DWRITE_PANOSE_XASCENT_ANY, + DWRITE_PANOSE_XASCENT_NO_FIT, + DWRITE_PANOSE_XASCENT_VERY_LOW, + DWRITE_PANOSE_XASCENT_LOW, + DWRITE_PANOSE_XASCENT_MEDIUM, + DWRITE_PANOSE_XASCENT_HIGH, + DWRITE_PANOSE_XASCENT_VERY_HIGH +} DWRITE_PANOSE_XASCENT; + +typedef enum DWRITE_PANOSE_DECORATIVE_CLASS +{ + DWRITE_PANOSE_DECORATIVE_CLASS_ANY, + DWRITE_PANOSE_DECORATIVE_CLASS_NO_FIT, + DWRITE_PANOSE_DECORATIVE_CLASS_DERIVATIVE, + DWRITE_PANOSE_DECORATIVE_CLASS_NONSTANDARD_TOPOLOGY, + DWRITE_PANOSE_DECORATIVE_CLASS_NONSTANDARD_ELEMENTS, + DWRITE_PANOSE_DECORATIVE_CLASS_NONSTANDARD_ASPECT, + DWRITE_PANOSE_DECORATIVE_CLASS_INITIALS, + DWRITE_PANOSE_DECORATIVE_CLASS_CARTOON, + DWRITE_PANOSE_DECORATIVE_CLASS_PICTURE_STEMS, + DWRITE_PANOSE_DECORATIVE_CLASS_ORNAMENTED, + DWRITE_PANOSE_DECORATIVE_CLASS_TEXT_AND_BACKGROUND, + DWRITE_PANOSE_DECORATIVE_CLASS_COLLAGE, + DWRITE_PANOSE_DECORATIVE_CLASS_MONTAGE +} DWRITE_PANOSE_DECORATIVE_CLASS; + +typedef enum DWRITE_PANOSE_ASPECT +{ + DWRITE_PANOSE_ASPECT_ANY, + DWRITE_PANOSE_ASPECT_NO_FIT, + DWRITE_PANOSE_ASPECT_SUPER_CONDENSED, + DWRITE_PANOSE_ASPECT_VERY_CONDENSED, + DWRITE_PANOSE_ASPECT_CONDENSED, + DWRITE_PANOSE_ASPECT_NORMAL, + DWRITE_PANOSE_ASPECT_EXTENDED, + DWRITE_PANOSE_ASPECT_VERY_EXTENDED, + DWRITE_PANOSE_ASPECT_SUPER_EXTENDED, + DWRITE_PANOSE_ASPECT_MONOSPACED +} DWRITE_PANOSE_ASPECT; + +typedef enum DWRITE_PANOSE_FILL +{ + DWRITE_PANOSE_FILL_ANY, + DWRITE_PANOSE_FILL_NO_FIT, + DWRITE_PANOSE_FILL_STANDARD_SOLID_FILL, + DWRITE_PANOSE_FILL_NO_FILL, + DWRITE_PANOSE_FILL_PATTERNED_FILL, + DWRITE_PANOSE_FILL_COMPLEX_FILL, + DWRITE_PANOSE_FILL_SHAPED_FILL, + DWRITE_PANOSE_FILL_DRAWN_DISTRESSED +} DWRITE_PANOSE_FILL; + +typedef enum DWRITE_PANOSE_LINING +{ + DWRITE_PANOSE_LINING_ANY, + DWRITE_PANOSE_LINING_NO_FIT, + DWRITE_PANOSE_LINING_NONE, + DWRITE_PANOSE_LINING_INLINE, + DWRITE_PANOSE_LINING_OUTLINE, + DWRITE_PANOSE_LINING_ENGRAVED, + DWRITE_PANOSE_LINING_SHADOW, + DWRITE_PANOSE_LINING_RELIEF, + DWRITE_PANOSE_LINING_BACKDROP +} DWRITE_PANOSE_LINING; + +typedef enum DWRITE_PANOSE_DECORATIVE_TOPOLOGY +{ + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_ANY, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_NO_FIT, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_STANDARD, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_SQUARE, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_MULTIPLE_SEGMENT, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_ART_DECO, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_UNEVEN_WEIGHTING, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_DIVERSE_ARMS, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_DIVERSE_FORMS, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_LOMBARDIC_FORMS, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_UPPER_CASE_IN_LOWER_CASE, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_IMPLIED_TOPOLOGY, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_HORSESHOE_E_AND_A, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_CURSIVE, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_BLACKLETTER, + DWRITE_PANOSE_DECORATIVE_TOPOLOGY_SWASH_VARIANCE +} DWRITE_PANOSE_DECORATIVE_TOPOLOGY; + +typedef enum DWRITE_PANOSE_CHARACTER_RANGES +{ + DWRITE_PANOSE_CHARACTER_RANGES_ANY, + DWRITE_PANOSE_CHARACTER_RANGES_NO_FIT, + DWRITE_PANOSE_CHARACTER_RANGES_EXTENDED_COLLECTION, + DWRITE_PANOSE_CHARACTER_RANGES_LITERALS, + DWRITE_PANOSE_CHARACTER_RANGES_NO_LOWER_CASE, + DWRITE_PANOSE_CHARACTER_RANGES_SMALL_CAPS +} DWRITE_PANOSE_CHARACTER_RANGES; + +typedef enum DWRITE_PANOSE_SYMBOL_KIND +{ + DWRITE_PANOSE_SYMBOL_KIND_ANY, + DWRITE_PANOSE_SYMBOL_KIND_NO_FIT, + DWRITE_PANOSE_SYMBOL_KIND_MONTAGES, + DWRITE_PANOSE_SYMBOL_KIND_PICTURES, + DWRITE_PANOSE_SYMBOL_KIND_SHAPES, + DWRITE_PANOSE_SYMBOL_KIND_SCIENTIFIC, + DWRITE_PANOSE_SYMBOL_KIND_MUSIC, + DWRITE_PANOSE_SYMBOL_KIND_EXPERT, + DWRITE_PANOSE_SYMBOL_KIND_PATTERNS, + DWRITE_PANOSE_SYMBOL_KIND_BOARDERS, + DWRITE_PANOSE_SYMBOL_KIND_ICONS, + DWRITE_PANOSE_SYMBOL_KIND_LOGOS, + DWRITE_PANOSE_SYMBOL_KIND_INDUSTRY_SPECIFIC +} DWRITE_PANOSE_SYMBOL_KIND; + +typedef enum DWRITE_PANOSE_SYMBOL_ASPECT_RATIO +{ + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_ANY, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_NO_FIT, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_NO_WIDTH, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_EXCEPTIONALLY_WIDE, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_SUPER_WIDE, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_VERY_WIDE, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_WIDE, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_NORMAL, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_NARROW, + DWRITE_PANOSE_SYMBOL_ASPECT_RATIO_VERY_NARROW +} DWRITE_PANOSE_SYMBOL_ASPECT_RATIO; + +typedef enum DWRITE_OUTLINE_THRESHOLD +{ + DWRITE_OUTLINE_THRESHOLD_ANTIALIASED, + DWRITE_OUTLINE_THRESHOLD_ALIASED +} DWRITE_OUTLINE_THRESHOLD; + +typedef enum DWRITE_BASELINE +{ + DWRITE_BASELINE_DEFAULT, + DWRITE_BASELINE_ROMAN, + DWRITE_BASELINE_CENTRAL, + DWRITE_BASELINE_MATH, + DWRITE_BASELINE_HANGING, + DWRITE_BASELINE_IDEOGRAPHIC_BOTTOM, + DWRITE_BASELINE_IDEOGRAPHIC_TOP, + DWRITE_BASELINE_MINIMUM, + DWRITE_BASELINE_MAXIMUM +} DWRITE_BASELINE; + +typedef enum DWRITE_VERTICAL_GLYPH_ORIENTATION +{ + DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT, + DWRITE_VERTICAL_GLYPH_ORIENTATION_STACKED +} DWRITE_VERTICAL_GLYPH_ORIENTATION; + +typedef enum DWRITE_GLYPH_ORIENTATION_ANGLE +{ + DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES, + DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES, + DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES, + DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES +} DWRITE_GLYPH_ORIENTATION_ANGLE; + +typedef struct DWRITE_FONT_METRICS1 +{ + UINT16 designUnitsPerEm; + UINT16 ascent; + UINT16 descent; + INT16 lineGap; + UINT16 capHeight; + UINT16 xHeight; + INT16 underlinePosition; + UINT16 underlineThickness; + INT16 strikethroughPosition; + UINT16 strikethroughThickness; + INT16 glyphBoxLeft; + INT16 glyphBoxTop; + INT16 glyphBoxRight; + INT16 glyphBoxBottom; + INT16 subscriptPositionX; + INT16 subscriptPositionY; + INT16 subscriptSizeX; + INT16 subscriptSizeY; + INT16 superscriptPositionX; + INT16 superscriptPositionY; + INT16 superscriptSizeX; + INT16 superscriptSizeY; + BOOL hasTypographicMetrics; +} DWRITE_FONT_METRICS1; + +typedef struct DWRITE_CARET_METRICS +{ + INT16 slopeRise; + INT16 slopeRun; + INT16 offset; +} DWRITE_CARET_METRICS; + +typedef union DWRITE_PANOSE +{ + UINT8 values[10]; + UINT8 familyKind; + struct + { + UINT8 familyKind; + UINT8 serifStyle; + UINT8 weight; + UINT8 proportion; + UINT8 contrast; + UINT8 strokeVariation; + UINT8 armStyle; + UINT8 letterform; + UINT8 midline; + UINT8 xHeight; + } text; + struct + { + UINT8 familyKind; + UINT8 toolKind; + UINT8 weight; + UINT8 spacing; + UINT8 aspectRatio; + UINT8 contrast; + UINT8 scriptTopology; + UINT8 scriptForm; + UINT8 finials; + UINT8 xAscent; + } script; + struct + { + UINT8 familyKind; + UINT8 decorativeClass; + UINT8 weight; + UINT8 aspect; + UINT8 contrast; + UINT8 serifVariant; + UINT8 fill; + UINT8 lining; + UINT8 decorativeTopology; + UINT8 characterRange; + } decorative; + struct + { + UINT8 familyKind; + UINT8 symbolKind; + UINT8 weight; + UINT8 spacing; + UINT8 aspectRatioAndContrast; + UINT8 aspectRatio94; + UINT8 aspectRatio119; + UINT8 aspectRatio157; + UINT8 aspectRatio163; + UINT8 aspectRatio211; + } symbol; +} DWRITE_PANOSE; + +typedef struct DWRITE_UNICODE_RANGE +{ + UINT32 first; + UINT32 last; +} DWRITE_UNICODE_RANGE; + +typedef struct DWRITE_SCRIPT_PROPERTIES +{ + UINT32 isoScriptCode; + UINT32 isoScriptNumber; + UINT32 clusterLookahead; + UINT32 justificationCharacter; + UINT32 restrictCaretToClusters : 1; + UINT32 usesWordDividers : 1; + UINT32 isDiscreteWriting : 1; + UINT32 isBlockWriting : 1; + UINT32 isDistributedWithinCluster : 1; + UINT32 isConnectedWriting : 1; + UINT32 isCursiveWriting : 1; + UINT32 reserved : 25; +} DWRITE_SCRIPT_PROPERTIES; + +typedef struct DWRITE_JUSTIFICATION_OPPORTUNITY +{ + FLOAT expansionMinimum; + FLOAT expansionMaximum; + FLOAT compressionMaximum; + UINT32 expansionPriority : 8; + UINT32 compressionPriority : 8; + UINT32 allowResidualExpansion : 1; + UINT32 allowResidualCompression : 1; + UINT32 applyToLeadingEdge : 1; + UINT32 applyToTrailingEdge : 1; + UINT32 reserved : 12; +} DWRITE_JUSTIFICATION_OPPORTUNITY; + +interface IDWriteTextAnalysisSource1; +interface IDWriteTextAnalysisSink1; +interface IDWriteRenderingParams1; + +[ +local, +object, +uuid(30572f99-dac6-41db-a16e-0486307e606a) +] +interface IDWriteFactory1 : IDWriteFactory +{ + HRESULT GetEudcFontCollection(IDWriteFontCollection **collection, + [defaultvalue(FALSE)] BOOL check_for_updates); + HRESULT CreateCustomRenderingParams(FLOAT gamma, + FLOAT enhcontrast, + FLOAT enhcontrast_grayscale, + FLOAT cleartype_level, + DWRITE_PIXEL_GEOMETRY geometry, + DWRITE_RENDERING_MODE mode, + IDWriteRenderingParams1** params); +} + +[ +local, +object, +uuid(a71efdb4-9fdb-4838-ad90-cfc3be8c3daf) +] +interface IDWriteFontFace1 : IDWriteFontFace +{ + void GetMetrics(DWRITE_FONT_METRICS1 *metrics); + HRESULT GetGdiCompatibleMetrics(FLOAT em_size, + FLOAT pixels_per_dip, + const DWRITE_MATRIX *transform, + DWRITE_FONT_METRICS1 *metrics); + void GetCaretMetrics(DWRITE_CARET_METRICS *metrics); + HRESULT GetUnicodeRanges(UINT32 max_count, + DWRITE_UNICODE_RANGE *ranges, + UINT32 *count); + BOOL IsMonospacedFont(); + HRESULT GetDesignGlyphAdvances(UINT32 glyph_count, + UINT16 const *indices, + INT32 *advances, + [defaultvalue(FALSE)] BOOL is_sideways); + HRESULT GetGdiCompatibleGlyphAdvances(FLOAT em_size, + FLOAT pixels_per_dip, + const DWRITE_MATRIX *transform, + BOOL use_gdi_natural, + BOOL is_sideways, + UINT32 glyph_count, + const UINT16 *indices, + INT32 *advances); + + HRESULT GetKerningPairAdjustments(UINT32 glyph_count, + const UINT16 *indices, + INT32 *adjustments); + BOOL HasKerningPairs(); + HRESULT GetRecommendedRenderingMode(FLOAT font_emsize, + FLOAT dpiX, + FLOAT dpiY, + const DWRITE_MATRIX *transform, + BOOL is_sideways, + DWRITE_OUTLINE_THRESHOLD threshold, + DWRITE_MEASURING_MODE measuring_mode, + DWRITE_RENDERING_MODE *rendering_mode); + + HRESULT GetVerticalGlyphVariants(UINT32 glyph_count, + const UINT16 *nominal_indices, + UINT16 *vertical_indices); + BOOL HasVerticalGlyphVariants(); +} + +[ +local, +object, +uuid(acd16696-8c14-4f5d-877e-fe3fc1d32738) +] +interface IDWriteFont1 : IDWriteFont +{ + void GetMetrics(DWRITE_FONT_METRICS1 *metrics); + void GetPanose(DWRITE_PANOSE *panose); + HRESULT GetUnicodeRanges(UINT32 max_count, + DWRITE_UNICODE_RANGE *ranges, + UINT32 *count); + BOOL IsMonospacedFont(); +} + +[ +local, +object, +uuid(94413cf4-a6fc-4248-8b50-6674348fcad3) +] +interface IDWriteRenderingParams1 : IDWriteRenderingParams +{ + FLOAT GetGrayscaleEnhancedContrast(); +} + +[ +local, +object, +uuid(80dad800-e21f-4e83-96ce-bfcce500db7c) +] +interface IDWriteTextAnalyzer1 : IDWriteTextAnalyzer +{ + HRESULT ApplyCharacterSpacing(FLOAT leading_spacing, + FLOAT trailing_spacing, + FLOAT min_advance_width, + UINT32 len, + UINT32 glyph_count, + UINT16 const *clustermap, + FLOAT const *advances, + DWRITE_GLYPH_OFFSET const *offsets, + DWRITE_SHAPING_GLYPH_PROPERTIES const *props, + FLOAT *modified_advances, + DWRITE_GLYPH_OFFSET *modified_offsets); + HRESULT GetBaseline(IDWriteFontFace *face, + DWRITE_BASELINE baseline, + BOOL vertical, + BOOL is_simulation_allowed, + DWRITE_SCRIPT_ANALYSIS sa, + const WCHAR *localeName, + INT32 *baseline_coord, + BOOL *exists); + + HRESULT AnalyzeVerticalGlyphOrientation( + IDWriteTextAnalysisSource1* source, + UINT32 text_pos, + UINT32 len, + IDWriteTextAnalysisSink1 *sink); + + HRESULT GetGlyphOrientationTransform( + DWRITE_GLYPH_ORIENTATION_ANGLE angle, + BOOL is_sideways, + DWRITE_MATRIX *transform); + + HRESULT GetScriptProperties(DWRITE_SCRIPT_ANALYSIS sa, DWRITE_SCRIPT_PROPERTIES *props); + + HRESULT GetTextComplexity(const WCHAR *text, + UINT32 len, + IDWriteFontFace *face, + BOOL *is_simple, + UINT32 *len_read, + UINT16 *indices); + HRESULT GetJustificationOpportunities( + IDWriteFontFace *face, + FLOAT font_em_size, + DWRITE_SCRIPT_ANALYSIS sa, + UINT32 length, + UINT32 glyph_count, + const WCHAR *text, + const UINT16 *clustermap, + const DWRITE_SHAPING_GLYPH_PROPERTIES *prop, + DWRITE_JUSTIFICATION_OPPORTUNITY *jo); + + HRESULT JustifyGlyphAdvances( + FLOAT width, + UINT32 glyph_count, + const DWRITE_JUSTIFICATION_OPPORTUNITY *jo, + const FLOAT *advances, + const DWRITE_GLYPH_OFFSET *offsets, + FLOAT *justifiedadvances, + DWRITE_GLYPH_OFFSET *justifiedoffsets); + + HRESULT GetJustifiedGlyphs( + IDWriteFontFace *face, + FLOAT font_em_size, + DWRITE_SCRIPT_ANALYSIS sa, + UINT32 length, + UINT32 glyph_count, + UINT32 max_glyphcount, + const UINT16 *clustermap, + const UINT16 *indices, + const FLOAT *advances, + const FLOAT *justifiedadvances, + const DWRITE_GLYPH_OFFSET *justifiedoffsets, + const DWRITE_SHAPING_GLYPH_PROPERTIES *prop, + UINT32 *actual_count, + UINT16 *modified_clustermap, + UINT16 *modified_indices, + FLOAT *modified_advances, + DWRITE_GLYPH_OFFSET *modified_offsets); +} + +[ +local, +object, +uuid(639cfad8-0fb4-4b21-a58a-067920120009) +] +interface IDWriteTextAnalysisSource1 : IDWriteTextAnalysisSource +{ + HRESULT GetVerticalGlyphOrientation( + UINT32 pos, + UINT32 *length, + DWRITE_VERTICAL_GLYPH_ORIENTATION *orientation, + UINT8 *bidi_level); +} + +[ +local, +object, +uuid(b0d941a0-85e7-4d8b-9fd3-5ced9934482a) +] +interface IDWriteTextAnalysisSink1 : IDWriteTextAnalysisSink +{ + HRESULT SetGlyphOrientation( + UINT32 pos, + UINT32 length, + DWRITE_GLYPH_ORIENTATION_ANGLE angle, + UINT8 adjusted_bidilevel, + BOOL is_sideways, + BOOL is_rtl); +} + +[ +local, +object, +uuid(9064d822-80a7-465c-a986-df65f78b8feb) +] +interface IDWriteTextLayout1 : IDWriteTextLayout +{ + HRESULT SetPairKerning( + BOOL is_pairkerning_enabled, + DWRITE_TEXT_RANGE range); + + HRESULT GetPairKerning( + UINT32 position, + BOOL *is_pairkerning_enabled, + DWRITE_TEXT_RANGE *range); + + HRESULT SetCharacterSpacing( + FLOAT leading_spacing, + FLOAT trailing_spacing, + FLOAT minimum_advance_width, + DWRITE_TEXT_RANGE range); + + HRESULT GetCharacterSpacing( + UINT32 position, + FLOAT* leading_spacing, + FLOAT* trailing_spacing, + FLOAT* minimum_advance_width, + [defaultvalue(NULL)] DWRITE_TEXT_RANGE *range); +} + +typedef enum DWRITE_TEXT_ANTIALIAS_MODE +{ + DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE, + DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE +} DWRITE_TEXT_ANTIALIAS_MODE; + +[ +local, +object, +uuid(791e8298-3ef3-4230-9880-c9bdecc42064) +] +interface IDWriteBitmapRenderTarget1 : IDWriteBitmapRenderTarget +{ + DWRITE_TEXT_ANTIALIAS_MODE GetTextAntialiasMode(); + HRESULT SetTextAntialiasMode(DWRITE_TEXT_ANTIALIAS_MODE mode); +} diff --git a/sdk/include/psdk/dwrite_2.idl b/sdk/include/psdk/dwrite_2.idl new file mode 100644 index 00000000000..5401cf35c5b --- /dev/null +++ b/sdk/include/psdk/dwrite_2.idl @@ -0,0 +1,332 @@ +/* + * Copyright 2014 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dwrite_1.idl"; + +typedef enum DWRITE_OPTICAL_ALIGNMENT +{ + DWRITE_OPTICAL_ALIGNMENT_NONE, + DWRITE_OPTICAL_ALIGNMENT_NO_SIDE_BEARINGS +} DWRITE_OPTICAL_ALIGNMENT; + +typedef enum DWRITE_GRID_FIT_MODE +{ + DWRITE_GRID_FIT_MODE_DEFAULT, + DWRITE_GRID_FIT_MODE_DISABLED, + DWRITE_GRID_FIT_MODE_ENABLED +} DWRITE_GRID_FIT_MODE; + +typedef struct DWRITE_TEXT_METRICS1 +{ + /* DWRITE_TEXT_METRICS fields */ + FLOAT left; + FLOAT top; + FLOAT width; + FLOAT widthIncludingTrailingWhitespace; + FLOAT height; + FLOAT layoutWidth; + FLOAT layoutHeight; + UINT32 maxBidiReorderingDepth; + UINT32 lineCount; + /* DWRITE_TEXT_METRICS1 fields */ + FLOAT heightIncludingTrailingWhitespace; +} DWRITE_TEXT_METRICS1; + +cpp_quote("#ifndef D3DCOLORVALUE_DEFINED") +typedef struct _D3DCOLORVALUE +{ + union { + FLOAT r; + FLOAT dvR; + }; + union { + FLOAT g; + FLOAT dvG; + }; + union { + FLOAT b; + FLOAT dvB; + }; + union { + FLOAT a; + FLOAT dvA; + }; +} D3DCOLORVALUE; +cpp_quote("#define D3DCOLORVALUE_DEFINED") +cpp_quote("#endif") + +typedef D3DCOLORVALUE DWRITE_COLOR_F; + +typedef struct DWRITE_COLOR_GLYPH_RUN +{ + DWRITE_GLYPH_RUN glyphRun; + DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription; + FLOAT baselineOriginX; + FLOAT baselineOriginY; + DWRITE_COLOR_F runColor; + UINT16 paletteIndex; +} DWRITE_COLOR_GLYPH_RUN; + +[ + local, + object, + uuid(d3e0e934-22a0-427e-aae4-7d9574b59db1) +] +interface IDWriteTextRenderer1 : IDWriteTextRenderer +{ + HRESULT DrawGlyphRun(void *context, + FLOAT originX, + FLOAT originY, + DWRITE_GLYPH_ORIENTATION_ANGLE angle, + DWRITE_MEASURING_MODE mode, + DWRITE_GLYPH_RUN const *run, + DWRITE_GLYPH_RUN_DESCRIPTION const *rundescr, + IUnknown *effect); + + HRESULT DrawUnderline(void *context, + FLOAT originX, + FLOAT originY, + DWRITE_GLYPH_ORIENTATION_ANGLE angle, + DWRITE_UNDERLINE const *underline, + IUnknown *effect); + + HRESULT DrawStrikethrough(void *context, + FLOAT originX, + FLOAT originY, + DWRITE_GLYPH_ORIENTATION_ANGLE angle, + DWRITE_STRIKETHROUGH const *strikethrough, + IUnknown *effect + ); + + HRESULT DrawInlineObject(void *context, + FLOAT originX, + FLOAT originY, + DWRITE_GLYPH_ORIENTATION_ANGLE angle, + IDWriteInlineObject *inlineObject, + BOOL is_sideways, + BOOL is_rtl, + IUnknown *effect + ); +} + +[ + local, + object, + uuid(efa008f9-f7a1-48bf-b05c-f224713cc0ff) +] +interface IDWriteFontFallback : IUnknown +{ + HRESULT MapCharacters(IDWriteTextAnalysisSource *source, + UINT32 position, + UINT32 length, + IDWriteFontCollection *basecollection, + const WCHAR *baseFamilyName, + DWRITE_FONT_WEIGHT baseWeight, + DWRITE_FONT_STYLE baseStyle, + DWRITE_FONT_STRETCH baseStretch, + UINT32 *mappedLength, + IDWriteFont **mappedFont, + FLOAT *scale + ); +} + +[ + local, + object, + uuid(5f174b49-0d8b-4cfb-8bca-f1cce9d06c67) +] +interface IDWriteTextFormat1 : IDWriteTextFormat +{ + HRESULT SetVerticalGlyphOrientation(DWRITE_VERTICAL_GLYPH_ORIENTATION orientation); + DWRITE_VERTICAL_GLYPH_ORIENTATION GetVerticalGlyphOrientation(); + HRESULT SetLastLineWrapping(BOOL lastline_wrapping_enabled); + BOOL GetLastLineWrapping(); + HRESULT SetOpticalAlignment(DWRITE_OPTICAL_ALIGNMENT alignment); + DWRITE_OPTICAL_ALIGNMENT GetOpticalAlignment(); + HRESULT SetFontFallback(IDWriteFontFallback *fallback); + HRESULT GetFontFallback(IDWriteFontFallback **fallback); +} + +[ + local, + object, + uuid(1093c18f-8d5e-43f0-b064-0917311b525e) +] +interface IDWriteTextLayout2 : IDWriteTextLayout1 +{ + HRESULT GetMetrics(DWRITE_TEXT_METRICS1 *metrics); + HRESULT SetVerticalGlyphOrientation(DWRITE_VERTICAL_GLYPH_ORIENTATION orientation); + DWRITE_VERTICAL_GLYPH_ORIENTATION GetVerticalGlyphOrientation(); + HRESULT SetLastLineWrapping(BOOL lastline_wrapping_enabled); + BOOL GetLastLineWrapping(); + HRESULT SetOpticalAlignment(DWRITE_OPTICAL_ALIGNMENT alignment); + DWRITE_OPTICAL_ALIGNMENT GetOpticalAlignment(); + HRESULT SetFontFallback(IDWriteFontFallback *fallback); + HRESULT GetFontFallback(IDWriteFontFallback **fallback); +} + +[ + local, + object, + uuid(553a9ff3-5693-4df7-b52b-74806f7f2eb9) +] +interface IDWriteTextAnalyzer2 : IDWriteTextAnalyzer1 +{ + HRESULT GetGlyphOrientationTransform(DWRITE_GLYPH_ORIENTATION_ANGLE angle, + BOOL is_sideways, + FLOAT originX, + FLOAT originY, + DWRITE_MATRIX *transform + ); + HRESULT GetTypographicFeatures(IDWriteFontFace *fontface, + DWRITE_SCRIPT_ANALYSIS analysis, + const WCHAR *localeName, + UINT32 max_tagcount, + UINT32 *actual_tagcount, + DWRITE_FONT_FEATURE_TAG *tags + ); + + HRESULT CheckTypographicFeature(IDWriteFontFace *fontface, + DWRITE_SCRIPT_ANALYSIS analysis, + const WCHAR *localeName, + DWRITE_FONT_FEATURE_TAG feature, + UINT32 glyph_count, + const UINT16 *indices, + UINT8 *feature_applies + ); +} + +[ + local, + object, + uuid(fd882d06-8aba-4fb8-b849-8be8b73e14de) +] +interface IDWriteFontFallbackBuilder : IUnknown +{ + HRESULT AddMapping(const DWRITE_UNICODE_RANGE *ranges, + UINT32 rangesCount, + WCHAR const **targetFamilyNames, + UINT32 targetFamilyNamesCount, + [defaultvalue(NULL)] IDWriteFontCollection *collection, + [defaultvalue(NULL)] WCHAR const *localeName, + [defaultvalue(NULL)] WCHAR const *baseFamilyName, + [defaultvalue(1)] FLOAT scale + ); + HRESULT AddMappings(IDWriteFontFallback *fallback); + HRESULT CreateFontFallback(IDWriteFontFallback **fallback); +} + +[ + local, + object, + uuid(29748ed6-8c9c-4a6a-be0b-d912e8538944) +] +interface IDWriteFont2 : IDWriteFont1 +{ + BOOL IsColorFont(); +} + +[ + local, + object, + uuid(d8b768ff-64bc-4e66-982b-ec8e87f693f7) +] +interface IDWriteFontFace2 : IDWriteFontFace1 +{ + BOOL IsColorFont(); + UINT32 GetColorPaletteCount(); + UINT32 GetPaletteEntryCount(); + HRESULT GetPaletteEntries(UINT32 palette_index, + UINT32 first_entry_index, + UINT32 entry_count, + DWRITE_COLOR_F *entries + ); + HRESULT GetRecommendedRenderingMode(FLOAT fontEmSize, + FLOAT dpiX, + FLOAT dpiY, + DWRITE_MATRIX const *transform, + BOOL is_sideways, + DWRITE_OUTLINE_THRESHOLD threshold, + DWRITE_MEASURING_MODE measuringmode, + IDWriteRenderingParams *params, + DWRITE_RENDERING_MODE *renderingmode, + DWRITE_GRID_FIT_MODE *gridfitmode + ); +} + +[ + local, + object, + uuid(d31fbe17-f157-41a2-8d24-cb779e0560e8) +] +interface IDWriteColorGlyphRunEnumerator : IUnknown +{ + HRESULT MoveNext(BOOL *hasRun); + HRESULT GetCurrentRun(DWRITE_COLOR_GLYPH_RUN const **run); +} + +[ + local, + object, + uuid(f9d711c3-9777-40ae-87e8-3e5aF9bf0948) +] +interface IDWriteRenderingParams2 : IDWriteRenderingParams1 +{ + DWRITE_GRID_FIT_MODE GetGridFitMode(); +} + +[ + local, + object, + uuid(0439fc60-ca44-4994-8dee-3a9af7b732ec) +] +interface IDWriteFactory2 : IDWriteFactory1 +{ + HRESULT GetSystemFontFallback(IDWriteFontFallback **fallback); + HRESULT CreateFontFallbackBuilder(IDWriteFontFallbackBuilder **fallbackbuilder); + HRESULT TranslateColorGlyphRun(FLOAT originX, + FLOAT originY, + const DWRITE_GLYPH_RUN *run, + const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, + DWRITE_MEASURING_MODE mode, + const DWRITE_MATRIX *transform, + UINT32 palette_index, + IDWriteColorGlyphRunEnumerator **colorlayers + ); + + HRESULT CreateCustomRenderingParams(FLOAT gamma, + FLOAT contrast, + FLOAT grayscalecontrast, + FLOAT cleartypeLevel, + DWRITE_PIXEL_GEOMETRY pixelGeometry, + DWRITE_RENDERING_MODE renderingMode, + DWRITE_GRID_FIT_MODE gridFitMode, + IDWriteRenderingParams2 **params + ); + + HRESULT CreateGlyphRunAnalysis(const DWRITE_GLYPH_RUN *run, + const DWRITE_MATRIX *transform, + DWRITE_RENDERING_MODE renderingMode, + DWRITE_MEASURING_MODE measuringMode, + DWRITE_GRID_FIT_MODE gridFitMode, + DWRITE_TEXT_ANTIALIAS_MODE antialiasMode, + FLOAT originX, + FLOAT originY, + IDWriteGlyphRunAnalysis **analysis + ); +} diff --git a/sdk/include/psdk/dwrite_3.idl b/sdk/include/psdk/dwrite_3.idl new file mode 100644 index 00000000000..f7cb97dff6f --- /dev/null +++ b/sdk/include/psdk/dwrite_3.idl @@ -0,0 +1,989 @@ +/* + * Copyright 2016 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dwrite_2.idl"; + +interface IDWriteFontFaceReference; +interface IDWriteFontFaceReference1; +interface IDWriteFontFace3; +interface IDWriteFontSet; +interface IDWriteFontDownloadQueue; +interface IDWriteFontFace5; +interface IDWriteFontList2; + +cpp_quote("#ifndef _WINGDI_") +/* already defined in wingdi.h but needed for WIDL */ +typedef struct FONTSIGNATURE FONTSIGNATURE; +cpp_quote("#endif /* _WINGDI_ */") + +typedef enum DWRITE_LOCALITY +{ + DWRITE_LOCALITY_REMOTE, + DWRITE_LOCALITY_PARTIAL, + DWRITE_LOCALITY_LOCAL +} DWRITE_LOCALITY; + +typedef enum DWRITE_RENDERING_MODE1 +{ + DWRITE_RENDERING_MODE1_DEFAULT, + DWRITE_RENDERING_MODE1_ALIASED, + DWRITE_RENDERING_MODE1_GDI_CLASSIC, + DWRITE_RENDERING_MODE1_GDI_NATURAL, + DWRITE_RENDERING_MODE1_NATURAL, + DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC, + DWRITE_RENDERING_MODE1_OUTLINE, + DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED +} DWRITE_RENDERING_MODE1; + +typedef enum DWRITE_FONT_PROPERTY_ID +{ + DWRITE_FONT_PROPERTY_ID_NONE, + DWRITE_FONT_PROPERTY_ID_FAMILY_NAME, + DWRITE_FONT_PROPERTY_ID_PREFERRED_FAMILY_NAME, + DWRITE_FONT_PROPERTY_ID_FACE_NAME, + DWRITE_FONT_PROPERTY_ID_FULL_NAME, + DWRITE_FONT_PROPERTY_ID_WIN32_FAMILY_NAME, + DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME, + DWRITE_FONT_PROPERTY_ID_DESIGN_SCRIPT_LANGUAGE_TAG, + DWRITE_FONT_PROPERTY_ID_SUPPORTED_SCRIPT_LANGUAGE_TAG, + DWRITE_FONT_PROPERTY_ID_SEMANTIC_TAG, + DWRITE_FONT_PROPERTY_ID_WEIGHT, + DWRITE_FONT_PROPERTY_ID_STRETCH, + DWRITE_FONT_PROPERTY_ID_STYLE, + DWRITE_FONT_PROPERTY_ID_TOTAL +} DWRITE_FONT_PROPERTY_ID; + +typedef struct DWRITE_FONT_PROPERTY +{ + DWRITE_FONT_PROPERTY_ID propertyId; + WCHAR const *propertyValue; + WCHAR const *localeName; +} DWRITE_FONT_PROPERTY; + +typedef enum DWRITE_FONT_AXIS_TAG +{ + DWRITE_FONT_AXIS_TAG_WEIGHT = 0x74686777, /* 'wght' */ + DWRITE_FONT_AXIS_TAG_WIDTH = 0x68746477, /* 'wdth' */ + DWRITE_FONT_AXIS_TAG_SLANT = 0x746e6c73, /* 'slnt' */ + DWRITE_FONT_AXIS_TAG_OPTICAL_SIZE = 0x7a73706f, /* 'opsz' */ + DWRITE_FONT_AXIS_TAG_ITALIC = 0x6c617469, /* 'ital' */ +} DWRITE_FONT_AXIS_TAG; + +typedef enum DWRITE_FONT_SOURCE_TYPE +{ + DWRITE_FONT_SOURCE_TYPE_UNKNOWN, + DWRITE_FONT_SOURCE_TYPE_PER_MACHINE, + DWRITE_FONT_SOURCE_TYPE_PER_USER, + DWRITE_FONT_SOURCE_TYPE_APPX_PACKAGE, + DWRITE_FONT_SOURCE_TYPE_REMOTE_FONT_PROVIDER +} DWRITE_FONT_SOURCE_TYPE; + +typedef struct DWRITE_FONT_AXIS_VALUE +{ + DWRITE_FONT_AXIS_TAG axisTag; + FLOAT value; +} DWRITE_FONT_AXIS_VALUE; + +typedef struct DWRITE_FONT_AXIS_RANGE +{ + DWRITE_FONT_AXIS_TAG axisTag; + FLOAT minValue; + FLOAT maxValue; +} DWRITE_FONT_AXIS_RANGE; + +typedef enum DWRITE_AUTOMATIC_FONT_AXES +{ + DWRITE_AUTOMATIC_FONT_AXES_NONE, + DWRITE_AUTOMATIC_FONT_AXES_OPTICAL_SIZE, +} DWRITE_AUTOMATIC_FONT_AXES; + +typedef enum DWRITE_FONT_AXIS_ATTRIBUTES +{ + DWRITE_FONT_AXIS_ATTRIBUTES_NONE, + DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE, + DWRITE_FONT_AXIS_ATTRIBUTES_HIDDEN, +} DWRITE_FONT_AXIS_ATTRIBUTES; + +typedef enum DWRITE_FONT_FAMILY_MODEL +{ + DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, + DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, +} DWRITE_FONT_FAMILY_MODEL; + +[ + local, + object, + uuid(b06fe5b9-43ec-4393-881b-dbe4dc72fda7) +] +interface IDWriteFontDownloadListener : IUnknown +{ + void DownloadCompleted(IDWriteFontDownloadQueue *queue, IUnknown *context, HRESULT result); +} + +[ + local, + object, + uuid(b71e6052-5aea-4fa3-832e-f60d431f7e91) +] +interface IDWriteFontDownloadQueue : IUnknown +{ + HRESULT AddListener(IDWriteFontDownloadListener *listener, UINT32 *token); + HRESULT RemoveListener(UINT32 token); + BOOL IsEmpty(); + HRESULT BeginDownload(IUnknown *context); + HRESULT CancelDownload(); + UINT64 GetGenerationCount(); +} + +[ + local, + object, + uuid(b7924baa-391b-412a-8c5c-e44cc2d867dc) +] +interface IDWriteRenderingParams3 : IDWriteRenderingParams2 +{ + DWRITE_RENDERING_MODE1 GetRenderingMode1(); +} + +[ + local, + object, + uuid(cfee3140-1257-47ca-8b85-31bfcf3f2d0e) +] +interface IDWriteStringList : IUnknown +{ + UINT32 GetCount(); + HRESULT GetLocaleNameLength(UINT32 index, UINT32 *length); + HRESULT GetLocaleName(UINT32 index, WCHAR *name, UINT32 size); + HRESULT GetStringLength(UINT32 index, UINT32 *length); + HRESULT GetString(UINT32 index, WCHAR *string, UINT32 size); +} + +[ + local, + object, + uuid(53585141-d9f8-4095-8321-d73cf6bd116b) +] +interface IDWriteFontSet : IUnknown +{ + UINT32 GetFontCount(); + HRESULT GetFontFaceReference(UINT32 index, IDWriteFontFaceReference **reference); + HRESULT FindFontFaceReference(IDWriteFontFaceReference *reference, + UINT32 *index, BOOL *exists); + HRESULT FindFontFace(IDWriteFontFace *fontface, UINT32 *index, BOOL *exists); + HRESULT GetPropertyValues__(DWRITE_FONT_PROPERTY_ID id, IDWriteStringList **values); + HRESULT GetPropertyValues_(DWRITE_FONT_PROPERTY_ID id, + WCHAR const *preferred_locales, IDWriteStringList **values); + HRESULT GetPropertyValues(UINT32 index, DWRITE_FONT_PROPERTY_ID id, BOOL *exists, + IDWriteLocalizedStrings **values); + HRESULT GetPropertyOccurrenceCount(DWRITE_FONT_PROPERTY const *property, UINT32 *count); + HRESULT GetMatchingFonts_(WCHAR const *family, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STRETCH stretch, + DWRITE_FONT_STYLE style, IDWriteFontSet **fontset); + HRESULT GetMatchingFonts(DWRITE_FONT_PROPERTY const *props, UINT32 count, IDWriteFontSet **fontset); +} + +[ + local, + object, + uuid(1f803a76-6871-48e8-987f-b975551c50f2) +] +interface IDWriteFontResource : IUnknown +{ + HRESULT GetFontFile(IDWriteFontFile **fontfile); + UINT32 GetFontFaceIndex(); + UINT32 GetFontAxisCount(); + HRESULT GetDefaultFontAxisValues( + DWRITE_FONT_AXIS_VALUE const *values, + UINT32 num_values); + HRESULT GetFontAxisRanges( + DWRITE_FONT_AXIS_RANGE const *ranges, + UINT32 num_ranges); + DWRITE_FONT_AXIS_ATTRIBUTES GetFontAxisAttributes( + UINT32 axis); + HRESULT GetAxisNames( + UINT32 axis, + IDWriteLocalizedStrings **names); + UINT32 GetAxisValueNameCount( + UINT32 axis); + HRESULT GetAxisValueNames( + UINT32 axis, + UINT32 axis_value, + DWRITE_FONT_AXIS_RANGE *axis_range, + IDWriteLocalizedStrings **names); + BOOL HasVariations(); + HRESULT CreateFontFace( + DWRITE_FONT_SIMULATIONS simulations, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + IDWriteFontFace5 **fontface); + HRESULT CreateFontFaceReference( + DWRITE_FONT_SIMULATIONS simulations, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + IDWriteFontFaceReference1 **reference); +} + +[ + local, + object, + uuid(7e9fda85-6c92-4053-bc47-7ae3530db4d3) +] +interface IDWriteFontSet1 : IDWriteFontSet +{ + HRESULT GetMatchingFonts( + DWRITE_FONT_PROPERTY const *property, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + IDWriteFontSet1 **fontset); + HRESULT GetFirstFontResources(IDWriteFontSet1 **fontset); + HRESULT GetFilteredFonts__( + UINT32 const *indices, + UINT32 num_indices, + IDWriteFontSet1 **fontset); + HRESULT GetFilteredFonts_( + DWRITE_FONT_AXIS_RANGE const *axis_ranges, + UINT32 num_ranges, + BOOL select_any_range, + IDWriteFontSet1 **fontset); + HRESULT GetFilteredFonts( + DWRITE_FONT_PROPERTY const *props, + UINT32 num_properties, + BOOL select_any_property, + IDWriteFontSet1 **fontset); + HRESULT GetFilteredFontIndices_( + DWRITE_FONT_AXIS_RANGE const *ranges, + UINT32 num_ranges, + BOOL select_any_range, + UINT32 *indices, + UINT32 num_indices, + UINT32 *actual_num_indices); + HRESULT GetFilteredFontIndices( + DWRITE_FONT_PROPERTY const *props, + UINT32 num_properties, + BOOL select_any_range, + UINT32 *indices, + UINT32 num_indices, + UINT32 *actual_num_indices); + HRESULT GetFontAxisRanges_( + UINT32 font_index, + DWRITE_FONT_AXIS_RANGE *axis_ranges, + UINT32 num_ranges, + UINT32 *actual_num_ranges); + HRESULT GetFontAxisRanges( + DWRITE_FONT_AXIS_RANGE *axis_ranges, + UINT32 num_ranges, + UINT32 *actual_num_ranges); + HRESULT GetFontFaceReference( + UINT32 index, + IDWriteFontFaceReference1 **reference); + HRESULT CreateFontResource( + UINT32 index, + IDWriteFontResource **resource); + HRESULT CreateFontFace( + UINT32 index, + IDWriteFontFace5 **fontface); + DWRITE_LOCALITY GetFontLocality(UINT32 index); +} + +[ + local, + object, + uuid(29748ed6-8c9c-4a6a-be0b-d912e8538944) +] +interface IDWriteFont3 : IDWriteFont2 +{ + HRESULT CreateFontFace(IDWriteFontFace3 **fontface); + BOOL Equals(IDWriteFont *font); + HRESULT GetFontFaceReference(IDWriteFontFaceReference **reference); + BOOL HasCharacter(UINT32 character); + DWRITE_LOCALITY GetLocality(); +} + +[ + local, + object, + uuid(da20d8ef-812a-4c43-9802-62ec4abd7adf) +] +interface IDWriteFontFamily1 : IDWriteFontFamily +{ + DWRITE_LOCALITY GetFontLocality(UINT32 index); + HRESULT GetFont(UINT32 index, IDWriteFont3 **font); + HRESULT GetFontFaceReference(UINT32 index, IDWriteFontFaceReference **reference); +} + +[ + local, + object, + uuid(3ed49e77-a398-4261-b9cf-c126c2131ef3) +] +interface IDWriteFontFamily2 : IDWriteFontFamily1 +{ + HRESULT GetMatchingFonts( + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + IDWriteFontList2 **fontlist); + HRESULT GetFontSet(IDWriteFontSet1 **fontset); +} + +[ + local, + object, + uuid(53585141-d9f8-4095-8321-d73cf6bd116c) +] +interface IDWriteFontCollection1 : IDWriteFontCollection +{ + HRESULT GetFontSet(IDWriteFontSet **fontset); + HRESULT GetFontFamily(UINT32 index, IDWriteFontFamily1 **family); +} + +[ + local, + object, + uuid(514039c6-4617-4064-bf8b-92ea83e506e0) +] +interface IDWriteFontCollection2 : IDWriteFontCollection1 +{ + HRESULT GetFontFamily( + UINT32 index, + IDWriteFontFamily2 **family); + HRESULT GetMatchingFonts( + const WCHAR *familyname, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + IDWriteFontList2 **fontlist); + DWRITE_FONT_FAMILY_MODEL GetFontFamilyModel(); + HRESULT GetFontSet(IDWriteFontSet1 **fontset); +} + +[ + local, + object, + uuid(a4d055a6-f9e3-4e25-93b7-9e309f3af8e9) +] +interface IDWriteFontCollection3 : IDWriteFontCollection2 +{ + HANDLE GetExpirationEvent(); +} + +[ + local, + object, + uuid(5e7fa7ca-dde3-424c-89f0-9fcd6fed58cd) +] +interface IDWriteFontFaceReference : IUnknown +{ + HRESULT CreateFontFace(IDWriteFontFace3 **fontface); + HRESULT CreateFontFaceWithSimulations(DWRITE_FONT_SIMULATIONS simulations, + IDWriteFontFace3 **fontface); + BOOL Equals(IDWriteFontFaceReference *reference); + UINT32 GetFontFaceIndex(); + DWRITE_FONT_SIMULATIONS GetSimulations(); + HRESULT GetFontFile(IDWriteFontFile **fontfile); + UINT64 GetLocalFileSize(); + UINT64 GetFileSize(); + HRESULT GetFileTime(FILETIME *writetime); + DWRITE_LOCALITY GetLocality(); + HRESULT EnqueueFontDownloadRequest(); + HRESULT EnqueueCharacterDownloadRequest(WCHAR const *chars, UINT32 count); + HRESULT EnqueueGlyphDownloadRequest(UINT16 const *glyphs, UINT32 count); + HRESULT EnqueueFileFragmentDownloadRequest(UINT64 offset, UINT64 size); +} + +[ + local, + object, + uuid(c081fe77-2fd1-41ac-a5a3-34983c4ba61a) +] +interface IDWriteFontFaceReference1 : IDWriteFontFaceReference +{ + HRESULT CreateFontFace(IDWriteFontFace5 **fontface); + UINT32 GetFontAxisValueCount(); + HRESULT GetFontAxisValues( + DWRITE_FONT_AXIS_VALUE *values, + UINT32 num_values); +} + +[ + local, + object, + uuid(da20d8ef-812a-4c43-9802-62ec4abd7ade) +] +interface IDWriteFontList1 : IDWriteFontList +{ + DWRITE_LOCALITY GetFontLocality(UINT32 index); + HRESULT GetFont(UINT32 index, IDWriteFont3 **font); + HRESULT GetFontFaceReference(UINT32 index, IDWriteFontFaceReference **reference); +} + +[ + local, + object, + uuid(c0763a34-77af-445a-b735-08c37b0a5bf5) +] +interface IDWriteFontList2 : IDWriteFontList1 +{ + HRESULT GetFontSet(IDWriteFontSet1 **fontset); +} + +[ + local, + object, + uuid(dc7ead19-e54c-43af-b2da-4e2b79ba3f7f) +] +interface IDWriteFontSet2 : IDWriteFontSet1 +{ + HANDLE GetExpirationEvent(); +} + +[ + local, + object, + uuid(7c073ef2-a7f4-4045-8c32-8ab8ae640f90) +] +interface IDWriteFontSet3 : IDWriteFontSet2 +{ + DWRITE_FONT_SOURCE_TYPE GetFontSourceType(UINT32 index); + UINT32 GetFontSourceNameLength(UINT32 index); + HRESULT GetFontSourceName(UINT32 index, WCHAR *buffer, UINT32 buffer_size); +} + +[ + local, + object, + uuid(d37d7598-09be-4222-a236-2081341cc1f2) +] +interface IDWriteFontFace3 : IDWriteFontFace2 +{ + HRESULT GetFontFaceReference(IDWriteFontFaceReference **reference); + void GetPanose(DWRITE_PANOSE *panose); + DWRITE_FONT_WEIGHT GetWeight(); + DWRITE_FONT_STRETCH GetStretch(); + DWRITE_FONT_STYLE GetStyle(); + HRESULT GetFamilyNames(IDWriteLocalizedStrings **names); + HRESULT GetFaceNames(IDWriteLocalizedStrings **names); + HRESULT GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_ID stringid, + IDWriteLocalizedStrings **strings, + BOOL *exists); + BOOL HasCharacter(UINT32 character); + HRESULT GetRecommendedRenderingMode( + FLOAT emsize, + FLOAT dpi_x, + FLOAT dpi_y, + DWRITE_MATRIX const *transform, + BOOL is_sideways, + DWRITE_OUTLINE_THRESHOLD threshold, + DWRITE_MEASURING_MODE measuring_mode, + IDWriteRenderingParams *params, + DWRITE_RENDERING_MODE1 *rendering_mode, + DWRITE_GRID_FIT_MODE *gridfit_mode); + BOOL IsCharacterLocal(UINT32 character); + BOOL IsGlyphLocal(UINT16 glyph); + HRESULT AreCharactersLocal(WCHAR const *characters, + UINT32 count, BOOL enqueue_if_not, BOOL *are_local); + HRESULT AreGlyphsLocal(UINT16 const *glyphs, UINT32 count, + BOOL enqueue_if_not, BOOL *are_local); +} + + +typedef struct DWRITE_LINE_METRICS1 +{ + UINT32 length; + UINT32 trailingWhitespaceLength; + UINT32 newlineLength; + FLOAT height; + FLOAT baseline; + BOOL isTrimmed; + FLOAT leadingBefore; + FLOAT leadingAfter; +} DWRITE_LINE_METRICS1; + +typedef enum DWRITE_FONT_LINE_GAP_USAGE +{ + DWRITE_FONT_LINE_GAP_USAGE_DEFAULT, + DWRITE_FONT_LINE_GAP_USAGE_DISABLED, + DWRITE_FONT_LINE_GAP_USAGE_ENABLED +} DWRITE_FONT_LINE_GAP_USAGE; + +typedef struct DWRITE_LINE_SPACING +{ + DWRITE_LINE_SPACING_METHOD method; + FLOAT height; + FLOAT baseline; + FLOAT leadingBefore; + DWRITE_FONT_LINE_GAP_USAGE fontLineGapUsage; +} DWRITE_LINE_SPACING; + +[ + local, + object, + uuid(f67e0edd-9e3d-4ecc-8c32-4183253dfe70) +] +interface IDWriteTextFormat2 : IDWriteTextFormat1 +{ + HRESULT SetLineSpacing(DWRITE_LINE_SPACING const *spacing); + HRESULT GetLineSpacing(DWRITE_LINE_SPACING *spacing); +} + +[ + local, + object, + uuid(6d3b5641-e550-430d-a85b-b7bf48a93427) +] +interface IDWriteTextFormat3 : IDWriteTextFormat2 +{ + HRESULT SetFontAxisValues( + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values); + UINT32 GetFontAxisValueCount(); + HRESULT GetFontAxisValues( + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values); + DWRITE_AUTOMATIC_FONT_AXES GetAutomaticFontAxes(); + HRESULT SetAutomaticFontAxes(DWRITE_AUTOMATIC_FONT_AXES axes); +} + +[ + local, + object, + uuid(07ddcd52-020e-4de8-ac33-6c953d83f92d) +] +interface IDWriteTextLayout3 : IDWriteTextLayout2 +{ + HRESULT InvalidateLayout(); + HRESULT SetLineSpacing(DWRITE_LINE_SPACING const *spacing); + HRESULT GetLineSpacing(DWRITE_LINE_SPACING *spacing); + HRESULT GetLineMetrics(DWRITE_LINE_METRICS1 *metrics, UINT32 max_count, UINT32 *count); +} + +[ + local, + object, + uuid(05a9bf42-223f-4441-b5fb-8263685f55e9) +] +interface IDWriteTextLayout4 : IDWriteTextLayout3 +{ + HRESULT SetFontAxisValues( + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + DWRITE_TEXT_RANGE range); + UINT32 GetFontAxisValueCount(UINT32 pos); + HRESULT GetFontAxisValues( + UINT32 pos, + DWRITE_FONT_AXIS_VALUE *values, + UINT32 num_values, + DWRITE_TEXT_RANGE *range); + DWRITE_AUTOMATIC_FONT_AXES GetAutomaticFontAxes(); + HRESULT SetAutomaticFontAxes(DWRITE_AUTOMATIC_FONT_AXES axes); +} + +[ + local, + object, + uuid(2397599d-dd0d-4681-bd6a-f4f31eaade77) +] +interface IDWriteFontFallback1 : IDWriteFontFallback +{ + HRESULT MapCharacters( + IDWriteTextAnalysisSource *source, + UINT32 pos, + UINT32 length, + IDWriteFontCollection *base_collection, + const WCHAR *familyname, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + UINT32 *mapped_length, + FLOAT *scale, + IDWriteFontFace5 **fontface); +} + +[ + local, + object, + uuid(4556be70-3abd-4f70-90be-421780a6f515) +] +interface IDWriteGdiInterop1 : IDWriteGdiInterop +{ + HRESULT CreateFontFromLOGFONT(LOGFONTW const *logfont, + IDWriteFontCollection *collection, + IDWriteFont **font); + + /* GetFontSignature() methods are listed in reversed order to make + resulting vtable order compatible. */ + HRESULT GetFontSignature_(IDWriteFontFace *fontface, FONTSIGNATURE *fontsig); + HRESULT GetFontSignature(IDWriteFont *font, FONTSIGNATURE *fontsig); + HRESULT GetMatchingFontsByLOGFONT(LOGFONTW const *logfont, + IDWriteFontSet *fontset, + IDWriteFontSet **subset); +} + +[ + local, + object, + uuid(2f642afe-9c68-4f40-b8be-457401afcb3d) +] +interface IDWriteFontSetBuilder : IUnknown +{ + HRESULT AddFontFaceReference_(IDWriteFontFaceReference *ref, + DWRITE_FONT_PROPERTY const *props, + UINT32 prop_count); + HRESULT AddFontFaceReference(IDWriteFontFaceReference *ref); + HRESULT AddFontSet(IDWriteFontSet *fontset); + HRESULT CreateFontSet(IDWriteFontSet **fontset); +} + +[ + local, + object, + uuid(3ff7715f-3cdc-4dc6-9b72-ec5621dccafd) +] +interface IDWriteFontSetBuilder1 : IDWriteFontSetBuilder +{ + HRESULT AddFontFile(IDWriteFontFile *file); +} + +[ + local, + object, + uuid(ee5ba612-b131-463c-8f4f-3189b9401e45) +] +interface IDWriteFontSetBuilder2 : IDWriteFontSetBuilder1 +{ + HRESULT AddFont( + IDWriteFontFile *fontfile, + UINT32 face_index, + DWRITE_FONT_SIMULATIONS simulations, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_values, + DWRITE_FONT_AXIS_RANGE const *axis_ranges, + UINT32 num_ranges, + DWRITE_FONT_PROPERTY const *props, + UINT32 num_properties); + HRESULT AddFontFile(const WCHAR *filepath); +} + +[ + local, + object, + uuid(9a1b41c3-d3bb-466a-87fc-fe67556a3b65) +] +interface IDWriteFactory3 : IDWriteFactory2 +{ + HRESULT CreateGlyphRunAnalysis( + DWRITE_GLYPH_RUN const *run, + DWRITE_MATRIX const *transform, + DWRITE_RENDERING_MODE1 rendering_mode, + DWRITE_MEASURING_MODE measuring_mode, + DWRITE_GRID_FIT_MODE gridfit_mode, + DWRITE_TEXT_ANTIALIAS_MODE antialias_mode, + FLOAT origin_x, + FLOAT origin_y, + IDWriteGlyphRunAnalysis **analysis); + + HRESULT CreateCustomRenderingParams( + FLOAT gamma, + FLOAT enhanced_contrast, + FLOAT grayscale_enhanced_contrast, + FLOAT cleartype_level, + DWRITE_PIXEL_GEOMETRY pixel_geometry, + DWRITE_RENDERING_MODE1 rendering_mode, + DWRITE_GRID_FIT_MODE gridfit_mode, + IDWriteRenderingParams3 **params); + + /* CreateFontFaceReference methods are listed in reversed order to make + resulting vtable order compatible. */ + HRESULT CreateFontFaceReference_( + IDWriteFontFile *file, + UINT32 index, + DWRITE_FONT_SIMULATIONS simulations, + IDWriteFontFaceReference **reference); + + HRESULT CreateFontFaceReference( + WCHAR const *path, + FILETIME const *writetime, + UINT32 index, + DWRITE_FONT_SIMULATIONS simulations, + IDWriteFontFaceReference **reference); + + HRESULT GetSystemFontSet(IDWriteFontSet **fontset); + HRESULT CreateFontSetBuilder(IDWriteFontSetBuilder **builder); + HRESULT CreateFontCollectionFromFontSet( + IDWriteFontSet *fontset, + IDWriteFontCollection1 **collection); + + HRESULT GetSystemFontCollection( + BOOL include_downloadable, + IDWriteFontCollection1 **collection, + BOOL check_for_updates); + + HRESULT GetFontDownloadQueue(IDWriteFontDownloadQueue **queue); +} + +typedef struct DWRITE_GLYPH_IMAGE_DATA +{ + void const *imageData; + UINT32 imageDataSize; + UINT32 uniqueDataId; + UINT32 pixelsPerEm; + D2D1_SIZE_U pixelSize; + D2D1_POINT_2L horizontalLeftOrigin; + D2D1_POINT_2L horizontalRightOrigin; + D2D1_POINT_2L verticalTopOrigin; + D2D1_POINT_2L verticalBottomOrigin; +} DWRITE_GLYPH_IMAGE_DATA; + +[ + local, + object, + uuid(27f2a904-4eb8-441d-9678-0563f53e3e2f) +] +interface IDWriteFontFace4 : IDWriteFontFace3 +{ + HRESULT GetGlyphImageFormats_( + UINT16 glyph, + UINT32 ppem_first, + UINT32 ppem_last, + DWRITE_GLYPH_IMAGE_FORMATS *formats); + DWRITE_GLYPH_IMAGE_FORMATS GetGlyphImageFormats(); + HRESULT GetGlyphImageData( + UINT16 glyph, + UINT32 ppem, + DWRITE_GLYPH_IMAGE_FORMATS format, + DWRITE_GLYPH_IMAGE_DATA *data, + void **context); + void ReleaseGlyphImageData(void *context); +} + +[ + local, + object, + uuid(98eff3a5-b667-479a-b145-e2fa5b9fdc29) +] +interface IDWriteFontFace5 : IDWriteFontFace4 +{ + UINT32 GetFontAxisValueCount(); + HRESULT GetFontAxisValues( + DWRITE_FONT_AXIS_VALUE *values, + UINT32 value_count); + BOOL HasVariations(); + HRESULT GetFontResource(IDWriteFontResource **resource); + BOOL Equals(IDWriteFontFace *fontface); +} + +typedef struct DWRITE_COLOR_GLYPH_RUN1 +{ + DWRITE_GLYPH_RUN glyphRun; + DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription; + FLOAT baselineOriginX; + FLOAT baselineOriginY; + DWRITE_COLOR_F runColor; + UINT16 paletteIndex; + DWRITE_GLYPH_IMAGE_FORMATS glyphImageFormat; + DWRITE_MEASURING_MODE measuringMode; +} DWRITE_COLOR_GLYPH_RUN1; + +[ + local, + object, + uuid(7c5f86da-c7a1-4f05-b8e1-55a179fe5a35) +] +interface IDWriteColorGlyphRunEnumerator1 : IDWriteColorGlyphRunEnumerator +{ + HRESULT GetCurrentRun( + DWRITE_COLOR_GLYPH_RUN1 const **run); +} + +[ + local, + object, + uuid(4b0b5bd3-0797-4549-8ac5-fe915cc53856) +] +interface IDWriteFactory4 : IDWriteFactory3 +{ + HRESULT TranslateColorGlyphRun( + D2D1_POINT_2F baseline_origin, + DWRITE_GLYPH_RUN const *run, + DWRITE_GLYPH_RUN_DESCRIPTION const *run_desc, + DWRITE_GLYPH_IMAGE_FORMATS desired_formats, + DWRITE_MEASURING_MODE measuring_mode, + DWRITE_MATRIX const *transform, + UINT32 palette, + IDWriteColorGlyphRunEnumerator1 **layers); + + HRESULT ComputeGlyphOrigins_( + DWRITE_GLYPH_RUN const *run, + D2D1_POINT_2F baseline_origin, + D2D1_POINT_2F *origins); + + HRESULT ComputeGlyphOrigins( + DWRITE_GLYPH_RUN const *run, + DWRITE_MEASURING_MODE measuring_mode, + D2D1_POINT_2F baseline_origin, + DWRITE_MATRIX const *transform, + D2D1_POINT_2F *origins); +} + +[ + local, + object, + uuid(ce25f8fd-863b-4d13-9651-c1f88dc73fe2) +] +interface IDWriteAsyncResult : IUnknown +{ + HANDLE GetWaitHandle(); + HRESULT GetResult(); +} + +typedef struct DWRITE_FILE_FRAGMENT +{ + UINT64 fileOffset; + UINT64 fragmentSize; +} DWRITE_FILE_FRAGMENT; + +[ + local, + object, + uuid(4db3757a-2c72-4ed9-b2b6-1ababe1aff9c) +] +interface IDWriteRemoteFontFileStream : IDWriteFontFileStream +{ + HRESULT GetLocalFileSize(UINT64 *size); + HRESULT GetFileFragmentLocality(UINT64 offset, UINT64 size, BOOL *is_local, UINT64 *partial_size); + DWRITE_LOCALITY GetLocality(); + HRESULT BeginDownload( + GUID const *operation_id, + DWRITE_FILE_FRAGMENT const *fragments, + UINT32 fragment_count, + IDWriteAsyncResult **async_result); +} + +typedef enum DWRITE_CONTAINER_TYPE +{ + DWRITE_CONTAINER_TYPE_UNKNOWN, + DWRITE_CONTAINER_TYPE_WOFF, + DWRITE_CONTAINER_TYPE_WOFF2, +} DWRITE_CONTAINER_TYPE; + +[ + local, + object, + uuid(68648c83-6ede-46c0-ab46-20083a887fde) +] +interface IDWriteRemoteFontFileLoader : IDWriteFontFileLoader +{ + HRESULT CreateRemoteStreamFromKey(void const *key, UINT32 key_size, IDWriteRemoteFontFileStream **stream); + HRESULT GetLocalityFromKey(void const *key, UINT32 key_size, DWRITE_LOCALITY *locality); + HRESULT CreateFontFileReferenceFromUrl( + IDWriteFactory *factory, + WCHAR const *base_url, + WCHAR const *file_url, + IDWriteFontFile **fontfile); +} + +[ + local, + object, + uuid(dc102f47-a12d-4b1c-822d-9e117e33043f) +] +interface IDWriteInMemoryFontFileLoader : IDWriteFontFileLoader +{ + HRESULT CreateInMemoryFontFileReference( + IDWriteFactory *factory, + void const *data, + UINT32 data_size, + IUnknown *owner, + IDWriteFontFile **fontfile); + UINT32 GetFileCount(); +} + +[ + local, + object, + uuid(958db99a-be2a-4f09-af7d-65189803d1d3) +] +interface IDWriteFactory5 : IDWriteFactory4 +{ + HRESULT CreateFontSetBuilder(IDWriteFontSetBuilder1 **fontset_builder); + HRESULT CreateInMemoryFontFileLoader(IDWriteFontFileLoader **loader); + HRESULT CreateHttpFontFileLoader( + WCHAR const *referrer_url, + WCHAR const *extra_headers, + IDWriteRemoteFontFileLoader **loader); + DWRITE_CONTAINER_TYPE AnalyzeContainerType(void const *data, UINT32 data_size); + HRESULT UnpackFontFile( + DWRITE_CONTAINER_TYPE container_type, + void const *data, + UINT32 data_size, + IDWriteFontFileStream **stream); +} + +[ + local, + object, + uuid(f3744d80-21f7-42eb-b35d-995bc72fc223) +] +interface IDWriteFactory6 : IDWriteFactory5 +{ + HRESULT CreateFontFaceReference( + IDWriteFontFile *file, + UINT32 face_index, + DWRITE_FONT_SIMULATIONS simulations, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_axis, + IDWriteFontFaceReference1 **face_ref); + HRESULT CreateFontResource( + IDWriteFontFile *file, + UINT32 face_index, + IDWriteFontResource **resource); + HRESULT GetSystemFontSet( + BOOL include_downloadable, + IDWriteFontSet1 **fontset); + HRESULT GetSystemFontCollection( + BOOL include_downloadable, + DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection2 **collection); + HRESULT CreateFontCollectionFromFontSet( + IDWriteFontSet *fontset, + DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection2 **collection); + HRESULT CreateFontSetBuilder( + IDWriteFontSetBuilder2 **builder); + HRESULT CreateTextFormat( + const WCHAR *familyname, + IDWriteFontCollection *collection, + DWRITE_FONT_AXIS_VALUE const *axis_values, + UINT32 num_axis, + FLOAT fontsize, + const WCHAR *localename, + IDWriteTextFormat3 **format); +} + +[ + local, + object, + uuid(35d0e0b3-9076-4d2e-a016-a91b568a06b4) +] +interface IDWriteFactory7 : IDWriteFactory6 +{ + HRESULT GetSystemFontSet( + BOOL include_downloadable, + IDWriteFontSet2 **fontset); + HRESULT GetSystemFontCollection( + BOOL include_downloadable, + DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection3 **collection); +} diff --git a/sdk/include/psdk/dxgi.idl b/sdk/include/psdk/dxgi.idl new file mode 100644 index 00000000000..b724770ab7b --- /dev/null +++ b/sdk/include/psdk/dxgi.idl @@ -0,0 +1,491 @@ +/* + * Copyright 2007 Andras Kovacs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgitype.idl"; + +const UINT _FACDXGI = 0x87a; + +cpp_quote("#define MAKE_DXGI_STATUS(x) MAKE_HRESULT(0, _FACDXGI, x)") +cpp_quote("#define MAKE_DXGI_HRESULT(x) MAKE_HRESULT(1, _FACDXGI, x)") + +cpp_quote("#if 0") +typedef HANDLE HMONITOR; +typedef struct _LUID { + DWORD LowPart; + LONG HighPart; +} LUID, *PLUID; +cpp_quote("#endif") + +typedef UINT DXGI_USAGE; +const DXGI_USAGE DXGI_USAGE_SHADER_INPUT = 0x10L; +const DXGI_USAGE DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x20L; +const DXGI_USAGE DXGI_USAGE_BACK_BUFFER = 0x40L; +const DXGI_USAGE DXGI_USAGE_SHARED = 0x80L; +const DXGI_USAGE DXGI_USAGE_READ_ONLY = 0x100L; +const DXGI_USAGE DXGI_USAGE_DISCARD_ON_PRESENT = 0x200L; +const DXGI_USAGE DXGI_USAGE_UNORDERED_ACCESS = 0x400L; + +const UINT DXGI_ENUM_MODES_INTERLACED = 1; +const UINT DXGI_ENUM_MODES_SCALING = 2; + +const UINT DXGI_RESOURCE_PRIORITY_MINIMUM = 0x28000000; +const UINT DXGI_RESOURCE_PRIORITY_LOW = 0x50000000; +const UINT DXGI_RESOURCE_PRIORITY_NORMAL = 0x78000000; +const UINT DXGI_RESOURCE_PRIORITY_HIGH = 0xa0000000; +const UINT DXGI_RESOURCE_PRIORITY_MAXIMUM = 0xc8000000; + +const UINT DXGI_MAP_READ = 0x1; +const UINT DXGI_MAP_WRITE = 0x2; +const UINT DXGI_MAP_DISCARD = 0x4; + +typedef enum DXGI_SWAP_EFFECT { + DXGI_SWAP_EFFECT_DISCARD = 0, + DXGI_SWAP_EFFECT_SEQUENTIAL = 1, + DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3, + DXGI_SWAP_EFFECT_FLIP_DISCARD = 4 +} DXGI_SWAP_EFFECT; + +typedef enum DXGI_RESIDENCY { + DXGI_RESIDENCY_FULLY_RESIDENT = 1, + DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2, + DXGI_RESIDENCY_EVICTED_TO_DISK = 3, +} DXGI_RESIDENCY; + +typedef struct DXGI_SURFACE_DESC { + UINT Width; + UINT Height; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; +} DXGI_SURFACE_DESC; + +typedef struct DXGI_MAPPED_RECT { + INT Pitch; + BYTE *pBits; +} DXGI_MAPPED_RECT; + +typedef struct DXGI_OUTPUT_DESC { + WCHAR DeviceName[32]; + RECT DesktopCoordinates; + BOOL AttachedToDesktop; + DXGI_MODE_ROTATION Rotation; + HMONITOR Monitor; +} DXGI_OUTPUT_DESC; + +typedef struct DXGI_FRAME_STATISTICS { + UINT PresentCount; + UINT PresentRefreshCount; + UINT SyncRefreshCount; + LARGE_INTEGER SyncQPCTime; + LARGE_INTEGER SyncGPUTime; +} DXGI_FRAME_STATISTICS; + +typedef struct DXGI_ADAPTER_DESC { + WCHAR Description[128]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; +} DXGI_ADAPTER_DESC; + +typedef enum DXGI_SWAP_CHAIN_FLAG +{ + DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 0x0001, + DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 0x0002, + DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 0x0004, + DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTEXT = 0x0008, + DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 0x0010, + DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 0x0020, + DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 0x0040, + DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 0x0080, + DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 0x0100, + DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 0x0200, + DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED = 0x0400, + DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING = 0x0800, + DXGI_SWAP_CHAIN_FLAG_RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 0x1000, +} DXGI_SWAP_CHAIN_FLAG; + +typedef struct DXGI_SWAP_CHAIN_DESC { + DXGI_MODE_DESC BufferDesc; + DXGI_SAMPLE_DESC SampleDesc; + DXGI_USAGE BufferUsage; + UINT BufferCount; + HWND OutputWindow; + BOOL Windowed; + DXGI_SWAP_EFFECT SwapEffect; + UINT Flags; +} DXGI_SWAP_CHAIN_DESC; + +typedef struct DXGI_SHARED_RESOURCE { + HANDLE Handle; +} DXGI_SHARED_RESOURCE; + +[ + object, + local, + uuid(aec22fb8-76f3-4639-9be0-28eb43a67a2e) +] +interface IDXGIObject : IUnknown +{ + HRESULT SetPrivateData( + [in] REFGUID guid, + [in] UINT data_size, + [in] const void *data + ); + HRESULT SetPrivateDataInterface( + [in] REFGUID guid, + [in] const IUnknown *object + ); + HRESULT GetPrivateData( + [in] REFGUID guid, + [in, out] UINT *data_size, + [out] void *data + ); + HRESULT GetParent( + [in] REFIID riid, + [out] void **parent + ); +} + +[ + object, + local, + uuid(3d3e0379-f9de-4d58-bb6c-18d62992f1a6) +] +interface IDXGIDeviceSubObject : IDXGIObject +{ + HRESULT GetDevice( + [in] REFIID riid, + [out] void **device + ); +} + +[ + object, + uuid(035f3ab4-482e-4e50-b41f-8a7f8bd8960b), + local, + pointer_default(unique) +] +interface IDXGIResource : IDXGIDeviceSubObject +{ + HRESULT GetSharedHandle([out] HANDLE *pSharedHandle); + HRESULT GetUsage([out] DXGI_USAGE *pUsage); + HRESULT SetEvictionPriority([in] UINT EvictionPriority); + HRESULT GetEvictionPriority([out, retval] UINT *pEvictionPriority); +} + +[ + object, + uuid(9d8e1289-d7b3-465f-8126-250e349af85d), + local, + pointer_default(unique) +] +interface IDXGIKeyedMutex : IDXGIDeviceSubObject +{ + HRESULT AcquireSync([in] UINT64 Key, [in] DWORD dwMilliseconds); + HRESULT ReleaseSync([in] UINT64 Key); +} + +[ + object, + local, + uuid(cafcb56c-6ac3-4889-bf47-9e23bbd260ec) +] +interface IDXGISurface : IDXGIDeviceSubObject +{ + HRESULT GetDesc( + [out] DXGI_SURFACE_DESC *desc + ); + HRESULT Map( + [out] DXGI_MAPPED_RECT *mapped_rect, + [in] UINT flags + ); + HRESULT Unmap( + ); +} + +[ + object, + local, + uuid(4ae63092-6327-4c1b-80ae-bfe12ea32b86) +] +interface IDXGISurface1 : IDXGISurface +{ + HRESULT GetDC( + [in] BOOL discard, + [out] HDC *hdc + ); + HRESULT ReleaseDC( + [in] RECT *dirty_rect + ); +} + +[ + object, + local, + uuid(ae02eedb-c735-4690-8d52-5a8dc20213aa) +] +interface IDXGIOutput : IDXGIObject +{ + HRESULT GetDesc( + [out] DXGI_OUTPUT_DESC *desc + ); + HRESULT GetDisplayModeList( + [in] DXGI_FORMAT format, + [in] UINT flags, + [in, out] UINT *mode_count, + [out] DXGI_MODE_DESC *desc + ); + HRESULT FindClosestMatchingMode( + [in] const DXGI_MODE_DESC *mode, + [out] DXGI_MODE_DESC *closest_match, + [in] IUnknown *device + ); + HRESULT WaitForVBlank( + ); + HRESULT TakeOwnership( + [in] IUnknown *device, + [in] BOOL exclusive + ); + void ReleaseOwnership( + ); + HRESULT GetGammaControlCapabilities( + [out] DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps + ); + HRESULT SetGammaControl( + [in] const DXGI_GAMMA_CONTROL *gamma_control + ); + HRESULT GetGammaControl( + [out] DXGI_GAMMA_CONTROL *gamma_control + ); + HRESULT SetDisplaySurface( + [in] IDXGISurface *surface + ); + HRESULT GetDisplaySurfaceData( + [in] IDXGISurface *surface + ); + HRESULT GetFrameStatistics( + [out] DXGI_FRAME_STATISTICS *stats + ); +} + +[ + object, + local, + uuid(2411e7e1-12ac-4ccf-bd14-9798e8534dc0) +] +interface IDXGIAdapter : IDXGIObject +{ + HRESULT EnumOutputs( + [in] UINT output_idx, + [in, out] IDXGIOutput **output + ); + HRESULT GetDesc( + [out] DXGI_ADAPTER_DESC *desc + ); + HRESULT CheckInterfaceSupport( + [in] REFGUID guid, + [out] LARGE_INTEGER *umd_version + ); +} + +cpp_quote("#define DXGI_MAX_SWAP_CHAIN_BUFFERS (16)") + +cpp_quote("#define DXGI_PRESENT_TEST __MSABI_LONG(0x00000001U)") +cpp_quote("#define DXGI_PRESENT_DO_NOT_SEQUENCE __MSABI_LONG(0x00000002U)") +cpp_quote("#define DXGI_PRESENT_RESTART __MSABI_LONG(0x00000004U)") +cpp_quote("#define DXGI_PRESENT_DO_NOT_WAIT __MSABI_LONG(0x00000008U)") +cpp_quote("#define DXGI_PRESENT_STEREO_PREFER_RIGHT __MSABI_LONG(0x00000010U)") +cpp_quote("#define DXGI_PRESENT_STEREO_TEMPORARY_MONO __MSABI_LONG(0x00000020U)") +cpp_quote("#define DXGI_PRESENT_RESTRICT_TO_OUTPUT __MSABI_LONG(0x00000040U)") +cpp_quote("#define DXGI_PRESENT_USE_DURATION __MSABI_LONG(0x00000100U)") +cpp_quote("#define DXGI_PRESENT_ALLOW_TEARING __MSABI_LONG(0x00000200U)") + +[ + object, + local, + uuid(310d36a0-d2e7-4c0a-aa04-6a9d23b8886a) +] +interface IDXGISwapChain : IDXGIDeviceSubObject +{ + HRESULT Present( + [in] UINT sync_interval, + [in] UINT flags + ); + HRESULT GetBuffer( + [in] UINT buffer_idx, + [in] REFIID riid, + [in, out] void **surface + ); + HRESULT SetFullscreenState( + [in] BOOL fullscreen, + [in] IDXGIOutput *target + ); + HRESULT GetFullscreenState( + [out] BOOL *fullscreen, + [out] IDXGIOutput **target + ); + HRESULT GetDesc( + [out] DXGI_SWAP_CHAIN_DESC *desc + ); + HRESULT ResizeBuffers( + [in] UINT buffer_count, + [in] UINT width, + [in] UINT height, + [in] DXGI_FORMAT format, + [in] UINT flags + ); + HRESULT ResizeTarget( + [in] const DXGI_MODE_DESC *target_mode_desc + ); + HRESULT GetContainingOutput( + [out] IDXGIOutput **output + ); + HRESULT GetFrameStatistics( + [out] DXGI_FRAME_STATISTICS *stats + ); + HRESULT GetLastPresentCount( + [out] UINT *last_present_count + ); +} + +cpp_quote("#define DXGI_MWA_NO_WINDOW_CHANGES 0x1") +cpp_quote("#define DXGI_MWA_NO_ALT_ENTER 0x2") +cpp_quote("#define DXGI_MWA_NO_PRINT_SCREEN 0x4") +cpp_quote("#define DXGI_MWA_VALID 0x7") + +[ + object, + local, + uuid(7b7166ec-21c7-44ae-b21a-c9ae321ae369) +] +interface IDXGIFactory : IDXGIObject +{ + HRESULT EnumAdapters( + [in] UINT adapter_idx, + [out] IDXGIAdapter **adapter + ); + HRESULT MakeWindowAssociation( + [in] HWND window, + [in] UINT flags + ); + HRESULT GetWindowAssociation( + [in] HWND *window + ); + HRESULT CreateSwapChain( + [in] IUnknown *device, + [in] DXGI_SWAP_CHAIN_DESC *desc, + [out] IDXGISwapChain **swapchain + ); + HRESULT CreateSoftwareAdapter( + [in] HMODULE swrast, + [out] IDXGIAdapter **adapter + ); +} + +[local] HRESULT __stdcall CreateDXGIFactory(REFIID riid, void **factory); +[local] HRESULT __stdcall CreateDXGIFactory1(REFIID riid, void **factory); + +[ + object, + local, + uuid(54ec77fa-1377-44e6-8c32-88fd5f44c84c) +] +interface IDXGIDevice : IDXGIObject +{ + HRESULT GetAdapter( + [out] IDXGIAdapter **adapter + ); + HRESULT CreateSurface( + [in] const DXGI_SURFACE_DESC *desc, + [in] UINT surface_count, + [in] DXGI_USAGE usage, + [in] const DXGI_SHARED_RESOURCE *shared_resource, + [out] IDXGISurface **surface + ); + HRESULT QueryResourceResidency( + [in] IUnknown *const *resources, + [out] DXGI_RESIDENCY *residency, + [in] UINT resource_count + ); + HRESULT SetGPUThreadPriority( + [in] INT priority + ); + HRESULT GetGPUThreadPriority( + [out] INT *priority + ); +} + +typedef enum DXGI_ADAPTER_FLAG { + DXGI_ADAPTER_FLAG_NONE = 0, + DXGI_ADAPTER_FLAG_REMOTE = 1, + DXGI_ADAPTER_FLAG_FORCE_DWORD = 0xFFFFFFFF +} DXGI_ADAPTER_FLAG; + +typedef struct DXGI_ADAPTER_DESC1 { + WCHAR Description[128]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; + UINT Flags; +} DXGI_ADAPTER_DESC1; + +[ + object, + uuid(29038f61-3839-4626-91fd-086879011a05), + local, + pointer_default(unique) +] +interface IDXGIAdapter1 : IDXGIAdapter +{ + HRESULT GetDesc1([out] DXGI_ADAPTER_DESC1 *pDesc); +} + +[ + object, + uuid(77db970f-6276-48ba-ba28-070143b4392c), + local, + pointer_default(unique) +] +interface IDXGIDevice1 : IDXGIDevice +{ + HRESULT SetMaximumFrameLatency([in] UINT MaxLatency); + HRESULT GetMaximumFrameLatency([out] UINT *pMaxLatency); +} + +[ + object, + uuid(770aae78-f26f-4dba-a829-253c83d1b387), + local, + pointer_default(unique) + ] +interface IDXGIFactory1 : IDXGIFactory +{ + HRESULT EnumAdapters1([in] UINT Adapter, [out] IDXGIAdapter1 **ppAdapter); + BOOL IsCurrent(); +} diff --git a/sdk/include/psdk/dxgi1_2.idl b/sdk/include/psdk/dxgi1_2.idl new file mode 100644 index 00000000000..eeabd031ed4 --- /dev/null +++ b/sdk/include/psdk/dxgi1_2.idl @@ -0,0 +1,422 @@ +/* + * Copyright 2014 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgi.idl"; + +const UINT DXGI_ENUM_MODES_STEREO = 0x4; +const UINT DXGI_ENUM_MODES_DISABLED_STEREO = 0x8; + +const DWORD DXGI_SHARED_RESOURCE_READ = 0x80000000; +const DWORD DXGI_SHARED_RESOURCE_WRITE = 0x00000001; + +typedef enum _DXGI_OFFER_RESOURCE_PRIORITY { + DXGI_OFFER_RESOURCE_PRIORITY_LOW = 1, + DXGI_OFFER_RESOURCE_PRIORITY_NORMAL, + DXGI_OFFER_RESOURCE_PRIORITY_HIGH +} DXGI_OFFER_RESOURCE_PRIORITY; + +typedef enum DXGI_ALPHA_MODE { + DXGI_ALPHA_MODE_UNSPECIFIED = 0, + DXGI_ALPHA_MODE_PREMULTIPLIED = 1, + DXGI_ALPHA_MODE_STRAIGHT = 2, + DXGI_ALPHA_MODE_IGNORE = 3, + DXGI_ALPHA_MODE_FORCE_DWORD = 0xffffffff +} DXGI_ALPHA_MODE; + +typedef struct DXGI_OUTDUPL_MOVE_RECT +{ + POINT SourcePoint; + RECT DestinationRect; +} DXGI_OUTDUPL_MOVE_RECT; + +typedef struct DXGI_OUTDUPL_DESC +{ + DXGI_MODE_DESC ModeDesc; + DXGI_MODE_ROTATION Rotation; + BOOL DesktopImageInSystemMemory; +} DXGI_OUTDUPL_DESC; + +typedef struct DXGI_OUTDUPL_POINTER_POSITION +{ + POINT Position; + BOOL Visible; +} DXGI_OUTDUPL_POINTER_POSITION; + +typedef enum DXGI_OUTDUPL_POINTER_SHAPE_TYPE +{ + DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME = 0x00000001, + DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR = 0x00000002, + DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR = 0x00000004 +} DXGI_OUTDUPL_POINTER_SHAPE_TYPE; + +typedef struct DXGI_OUTDUPL_POINTER_SHAPE_INFO +{ + UINT Type; + UINT Width; + UINT Height; + UINT Pitch; + POINT HotSpot; +} DXGI_OUTDUPL_POINTER_SHAPE_INFO; + +typedef struct DXGI_OUTDUPL_FRAME_INFO +{ + LARGE_INTEGER LastPresentTime; + LARGE_INTEGER LastMouseUpdateTime; + UINT AccumulatedFrames; + BOOL RectsCoalesced; + BOOL ProtectedContentMaskedOut; + DXGI_OUTDUPL_POINTER_POSITION PointerPosition; + UINT TotalMetadataBufferSize; + UINT PointerShapeBufferSize; +} DXGI_OUTDUPL_FRAME_INFO; + +typedef struct DXGI_MODE_DESC1 +{ + UINT Width; + UINT Height; + DXGI_RATIONAL RefreshRate; + DXGI_FORMAT Format; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; + BOOL Stereo; +} DXGI_MODE_DESC1; + +[ + object, + uuid(191cfac3-a341-470d-b26e-a864f428319c), + local, + pointer_default(unique) +] +interface IDXGIOutputDuplication : IDXGIObject +{ + void GetDesc( + [out] DXGI_OUTDUPL_DESC *desc + ); + + HRESULT AcquireNextFrame( + [in] UINT timeout_in_milliseconds, + [out] DXGI_OUTDUPL_FRAME_INFO *frame_info, + [out] IDXGIResource **desktop_resource + ); + + HRESULT GetFrameDirtyRects( + [in] UINT dirty_rects_buffer_size, + [out] RECT *dirty_rects_buffer, + [out] UINT *dirty_rects_buffer_size_required + ); + + HRESULT GetFrameMoveRects( + [in] UINT move_rects_buffer_size, + [out] DXGI_OUTDUPL_MOVE_RECT *move_rect_buffer, + [out] UINT *move_rects_buffer_size_required + ); + + HRESULT GetFramePointerShape( + [in] UINT pointer_shape_buffer_size, + [out] void *pointer_shape_buffer, + [out] UINT *pointer_shape_buffer_size_required, + [out] DXGI_OUTDUPL_POINTER_SHAPE_INFO *pointer_shape_info + ); + + HRESULT MapDesktopSurface( + [out] DXGI_MAPPED_RECT *locked_rect + ); + + HRESULT UnMapDesktopSurface(); + + HRESULT ReleaseFrame(); +} + +[ + object, + uuid(aba496dd-b617-4cb8-a866-bc44d7eb1fa2), + local, + pointer_default(unique) +] +interface IDXGISurface2 : IDXGISurface1 +{ + HRESULT GetResource( + [in] REFIID iid, + [out] void **parent_resource, + [out] UINT *subresource_idx + ); +} + +[ + object, + uuid(30961379-4609-4a41-998e-54fe567ee0c1), + local, + pointer_default(unique) +] +interface IDXGIResource1 : IDXGIResource +{ + HRESULT CreateSubresourceSurface( + UINT index, + [out] IDXGISurface2 **surface + ); + HRESULT CreateSharedHandle( + [in] const SECURITY_ATTRIBUTES *attributes, + [in] DWORD access, + [in] const WCHAR *name, + [out] HANDLE *handle + ); +} + +[ + object, + uuid(ea9dbf1a-c88e-4486-854a-98aa0138f30c), + local, + pointer_default(unique) +] +interface IDXGIDisplayControl : IUnknown +{ + BOOL IsStereoEnabled(); + void SetStereoEnabled(BOOL enabled); +} + +[ + object, + uuid(05008617-fbfd-4051-a790-144884b4f6a9), + local, + pointer_default(unique) +] +interface IDXGIDevice2 : IDXGIDevice1 +{ + HRESULT OfferResources( + [in] UINT NumResources, + [in, size_is(NumResources)] IDXGIResource *const *ppResources, + [in] DXGI_OFFER_RESOURCE_PRIORITY Priority); + + HRESULT ReclaimResources( + [in] UINT NumResources, + [in, size_is(NumResources)] IDXGIResource *const *ppResources, + [out, size_is(NumResources)] BOOL *pDiscarded); + + HRESULT EnqueueSetEvent( + [in] HANDLE hEvent); +} + +typedef enum DXGI_SCALING { + DXGI_SCALING_STRETCH = 0, + DXGI_SCALING_NONE = 1 +} DXGI_SCALING; + +typedef struct DXGI_SWAP_CHAIN_DESC1 { + UINT Width; + UINT Height; + DXGI_FORMAT Format; + BOOL Stereo; + DXGI_SAMPLE_DESC SampleDesc; + DXGI_USAGE BufferUsage; + UINT BufferCount; + DXGI_SCALING Scaling; + DXGI_SWAP_EFFECT SwapEffect; + DXGI_ALPHA_MODE AlphaMode; + UINT Flags; +} DXGI_SWAP_CHAIN_DESC1; + +typedef struct DXGI_SWAP_CHAIN_FULLSCREEN_DESC { + DXGI_RATIONAL RefreshRate; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; + BOOL Windowed; +} DXGI_SWAP_CHAIN_FULLSCREEN_DESC; + +typedef struct DXGI_PRESENT_PARAMETERS { + UINT DirtyRectsCount; + RECT *pDirtyRects; + RECT *pScrollRect; + POINT *pScrollOffset; +} DXGI_PRESENT_PARAMETERS; + +[ + object, + uuid(790a45f7-0d42-4876-983a-0a55cfe6f4aa), + local, + pointer_default(unique) +] +interface IDXGISwapChain1 : IDXGISwapChain +{ + HRESULT GetDesc1( + [out] DXGI_SWAP_CHAIN_DESC1 *pDesc); + + HRESULT GetFullscreenDesc( + [out] DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pDesc); + + HRESULT GetHwnd( + [out] HWND *pHwnd); + + HRESULT GetCoreWindow( + [in] REFIID refiid, + [out] void **ppUnk); + + HRESULT Present1( + [in] UINT SyncInterval, + [in] UINT PresentFlags, + [in] const DXGI_PRESENT_PARAMETERS *pPresentParameters); + + BOOL IsTemporaryMonoSupported(); + + HRESULT GetRestrictToOutput( + [out] IDXGIOutput **ppRestrictToOutput); + + HRESULT SetBackgroundColor( + [in] const DXGI_RGBA *pColor); + + HRESULT GetBackgroundColor( + [out] DXGI_RGBA *pColor); + + HRESULT SetRotation( + [in] DXGI_MODE_ROTATION Rotation); + + HRESULT GetRotation( + [out] DXGI_MODE_ROTATION *pRotation); +} + +[ + object, + uuid(50c83a1c-e072-4c48-87b0-3630fa36a6d0), + local, + pointer_default(unique) +] +interface IDXGIFactory2 : IDXGIFactory1 +{ + BOOL IsWindowedStereoEnabled(); + + HRESULT CreateSwapChainForHwnd( + [in] IUnknown *pDevice, + [in] HWND hWnd, + [in] const DXGI_SWAP_CHAIN_DESC1 *pDesc, + [in] const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + [in] IDXGIOutput *pRestrictToOutput, + [out] IDXGISwapChain1 **ppSwapChain); + + HRESULT CreateSwapChainForCoreWindow( + [in] IUnknown *pDevice, + [in] IUnknown *pWindow, + [in] const DXGI_SWAP_CHAIN_DESC1 *pDesc, + [in] IDXGIOutput *pRestrictToOutput, + [out] IDXGISwapChain1 **ppSwapChain); + + HRESULT GetSharedResourceAdapterLuid( + [in] HANDLE hResource, + [out] LUID *pLuid); + + HRESULT RegisterOcclusionStatusWindow( + [in] HWND WindowHandle, + [in] UINT wMsg, + [out] DWORD *pdwCookie); + + HRESULT RegisterStereoStatusEvent( + [in] HANDLE hEvent, + [out] DWORD *pdwCookie); + + void UnregisterStereoStatus( + [in] DWORD dwCookie); + + HRESULT RegisterStereoStatusWindow( + [in] HWND WindowHandle, + [in] UINT wMsg, + [out] DWORD *pdwCookie); + + HRESULT RegisterOcclusionStatusEvent( + [in] HANDLE hEvent, + [out] DWORD *pdwCookie); + + void UnregisterOcclusionStatus( + [in] DWORD dwCookie); + + HRESULT CreateSwapChainForComposition( + [in] IUnknown *pDevice, + [in] const DXGI_SWAP_CHAIN_DESC1 *pDesc, + [in] IDXGIOutput *pRestrictToOutput, + [out] IDXGISwapChain1 **ppSwapChain); +} + +typedef enum DXGI_GRAPHICS_PREEMPTION_GRANULARITY { + DXGI_GRAPHICS_PREEMPTION_DMA_BUFFER_BOUNDARY, + DXGI_GRAPHICS_PREEMPTION_PRIMITIVE_BOUNDARY, + DXGI_GRAPHICS_PREEMPTION_TRIANGLE_BOUNDARY, + DXGI_GRAPHICS_PREEMPTION_PIXEL_BOUNDARY, + DXGI_GRAPHICS_PREEMPTION_INSTRUCTION_BOUNDARY +} DXGI_GRAPHICS_PREEMPTION_GRANULARITY; + +typedef enum DXGI_COMPUTE_PREEMPTION_GRANULARITY { + DXGI_COMPUTE_PREEMPTION_DMA_BUFFER_BOUNDARY, + DXGI_COMPUTE_PREEMPTION_DISPATCH_BOUNDARY, + DXGI_COMPUTE_PREEMPTION_THREAD_GROUP_BOUNDARY, + DXGI_COMPUTE_PREEMPTION_THREAD_BOUNDARY, + DXGI_COMPUTE_PREEMPTION_INSTRUCTION_BOUNDARY +} DXGI_COMPUTE_PREEMPTION_GRANULARITY; + +typedef struct DXGI_ADAPTER_DESC2 { + WCHAR Description[128]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; + UINT Flags; + DXGI_GRAPHICS_PREEMPTION_GRANULARITY GraphicsPreemptionGranularity; + DXGI_COMPUTE_PREEMPTION_GRANULARITY ComputePreemptionGranularity; +} DXGI_ADAPTER_DESC2; + +[ + object, + uuid(0aa1ae0a-fa0e-4b84-8644-e05ff8e5acb5), + local, + pointer_default(unique) +] +interface IDXGIAdapter2 : IDXGIAdapter1 +{ + HRESULT GetDesc2([out] DXGI_ADAPTER_DESC2 *pDesc); +} + +[ + object, + uuid(00cddea8-939b-4b83-a340-a685226666cc), + local, + pointer_default(unique) +] +interface IDXGIOutput1 : IDXGIOutput +{ + HRESULT GetDisplayModeList1( + [in] DXGI_FORMAT enum_format, + [in] UINT flags, + [in, out] UINT *num_modes, + [out] DXGI_MODE_DESC1 *desc + ); + + HRESULT FindClosestMatchingMode1( + [in] const DXGI_MODE_DESC1 *mode_to_match, + [out] DXGI_MODE_DESC1 *closest_match, + [in] IUnknown *concerned_device + ); + + HRESULT GetDisplaySurfaceData1( + [in] IDXGIResource *destination + ); + + HRESULT DuplicateOutput( + [in] IUnknown *device, + [out] IDXGIOutputDuplication **output_duplication + ); +} diff --git a/sdk/include/psdk/dxgi1_3.idl b/sdk/include/psdk/dxgi1_3.idl new file mode 100644 index 00000000000..b43ca23b96e --- /dev/null +++ b/sdk/include/psdk/dxgi1_3.idl @@ -0,0 +1,231 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgi1_2.idl"; + +typedef struct DXGI_MATRIX_3X2_F +{ + float _11; + float _12; + float _21; + float _22; + float _31; + float _32; +} DXGI_MATRIX_3X2_F; + +typedef struct DXGI_DECODE_SWAP_CHAIN_DESC +{ + UINT Flags; +} DXGI_DECODE_SWAP_CHAIN_DESC; + +typedef enum DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS +{ + DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_NOMINAL_RANGE = 0x1, + DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_BT709 = 0x2, + DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_xvYCC = 0x4, +} DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS; + +typedef enum DXGI_FRAME_PRESENTATION_MODE +{ + DXGI_FRAME_PRESENTATION_MODE_COMPOSED = 0, + DXGI_FRAME_PRESENTATION_MODE_OVERLAY = 1, + DXGI_FRAME_PRESENTATION_MODE_NONE = 2, + DXGI_FRAME_PRESENTATION_MODE_COMPOSITION_FAILURE = 3, +} DXGI_FRAME_PRESENTATION_MODE; + +typedef struct DXGI_FRAME_STATISTICS_MEDIA +{ + UINT PresentCount; + UINT PresentRefreshCount; + UINT SyncRefreshCount; + LARGE_INTEGER SyncQPCTime; + LARGE_INTEGER SyncGPUTime; + DXGI_FRAME_PRESENTATION_MODE CompositionMode; + UINT ApprovedPresentDuration; +} DXGI_FRAME_STATISTICS_MEDIA; + +typedef enum DXGI_OVERLAY_SUPPORT_FLAG +{ + DXGI_OVERLAY_SUPPORT_FLAG_DIRECT = 0x1, + DXGI_OVERLAY_SUPPORT_FLAG_SCALING = 0x2, +} DXGI_OVERLAY_SUPPORT_FLAG; + +[ + object, + uuid(6007896c-3244-4afd-bf18-a6d3beda5023), + local, + pointer_default(unique) +] +interface IDXGIDevice3 : IDXGIDevice2 +{ + void Trim(); +} + +[ + object, + uuid(a8be2ac4-199f-4946-b331-79599fb98de7), + local, + pointer_default(unique) +] +interface IDXGISwapChain2 : IDXGISwapChain1 +{ + HRESULT SetSourceSize(UINT width, UINT height); + + HRESULT GetSourceSize( + [out] UINT *width, + [out] UINT *height + ); + + HRESULT SetMaximumFrameLatency(UINT max_latency); + + HRESULT GetMaximumFrameLatency( + [out] UINT *max_latency + ); + + HANDLE GetFrameLatencyWaitableObject(); + + HRESULT SetMatrixTransform(const DXGI_MATRIX_3X2_F *matrix); + + HRESULT GetMatrixTransform( + [out] DXGI_MATRIX_3X2_F *matrix + ); +} + +[ + object, + uuid(595e39d1-2724-4663-99b1-da969de28364), + local, + pointer_default(unique) +] +interface IDXGIOutput2 : IDXGIOutput1 +{ + BOOL SupportsOverlays(); +} + +[ + object, + uuid(25483823-cd46-4c7d-86ca-47aa95b837bd), + local, + pointer_default(unique) +] +interface IDXGIFactory3 : IDXGIFactory2 +{ + UINT GetCreationFlags(); +} + +[ + object, + uuid(2633066b-4514-4c7a-8fd8-12ea98059d18), + local, + pointer_default(unique) +] +interface IDXGIDecodeSwapChain : IUnknown +{ + HRESULT PresentBuffer(UINT buffer_to_present, UINT sync_interval, UINT flags); + + HRESULT SetSourceRect(const RECT *rect); + + HRESULT SetTargetRect(const RECT *rect); + + HRESULT SetDestSize(UINT width, UINT height); + + HRESULT GetSourceRect( + [out] RECT *rect + ); + + HRESULT GetTargetRect( + [out] RECT *rect + ); + + HRESULT GetDestSize( + [out] UINT *width, + [out] UINT *height + ); + + HRESULT SetColorSpace(DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS colorspace); + + DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS GetColorSpace(); +} + +[ + object, + uuid(41e7d1f2-a591-4f7b-a2e5-fa9c843e1c12), + local, + pointer_default(unique) +] +interface IDXGIFactoryMedia : IUnknown +{ + HRESULT CreateSwapChainForCompositionSurfaceHandle( + [in] IUnknown *device, + [in] HANDLE surface, + [in] const DXGI_SWAP_CHAIN_DESC1 *desc, + [in] IDXGIOutput *restrict_to_output, + [out] IDXGISwapChain1 **swapchain + ); + + HRESULT CreateDecodeSwapChainForCompositionSurfaceHandle( + [in] IUnknown *device, + [in] HANDLE surface, + [in] DXGI_DECODE_SWAP_CHAIN_DESC *desc, + [in] IDXGIResource *yuv_decode_buffers, + [in] IDXGIOutput *restrict_to_output, + [out] IDXGIDecodeSwapChain **swapchain + ); +} + +[ + object, + uuid(dd95b90b-f05f-4f6a-bd65-25bfb264bd84), + local, + pointer_default(unique) +] +interface IDXGISwapChainMedia : IUnknown +{ + HRESULT GetFrameStatisticsMedia( + [out] DXGI_FRAME_STATISTICS_MEDIA *stats + ); + + HRESULT SetPresentDuration(UINT duration); + + HRESULT CheckPresentDurationSupport( + UINT desired_present_duration, + [out] UINT *closest_smaller_present_duration, + [out] UINT *closest_larger_present_duration + ); +} + +[ + object, + uuid(8a6bb301-7e7e-41F4-a8e0-5b32f7f99b18), + local, + pointer_default(unique) +] +interface IDXGIOutput3 : IDXGIOutput2 +{ + HRESULT CheckOverlaySupport( + [in] DXGI_FORMAT enum_format, + [out] IUnknown *concerned_device, + [out] UINT *flags + ); +} + +const UINT DXGI_CREATE_FACTORY_DEBUG = 0x1; + +[local] HRESULT __stdcall CreateDXGIFactory2(UINT flags, REFIID iid, void **factory); + +[local] HRESULT __stdcall DXGIGetDebugInterface1(UINT flags, REFIID iid, void **debug); diff --git a/sdk/include/psdk/dxgi1_4.idl b/sdk/include/psdk/dxgi1_4.idl new file mode 100644 index 00000000000..0f63df202e8 --- /dev/null +++ b/sdk/include/psdk/dxgi1_4.idl @@ -0,0 +1,140 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgi1_3.idl"; + +typedef enum DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG +{ + DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT = 0x1, + DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_OVERLAY_PRESENT = 0x2, +} DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG; + +typedef enum DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG +{ + DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG_PRESENT = 0x1, +} DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG; + +typedef enum DXGI_MEMORY_SEGMENT_GROUP +{ + DXGI_MEMORY_SEGMENT_GROUP_LOCAL = 0x0, + DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL = 0x1, +} DXGI_MEMORY_SEGMENT_GROUP; + +typedef struct DXGI_QUERY_VIDEO_MEMORY_INFO +{ + UINT64 Budget; + UINT64 CurrentUsage; + UINT64 AvailableForReservation; + UINT64 CurrentReservation; +} DXGI_QUERY_VIDEO_MEMORY_INFO; + +[ + object, + uuid(94d99bdb-f1f8-4ab0-b236-7da0170edab1), + local, + pointer_default(unique) +] +interface IDXGISwapChain3 : IDXGISwapChain2 +{ + UINT GetCurrentBackBufferIndex(); + HRESULT CheckColorSpaceSupport( + [in] DXGI_COLOR_SPACE_TYPE colour_space, + [out] UINT *colour_space_support + ); + HRESULT SetColorSpace1( + [in] DXGI_COLOR_SPACE_TYPE colour_space + ); + HRESULT ResizeBuffers1( + [in] UINT buffer_count, + [in] UINT width, + [in] UINT height, + [in] DXGI_FORMAT format, + [in] UINT flags, + [in] const UINT *node_mask, + [in] IUnknown *const *present_queue + ); +} + +[ + object, + uuid(dc7dca35-2196-414d-9F53-617884032a60), + local, + pointer_default(unique) +] +interface IDXGIOutput4 : IDXGIOutput3 +{ + HRESULT CheckOverlayColorSpaceSupport( + [in] DXGI_FORMAT format, + [in] DXGI_COLOR_SPACE_TYPE colour_space, + [in] IUnknown *device, + [out] UINT *flags + ); +} + +[ + object, + uuid(1bc6ea02-ef36-464f-bf0c-21ca39e5168a), + local, + pointer_default(unique) +] +interface IDXGIFactory4 : IDXGIFactory3 +{ + HRESULT EnumAdapterByLuid( + [in] LUID luid, + [in] REFIID iid, + [out] void **adapter + ); + HRESULT EnumWarpAdapter( + [in] REFIID iid, + [out] void **adapter + ); +} + +[ + object, + uuid(645967a4-1392-4310-a798-8053ce3e93fd), + local, + pointer_default(unique) +] +interface IDXGIAdapter3 : IDXGIAdapter2 +{ + HRESULT RegisterHardwareContentProtectionTeardownStatusEvent( + [in] HANDLE event, + [out] DWORD *cookie + ); + void UnregisterHardwareContentProtectionTeardownStatus( + [in] DWORD cookie + ); + HRESULT QueryVideoMemoryInfo( + [in] UINT node_index, + [in] DXGI_MEMORY_SEGMENT_GROUP segment_group, + [out] DXGI_QUERY_VIDEO_MEMORY_INFO *memory_info + ); + HRESULT SetVideoMemoryReservation( + [in] UINT node_index, + [in] DXGI_MEMORY_SEGMENT_GROUP segment_group, + [in] UINT64 reservation + ); + HRESULT RegisterVideoMemoryBudgetChangeNotificationEvent( + [in] HANDLE event, + [out] DWORD *cookie + ); + void UnregisterVideoMemoryBudgetChangeNotification( + [in] DWORD cookie + ); +} diff --git a/sdk/include/psdk/dxgi1_5.idl b/sdk/include/psdk/dxgi1_5.idl new file mode 100644 index 00000000000..d88d1417f50 --- /dev/null +++ b/sdk/include/psdk/dxgi1_5.idl @@ -0,0 +1,127 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgi1_4.idl"; + +typedef enum DXGI_OUTDUPL_FLAG +{ + DXGI_OUTDUPL_COMPOSITED_UI_CAPTURE_ONLY = 0x1, +} DXGI_OUTDUPL_FLAG; + +typedef enum DXGI_HDR_METADATA_TYPE +{ + DXGI_HDR_METADATA_TYPE_NONE = 0x0, + DXGI_HDR_METADATA_TYPE_HDR10 = 0x1, +} DXGI_HDR_METADATA_TYPE; + +typedef enum _DXGI_OFFER_RESOURCE_FLAGS +{ + DXGI_OFFER_RESOURCE_FLAG_ALLOW_DECOMMIT = 0x1, +} DXGI_OFFER_RESOURCE_FLAGS; + +typedef enum _DXGI_RECLAIM_RESOURCE_RESULTS +{ + DXGI_RECLAIM_RESOURCE_RESULT_OK = 0x0, + DXGI_RECLAIM_RESOURCE_RESULT_DISCARDED = 0x1, + DXGI_RECLAIM_RESOURCE_RESULT_NOT_COMMITTED = 0x2, +} DXGI_RECLAIM_RESOURCE_RESULTS; + +typedef enum DXGI_FEATURE +{ + DXGI_FEATURE_PRESENT_ALLOW_TEARING = 0x0, +} DXGI_FEATURE; + +typedef struct DXGI_HDR_METADATA_HDR10 +{ + UINT16 RedPrimary[2]; + UINT16 GreenPrimary[2]; + UINT16 BluePrimary[2]; + UINT16 WhitePoint[2]; + UINT MaxMasteringLuminance; + UINT MinMasteringLuminance; + UINT16 MaxContentLightLevel; + UINT16 MaxFrameAverageLightLevel; +} DXGI_HDR_METADATA_HDR10; + +[ + object, + uuid(80a07424-ab52-42eb-833c-0c42fd282d98), + local, + pointer_default(unique) +] +interface IDXGIOutput5 : IDXGIOutput4 +{ + HRESULT DuplicateOutput1( + [in] IUnknown *device, + [in] UINT flags, + [in] UINT format_count, + [in] const DXGI_FORMAT *formats, + [out] IDXGIOutputDuplication **duplication + ); +} + +[ + object, + uuid(3d585d5a-bd4a-489e-b1f4-3dbcb6452ffb), + local, + pointer_default(unique) +] +interface IDXGISwapChain4 : IDXGISwapChain3 +{ + HRESULT SetHDRMetaData( + [in] DXGI_HDR_METADATA_TYPE type, + [in] UINT size, + [in] void *metadata + ); +} + +[ + object, + uuid(95b4f95f-d8da-4ca4-9ee6-3b76d5968a10), + local, + pointer_default(unique) +] +interface IDXGIDevice4 : IDXGIDevice3 +{ + HRESULT OfferResources1( + [in] UINT resource_count, + [in] IDXGIResource *const *resources, + [in] DXGI_OFFER_RESOURCE_PRIORITY priority, + [in] UINT flags + ); + HRESULT ReclaimResources1( + [in] UINT resource_count, + [in] IDXGIResource *const *resources, + [out] DXGI_RECLAIM_RESOURCE_RESULTS *results + ); +} + +[ + object, + uuid(7632e1f5-ee65-4dca-87fd-84cd75f8838d), + local, + pointer_default(unique) +] +interface IDXGIFactory5 : IDXGIFactory4 +{ + HRESULT CheckFeatureSupport( + DXGI_FEATURE feature, + [in, out] void *support_data, + UINT support_data_size + ); +} diff --git a/sdk/include/psdk/dxgi1_6.idl b/sdk/include/psdk/dxgi1_6.idl new file mode 100644 index 00000000000..9dcf9f26b46 --- /dev/null +++ b/sdk/include/psdk/dxgi1_6.idl @@ -0,0 +1,98 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgi1_5.idl"; + +typedef enum DXGI_ADAPTER_FLAG3 +{ + DXGI_ADAPTER_FLAG3_NONE = 0x0, + DXGI_ADAPTER_FLAG3_REMOTE = 0x1, + DXGI_ADAPTER_FLAG3_SOFTWARE = 0x2, + DXGI_ADAPTER_FLAG3_ACG_COMPATIBLE = 0x4, + DXGI_ADAPTER_FLAG3_FORCE_DWORD = 0xffffffff, +} DXGI_ADAPTER_FLAG3; + +typedef enum DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAGS +{ + DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_FULLSCREEN = 0x1, + DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_WINDOWED = 0x2, + DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_CURSOR_STRETCHED = 0x4, +} DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAGS; + +typedef struct DXGI_ADAPTER_DESC3 +{ + WCHAR Description[128]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; + DXGI_ADAPTER_FLAG3 Flags; + DXGI_GRAPHICS_PREEMPTION_GRANULARITY GraphicsPreemptionGranularity; + DXGI_COMPUTE_PREEMPTION_GRANULARITY ComputePreemptionGranularity; +} DXGI_ADAPTER_DESC3; + +typedef struct DXGI_OUTPUT_DESC1 +{ + WCHAR DeviceName[32]; + RECT DesktopCoordinates; + BOOL AttachedToDesktop; + DXGI_MODE_ROTATION Rotation; + HMONITOR Monitor; + UINT BitsPerColor; + DXGI_COLOR_SPACE_TYPE ColorSpace; + FLOAT RedPrimary[2]; + FLOAT GreenPrimary[2]; + FLOAT BluePrimary[2]; + FLOAT WhitePoint[2]; + FLOAT MinLuminance; + FLOAT MaxLuminance; + FLOAT MaxFullFrameLuminance; +} DXGI_OUTPUT_DESC1; + +[ + object, + uuid(3c8d99d1-4fbf-4181-a82c-af66bf7bd24e), + local, + pointer_default(unique) +] +interface IDXGIAdapter4 : IDXGIAdapter3 +{ + HRESULT GetDesc3( + [out] DXGI_ADAPTER_DESC3 *desc + ); +} + +[ + object, + uuid(068346e8-aaec-4b84-add7-137f513f77a1), + local, + pointer_default(unique) +] +interface IDXGIOutput6 : IDXGIOutput5 +{ + HRESULT GetDesc1( + [out] DXGI_OUTPUT_DESC1 *desc + ); + HRESULT CheckHardwareCompositionSupport( + [out] UINT *flags + ); +} diff --git a/sdk/include/psdk/dxgicommon.idl b/sdk/include/psdk/dxgicommon.idl new file mode 100644 index 00000000000..99ace03c37d --- /dev/null +++ b/sdk/include/psdk/dxgicommon.idl @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Ihsan Akmal + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +cpp_quote("#if 0") +typedef unsigned int UINT; +cpp_quote("#endif") + +const UINT DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN = 0xffffffff; +const UINT DXGI_CENTER_MULTISAMPLE_QUALITY_PATTERN = 0xfffffffe; + +typedef enum DXGI_COLOR_SPACE_TYPE +{ + DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0x00, + DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 0x01, + DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 0x02, + DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 0x03, + DXGI_COLOR_SPACE_RESERVED = 0x04, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 0x05, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 0x06, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 0x07, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 0x08, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 0x09, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 0x0a, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 0x0b, + DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 0x0c, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 = 0x0d, + DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 = 0x0e, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020 = 0x0f, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 0x10, + DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 = 0x11, + DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 0x12, + DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 = 0x13, + DXGI_COLOR_SPACE_CUSTOM = 0xffffffff, +} DXGI_COLOR_SPACE_TYPE; + +typedef struct DXGI_SAMPLE_DESC +{ + UINT Count; + UINT Quality; +} DXGI_SAMPLE_DESC; + +typedef struct DXGI_RATIONAL +{ + UINT Numerator; + UINT Denominator; +} DXGI_RATIONAL; diff --git a/sdk/include/psdk/dxgiformat.idl b/sdk/include/psdk/dxgiformat.idl new file mode 100644 index 00000000000..5f85064d0dd --- /dev/null +++ b/sdk/include/psdk/dxgiformat.idl @@ -0,0 +1,145 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +const unsigned int DXGI_FORMAT_DEFINED = 1; + +typedef enum DXGI_FORMAT +{ + DXGI_FORMAT_UNKNOWN = 0x00, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 0x01, + DXGI_FORMAT_R32G32B32A32_FLOAT = 0x02, + DXGI_FORMAT_R32G32B32A32_UINT = 0x03, + DXGI_FORMAT_R32G32B32A32_SINT = 0x04, + DXGI_FORMAT_R32G32B32_TYPELESS = 0x05, + DXGI_FORMAT_R32G32B32_FLOAT = 0x06, + DXGI_FORMAT_R32G32B32_UINT = 0x07, + DXGI_FORMAT_R32G32B32_SINT = 0x08, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 0x09, + DXGI_FORMAT_R16G16B16A16_FLOAT = 0x0a, + DXGI_FORMAT_R16G16B16A16_UNORM = 0x0b, + DXGI_FORMAT_R16G16B16A16_UINT = 0x0c, + DXGI_FORMAT_R16G16B16A16_SNORM = 0x0d, + DXGI_FORMAT_R16G16B16A16_SINT = 0x0e, + DXGI_FORMAT_R32G32_TYPELESS = 0x0f, + DXGI_FORMAT_R32G32_FLOAT = 0x10, + DXGI_FORMAT_R32G32_UINT = 0x11, + DXGI_FORMAT_R32G32_SINT = 0x12, + DXGI_FORMAT_R32G8X24_TYPELESS = 0x13, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 0x14, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 0x15, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 0x16, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 0x17, + DXGI_FORMAT_R10G10B10A2_UNORM = 0x18, + DXGI_FORMAT_R10G10B10A2_UINT = 0x19, + DXGI_FORMAT_R11G11B10_FLOAT = 0x1a, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 0x1b, + DXGI_FORMAT_R8G8B8A8_UNORM = 0x1c, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 0x1d, + DXGI_FORMAT_R8G8B8A8_UINT = 0x1e, + DXGI_FORMAT_R8G8B8A8_SNORM = 0x1f, + DXGI_FORMAT_R8G8B8A8_SINT = 0x20, + DXGI_FORMAT_R16G16_TYPELESS = 0x21, + DXGI_FORMAT_R16G16_FLOAT = 0x22, + DXGI_FORMAT_R16G16_UNORM = 0x23, + DXGI_FORMAT_R16G16_UINT = 0x24, + DXGI_FORMAT_R16G16_SNORM = 0x25, + DXGI_FORMAT_R16G16_SINT = 0x26, + DXGI_FORMAT_R32_TYPELESS = 0x27, + DXGI_FORMAT_D32_FLOAT = 0x28, + DXGI_FORMAT_R32_FLOAT = 0x29, + DXGI_FORMAT_R32_UINT = 0x2a, + DXGI_FORMAT_R32_SINT = 0x2b, + DXGI_FORMAT_R24G8_TYPELESS = 0x2c, + DXGI_FORMAT_D24_UNORM_S8_UINT = 0x2d, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 0x2e, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 0x2f, + DXGI_FORMAT_R8G8_TYPELESS = 0x30, + DXGI_FORMAT_R8G8_UNORM = 0x31, + DXGI_FORMAT_R8G8_UINT = 0x32, + DXGI_FORMAT_R8G8_SNORM = 0x33, + DXGI_FORMAT_R8G8_SINT = 0x34, + DXGI_FORMAT_R16_TYPELESS = 0x35, + DXGI_FORMAT_R16_FLOAT = 0x36, + DXGI_FORMAT_D16_UNORM = 0x37, + DXGI_FORMAT_R16_UNORM = 0x38, + DXGI_FORMAT_R16_UINT = 0x39, + DXGI_FORMAT_R16_SNORM = 0x3a, + DXGI_FORMAT_R16_SINT = 0x3b, + DXGI_FORMAT_R8_TYPELESS = 0x3c, + DXGI_FORMAT_R8_UNORM = 0x3d, + DXGI_FORMAT_R8_UINT = 0x3e, + DXGI_FORMAT_R8_SNORM = 0x3f, + DXGI_FORMAT_R8_SINT = 0x40, + DXGI_FORMAT_A8_UNORM = 0x41, + DXGI_FORMAT_R1_UNORM = 0x42, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 0x43, + DXGI_FORMAT_R8G8_B8G8_UNORM = 0x44, + DXGI_FORMAT_G8R8_G8B8_UNORM = 0x45, + DXGI_FORMAT_BC1_TYPELESS = 0x46, + DXGI_FORMAT_BC1_UNORM = 0x47, + DXGI_FORMAT_BC1_UNORM_SRGB = 0x48, + DXGI_FORMAT_BC2_TYPELESS = 0x49, + DXGI_FORMAT_BC2_UNORM = 0x4a, + DXGI_FORMAT_BC2_UNORM_SRGB = 0x4b, + DXGI_FORMAT_BC3_TYPELESS = 0x4c, + DXGI_FORMAT_BC3_UNORM = 0x4d, + DXGI_FORMAT_BC3_UNORM_SRGB = 0x4e, + DXGI_FORMAT_BC4_TYPELESS = 0x4f, + DXGI_FORMAT_BC4_UNORM = 0x50, + DXGI_FORMAT_BC4_SNORM = 0x51, + DXGI_FORMAT_BC5_TYPELESS = 0x52, + DXGI_FORMAT_BC5_UNORM = 0x53, + DXGI_FORMAT_BC5_SNORM = 0x54, + DXGI_FORMAT_B5G6R5_UNORM = 0x55, + DXGI_FORMAT_B5G5R5A1_UNORM = 0x56, + DXGI_FORMAT_B8G8R8A8_UNORM = 0x57, + DXGI_FORMAT_B8G8R8X8_UNORM = 0x58, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 0x59, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 0x5a, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 0x5b, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 0x5c, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 0x5d, + DXGI_FORMAT_BC6H_TYPELESS = 0x5e, + DXGI_FORMAT_BC6H_UF16 = 0x5f, + DXGI_FORMAT_BC6H_SF16 = 0x60, + DXGI_FORMAT_BC7_TYPELESS = 0x61, + DXGI_FORMAT_BC7_UNORM = 0x62, + DXGI_FORMAT_BC7_UNORM_SRGB = 0x63, + DXGI_FORMAT_AYUV = 0x64, + DXGI_FORMAT_Y410 = 0x65, + DXGI_FORMAT_Y416 = 0x66, + DXGI_FORMAT_NV12 = 0x67, + DXGI_FORMAT_P010 = 0x68, + DXGI_FORMAT_P016 = 0x69, + DXGI_FORMAT_420_OPAQUE = 0x6a, + DXGI_FORMAT_YUY2 = 0x6b, + DXGI_FORMAT_Y210 = 0x6c, + DXGI_FORMAT_Y216 = 0x6d, + DXGI_FORMAT_NV11 = 0x6e, + DXGI_FORMAT_AI44 = 0x6f, + DXGI_FORMAT_IA44 = 0x70, + DXGI_FORMAT_P8 = 0x71, + DXGI_FORMAT_A8P8 = 0x72, + DXGI_FORMAT_B4G4R4A4_UNORM = 0x73, + + DXGI_FORMAT_P208 = 0x82, + DXGI_FORMAT_V208 = 0x83, + DXGI_FORMAT_V408 = 0x84, + + DXGI_FORMAT_FORCE_UINT = 0xffffffff, +} DXGI_FORMAT; diff --git a/sdk/include/psdk/dxgitype.idl b/sdk/include/psdk/dxgitype.idl new file mode 100644 index 00000000000..a9ed5719a5f --- /dev/null +++ b/sdk/include/psdk/dxgitype.idl @@ -0,0 +1,94 @@ +/* + * Copyright 2007 Andras Kovacs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "dxgicommon.idl"; +import "dxgiformat.idl"; + +cpp_quote("#if 0") +typedef unsigned int UINT; +typedef long BOOL; +cpp_quote("#endif") + +typedef enum DXGI_MODE_ROTATION +{ + DXGI_MODE_ROTATION_UNSPECIFIED = 0x0, + DXGI_MODE_ROTATION_IDENTITY = 0x1, + DXGI_MODE_ROTATION_ROTATE90 = 0x2, + DXGI_MODE_ROTATION_ROTATE180 = 0x3, + DXGI_MODE_ROTATION_ROTATE270 = 0x4, +} DXGI_MODE_ROTATION; + +typedef enum DXGI_MODE_SCANLINE_ORDER +{ + DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED = 0x0, + DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE = 0x1, + DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST = 0x2, + DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST = 0x3, +} DXGI_MODE_SCANLINE_ORDER; + +typedef enum DXGI_MODE_SCALING +{ + DXGI_MODE_SCALING_UNSPECIFIED = 0x0, + DXGI_MODE_SCALING_CENTERED = 0x1, + DXGI_MODE_SCALING_STRETCHED = 0x2, +} DXGI_MODE_SCALING; + +cpp_quote("#ifndef D3DCOLORVALUE_DEFINED") +cpp_quote("#define D3DCOLORVALUE_DEFINED") +typedef struct _D3DCOLORVALUE +{ + float r; + float g; + float b; + float a; +} D3DCOLORVALUE; +cpp_quote("#endif") +typedef D3DCOLORVALUE DXGI_RGBA; + +typedef struct DXGI_MODE_DESC +{ + UINT Width; + UINT Height; + DXGI_RATIONAL RefreshRate; + DXGI_FORMAT Format; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; +} DXGI_MODE_DESC; + +typedef struct DXGI_GAMMA_CONTROL_CAPABILITIES +{ + BOOL ScaleAndOffsetSupported; + float MaxConvertedValue; + float MinConvertedValue; + UINT NumGammaControlPoints; + float ControlPointPositions[1025]; +} DXGI_GAMMA_CONTROL_CAPABILITIES; + +typedef struct DXGI_RGB +{ + float Red; + float Green; + float Blue; +} DXGI_RGB; + +typedef struct DXGI_GAMMA_CONTROL +{ + DXGI_RGB Scale; + DXGI_RGB Offset; + DXGI_RGB GammaCurve[1025]; +} DXGI_GAMMA_CONTROL; diff --git a/sdk/include/psdk/dxva.h b/sdk/include/psdk/dxva.h new file mode 100644 index 00000000000..1260d75b37c --- /dev/null +++ b/sdk/include/psdk/dxva.h @@ -0,0 +1,215 @@ +/* + * Copyright 2015 Michael Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_DXVA_H +#define __WINE_DXVA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DXVA_USUAL_BLOCK_WIDTH 8 +#define DXVA_USUAL_BLOCK_HEIGHT 8 +#define DXVA_USUAL_BLOCK_SIZE (DXVA_USUAL_BLOCK_WIDTH * DXVA_USUAL_BLOCK_HEIGHT) + +#include + +typedef struct _DXVA_PictureParameters +{ + WORD wDecodedPictureIndex; + WORD wDeblockedPictureIndex; + WORD wForwardRefPictureIndex; + WORD wBackwardRefPictureIndex; + WORD wPicWidthInMBminus1; + WORD wPicHeightInMBminus1; + BYTE bMacroblockWidthMinus1; + BYTE bMacroblockHeightMinus1; + BYTE bBlockWidthMinus1; + BYTE bBlockHeightMinus1; + BYTE bBPPminus1; + BYTE bPicStructure; + BYTE bSecondField; + BYTE bPicIntra; + BYTE bPicBackwardPrediction; + BYTE bBidirectionalAveragingMode; + BYTE bMVprecisionAndChromaRelation; + BYTE bChromaFormat; + BYTE bPicScanFixed; + BYTE bPicScanMethod; + BYTE bPicReadbackRequests; + BYTE bRcontrol; + BYTE bPicSpatialResid8; + BYTE bPicOverflowBlocks; + BYTE bPicExtrapolation; + BYTE bPicDeblocked; + BYTE bPicDeblockConfined; + BYTE bPic4MVallowed; + BYTE bPicOBMC; + BYTE bPicBinPB; + BYTE bMV_RPS; + BYTE bReservedBits; + WORD wBitstreamFcodes; + WORD wBitstreamPCEelements; + BYTE bBitstreamConcealmentNeed; + BYTE bBitstreamConcealmentMethod; +} DXVA_PictureParameters, *LPDXVA_PictureParameters; + +typedef struct _DXVA_SliceInfo +{ + WORD wHorizontalPosition; + WORD wVerticalPosition; + DWORD dwSliceBitsInBuffer; + DWORD dwSliceDataLocation; + BYTE bStartCodeBitOffset; + BYTE bReservedBits; + WORD wMBbitOffset; + WORD wNumberMBsInSlice; + WORD wQuantizerScaleCode; + WORD wBadSliceChopping; +} DXVA_SliceInfo, *LPDXVA_SliceInfo; + +typedef struct _DXVA_QmatrixData +{ + BYTE bNewQmatrix[4]; + WORD Qmatrix[4][DXVA_USUAL_BLOCK_WIDTH * DXVA_USUAL_BLOCK_HEIGHT]; +} DXVA_QmatrixData, *LPDXVA_QmatrixData; + +typedef struct +{ + union + { + struct + { + UCHAR Index7Bits : 7; + UCHAR AssociatedFlag : 1; + } DUMMYSTRUCTNAME; + UCHAR bPicEntry; + } DUMMYUNIONNAME; +} DXVA_PicEntry_H264; + +typedef struct +{ + USHORT wFrameWidthInMbsMinus1; + USHORT wFrameHeightInMbsMinus1; + DXVA_PicEntry_H264 CurrPic; + UCHAR num_ref_frames; + union + { + struct + { + USHORT field_pic_flag : 1; + USHORT MbaffFrameFlag : 1; + USHORT residual_colour_transform_flag : 1; + USHORT sp_for_switch_flag : 1; + USHORT chroma_format_idc : 2; + USHORT RefPicFlag : 1; + USHORT constrained_intra_pred_flag : 1; + USHORT weighted_pred_flag : 1; + USHORT weighted_bipred_idc : 2; + USHORT MbsConsecutiveFlag : 1; + USHORT frame_mbs_only_flag : 1; + USHORT transform_8x8_mode_flag : 1; + USHORT MinLumaBipredSize8x8Flag : 1; + USHORT IntraPicFlag : 1; + } DUMMYSTRUCTNAME; + USHORT wBitFields; + } DUMMYUNIONNAME; + UCHAR bit_depth_luma_minus8; + UCHAR bit_depth_chroma_minus8; + USHORT Reserved16Bits; + UINT StatusReportFeedbackNumber; + DXVA_PicEntry_H264 RefFrameList[16]; + INT CurrFieldOrderCnt[2]; + INT FieldOrderCntList[16][2]; + CHAR pic_init_qs_minus26; + CHAR chroma_qp_index_offset; + CHAR second_chroma_qp_index_offset; + UCHAR ContinuationFlag; + CHAR pic_init_qp_minus26; + UCHAR num_ref_idx_l0_active_minus1; + UCHAR num_ref_idx_l1_active_minus1; + UCHAR Reserved8BitsA; + USHORT FrameNumList[16]; + + UINT UsedForReferenceFlags; + USHORT NonExistingFrameFlags; + USHORT frame_num; + UCHAR log2_max_frame_num_minus4; + UCHAR pic_order_cnt_type; + UCHAR log2_max_pic_order_cnt_lsb_minus4; + UCHAR delta_pic_order_always_zero_flag; + UCHAR direct_8x8_inference_flag; + UCHAR entropy_coding_mode_flag; + UCHAR pic_order_present_flag; + UCHAR num_slice_groups_minus1; + UCHAR slice_group_map_type; + UCHAR deblocking_filter_control_present_flag; + UCHAR redundant_pic_cnt_present_flag; + UCHAR Reserved8BitsB; + USHORT slice_group_change_rate_minus1; + UCHAR SliceGroupMap[810]; +} DXVA_PicParams_H264; + +typedef struct +{ + UCHAR bScalingLists4x4[6][16]; + UCHAR bScalingLists8x8[2][64]; +} DXVA_Qmatrix_H264; + +typedef struct +{ + UINT BSNALunitDataLocation; + UINT SliceBytesInBuffer; + USHORT wBadSliceChopping; + USHORT first_mb_in_slice; + USHORT NumMbsForSlice; + USHORT BitOffsetToSliceData; + UCHAR slice_type; + UCHAR luma_log2_weight_denom; + UCHAR chroma_log2_weight_denom; + + UCHAR num_ref_idx_l0_active_minus1; + UCHAR num_ref_idx_l1_active_minus1; + CHAR slice_alpha_c0_offset_div2; + CHAR slice_beta_offset_div2; + UCHAR Reserved8Bits; + DXVA_PicEntry_H264 RefPicList[2][32]; + SHORT Weights[2][32][3][2]; + CHAR slice_qs_delta; + CHAR slice_qp_delta; + UCHAR redundant_pic_cnt; + UCHAR direct_spatial_mv_pred_flag; + UCHAR cabac_init_idc; + UCHAR disable_deblocking_filter_idc; + USHORT slice_id; +} DXVA_Slice_H264_Long; + +typedef struct +{ + UINT BSNALunitDataLocation; + UINT SliceBytesInBuffer; + USHORT wBadSliceChopping; +} DXVA_Slice_H264_Short; + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_DXVA_H */ diff --git a/sdk/include/psdk/dxva2api.idl b/sdk/include/psdk/dxva2api.idl new file mode 100644 index 00000000000..88c586fa088 --- /dev/null +++ b/sdk/include/psdk/dxva2api.idl @@ -0,0 +1,555 @@ +/* + * Copyright 2014 Michael Müller for Pipelight + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "unknwn.idl"; + +cpp_quote("#if 0") +typedef DWORD IDirect3DDevice9; +typedef DWORD IDirect3DSurface9; + +typedef DWORD D3DFORMAT; +typedef DWORD D3DPOOL; +cpp_quote("#endif") + +/* MPEG2 */ +cpp_quote("DEFINE_GUID(DXVA2_ModeMPEG2_MoComp, 0xe6a9f44b, 0x61b0,0x4563, 0x9e,0xa4,0x63,0xd2,0xa3,0xc6,0xfe,0x66);") +cpp_quote("#define DXVA2_ModeMPEG2_MOCOMP DXVA2_ModeMPEG2_MoComp") + +cpp_quote("DEFINE_GUID(DXVA2_ModeMPEG2_IDCT, 0xbf22ad00, 0x03ea,0x4690, 0x80,0x77,0x47,0x33,0x46,0x20,0x9b,0x7e);") + +cpp_quote("DEFINE_GUID(DXVA2_ModeMPEG2_VLD, 0xee27417f, 0x5e28,0x4e65, 0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);") + +/* H264 */ +cpp_quote("DEFINE_GUID(DXVA2_ModeH264_A, 0x1b81be64, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeH264_MoComp_NoFGT DXVA2_ModeH264_A") + +cpp_quote("DEFINE_GUID(DXVA2_ModeH264_B, 0x1b81be65, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeH264_MoComp_FGT DXVA2_ModeH264_B") + +cpp_quote("DEFINE_GUID(DXVA2_ModeH264_C, 0x1b81be66, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeH264_IDCT_NoFGT DXVA2_ModeH264_C") + +cpp_quote("DEFINE_GUID(DXVA2_ModeH264_D, 0x1b81be67, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeH264_IDCT_FGT DXVA2_ModeH264_D") + +cpp_quote("DEFINE_GUID(DXVA2_ModeH264_E, 0x1b81be68, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeH264_VLD_NoFGT DXVA2_ModeH264_E") + +cpp_quote("DEFINE_GUID(DXVA2_ModeH264_F, 0x1b81be69, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeH264_VLD_FGT DXVA2_ModeH264_F") + +/* WMV8 */ +cpp_quote("DEFINE_GUID(DXVA2_ModeWMV8_A, 0x1b81be80, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeWMV8_PostProc DXVA2_ModeWMV8_A") + +cpp_quote("DEFINE_GUID(DXVA2_ModeWMV8_B, 0x1b81be81, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeWMV8_MoComp DXVA2_ModeWMV8_B") + +/* WMV9 */ +cpp_quote("DEFINE_GUID(DXVA2_ModeWMV9_A, 0x1b81be90, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeWMV9_PostProc DXVA2_ModeWMV9_A") + +cpp_quote("DEFINE_GUID(DXVA2_ModeWMV9_B, 0x1b81be91, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeWMV9_MoComp DXVA2_ModeWMV9_B") + +cpp_quote("DEFINE_GUID(DXVA2_ModeWMV9_C, 0x1b81be94, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeWMV9_IDCT DXVA2_ModeWMV9_C") + +/* VC1 */ +cpp_quote("DEFINE_GUID(DXVA2_ModeVC1_A, 0x1b81beA0, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeVC1_PostProc DXVA2_ModeVC1_A") + +cpp_quote("DEFINE_GUID(DXVA2_ModeVC1_B, 0x1b81beA1, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeVC1_MoComp DXVA2_ModeVC1_B") + +cpp_quote("DEFINE_GUID(DXVA2_ModeVC1_C, 0x1b81beA2, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeVC1_IDCT DXVA2_ModeVC1_C") + +cpp_quote("DEFINE_GUID(DXVA2_ModeVC1_D, 0x1b81beA3, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") +cpp_quote("#define DXVA2_ModeVC1_VLD DXVA2_ModeVC1_D") + +/* Encryption */ +cpp_quote("DEFINE_GUID(DXVA_NoEncrypt, 0x1b81bed0, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);") + +cpp_quote("#ifndef REFERENCE_TIME_DEFINED") +cpp_quote("#define REFERENCE_TIME_DEFINED") +typedef LONGLONG REFERENCE_TIME; +cpp_quote("#endif") + +enum +{ + DXVA2_PictureParametersBufferType, + DXVA2_MacroBlockControlBufferType, + DXVA2_ResidualDifferenceBufferType, + DXVA2_DeblockingControlBufferType, + DXVA2_InverseQuantizationMatrixBufferType, + DXVA2_SliceControlBufferType, + DXVA2_BitStreamDateBufferType, + DXVA2_MotionVectorBuffer, + DXVA2_FilmGrainBuffer +}; + +enum +{ + DXVA2_VideoDecoderRenderTarget, + DXVA2_VideoProcessorRenderTarget, + DXVA2_VideoSoftwareRenderTarget +}; + +typedef struct _DXVA2_ExtendedFormat +{ + union + { + struct + { + UINT SampleFormat :8; + UINT VideoChromaSubsampling :4; + UINT NominalRange :3; + UINT VideoTransferMatrix :3; + UINT VideoLighting :4; + UINT VideoPrimaries :5; + UINT VideoTransferFunction :5; + }; + UINT value; + }; +} DXVA2_ExtendedFormat; + +typedef struct _DXVA2_Frequency +{ + UINT Numerator; + UINT Denominator; +} DXVA2_Frequency; + +typedef struct _DXVA2_ConfigPictureDecode +{ + GUID guidConfigBitstreamEncryption; + GUID guidConfigMBcontrolEncryption; + GUID guidConfigResidDiffEncryption; + UINT ConfigBitstreamRaw; + UINT ConfigMBcontrolRasterOrder; + UINT ConfigResidDiffHost; + UINT ConfigSpatialResid8; + UINT ConfigResid8Subtraction; + UINT ConfigSpatialHost8or9Clipping; + UINT ConfigSpatialResidInterleaved; + UINT ConfigIntraResidUnsigned; + UINT ConfigResidDiffAccelerator; + UINT ConfigHostInverseScan; + UINT ConfigSpecificIDCT; + UINT Config4GroupedCoefs; + UINT ConfigMinRenderTargetBuffCount; + USHORT ConfigDecoderSpecific; +} DXVA2_ConfigPictureDecode; + +typedef struct _DXVA2_VideoDesc +{ + UINT SampleWidth; + UINT SampleHeight; + DXVA2_ExtendedFormat SampleFormat; + D3DFORMAT Format; + DXVA2_Frequency InputSampleFreq; + DXVA2_Frequency OutputFrameFreq; + UINT UABProtectionLevel; + UINT Reserved; +} DXVA2_VideoDesc; + +typedef struct _DXVA2_DecodeBufferDesc +{ + DWORD CompressedBufferType; + UINT BufferIndex; + UINT DataOffset; + UINT DataSize; + UINT FirstMBaddress; + UINT NumMBsInBuffer; + UINT Width; + UINT Height; + UINT Stride; + UINT ReservedBits; + PVOID pvPVPState; +} DXVA2_DecodeBufferDesc; + +typedef struct _DXVA2_DecodeExtensionData +{ + UINT Function; + PVOID pPrivateInputData; + UINT PrivateInputDataSize; + PVOID pPrivateOutputData; + UINT PrivateOutputDataSize; +} DXVA2_DecodeExtensionData; + +typedef struct _DXVA2_DecodeExecuteParams +{ + UINT NumCompBuffers; + DXVA2_DecodeBufferDesc* pCompressedBuffers; + DXVA2_DecodeExtensionData* pExtensionData; +} DXVA2_DecodeExecuteParams; + +typedef struct _DXVA2_VideoProcessorCaps +{ + UINT DeviceCaps; + D3DPOOL InputPool; + UINT NumForwardRefSamples; + UINT NumBackwardRefSamples; + UINT Reserved; + UINT DeinterlaceTechnology; + UINT ProcAmpControlCaps; + UINT VideoProcessorOperations; + UINT NoiseFilterTechnology; + UINT DetailFilterTechnology; +} DXVA2_VideoProcessorCaps; + +typedef struct _DXVA2_Fixed32 +{ + union + { + struct + { + USHORT Fraction; + SHORT Value; + }; + LONG ll; + }; +} DXVA2_Fixed32; + +typedef struct _DXVA2_ValueRange +{ + DXVA2_Fixed32 MinValue; + DXVA2_Fixed32 MaxValue; + DXVA2_Fixed32 DefaultValue; + DXVA2_Fixed32 StepSize; +} DXVA2_ValueRange; + +typedef struct _DXVA2_AYUVSample8 +{ + UCHAR Cr; + UCHAR Cb; + UCHAR Y; + UCHAR Alpha; +} DXVA2_AYUVSample8; + +typedef struct _DXVA2_AYUVSample16 +{ + USHORT Cr; + USHORT Cb; + USHORT Y; + USHORT Alpha; +} DXVA2_AYUVSample16; + +typedef struct _DXVA2_ProcAmpValues +{ + DXVA2_Fixed32 Brightness; + DXVA2_Fixed32 Contrast; + DXVA2_Fixed32 Hue; + DXVA2_Fixed32 Saturation; +} DXVA2_ProcAmpValues; + +typedef struct _DXVA2_FilterValues +{ + DXVA2_Fixed32 Level; + DXVA2_Fixed32 Threshold; + DXVA2_Fixed32 Radius; +} DXVA2_FilterValues; + +typedef struct _DXVA2_VideoProcessBltParams +{ + REFERENCE_TIME TargetFrame; + RECT TargetRect; + SIZE ConstrictionSize; + UINT StreamingFlags; + DXVA2_AYUVSample16 BackgroundColor; + DXVA2_ExtendedFormat DestFormat; + DXVA2_ProcAmpValues ProcAmpValues; + DXVA2_Fixed32 Alpha; + DXVA2_FilterValues NoiseFilterLuma; + DXVA2_FilterValues NoiseFilterChroma; + DXVA2_FilterValues DetailFilterLuma; + DXVA2_FilterValues DetailFilterChroma; + DWORD DestData; +} DXVA2_VideoProcessBltParams; + +typedef struct _DXVA2_VideoSample +{ + REFERENCE_TIME Start; + REFERENCE_TIME End; + DXVA2_ExtendedFormat SampleFormat; + IDirect3DSurface9* SrcSurface; + RECT SrcRect; + RECT DstRect; + DXVA2_AYUVSample8 Pal[16]; + DXVA2_Fixed32 PlanarAlpha; + DWORD SampleData; +} DXVA2_VideoSample; + +typedef enum +{ + DXVA2_SurfaceType_DecoderRenderTarget, + DXVA2_SurfaceType_ProcessorRenderTarget, + DXVA2_SurfaceType_D3DRenderTargetTexture, +} DXVA2_SurfaceType; + +interface IDirectXVideoDecoder; +interface IDirectXVideoProcessor; + +/***************************************************************************** + * IDirect3DDeviceManager9 interface + */ +[ + object, + uuid(a0cade0f-06d5-4cf4-a1c7-f3cdd725aa75), + local +] +interface IDirect3DDeviceManager9 : IUnknown +{ + HRESULT ResetDevice( + [in] IDirect3DDevice9* pDevice, + [in] UINT resetToken); + + HRESULT OpenDeviceHandle( + [out] HANDLE* phDevice); + + HRESULT CloseDeviceHandle( + [in] HANDLE hDevice); + + HRESULT TestDevice( + [in] HANDLE hDevice); + + HRESULT LockDevice( + [in] HANDLE hDevice, + [out] IDirect3DDevice9** ppDevice, + [in] BOOL fBlock); + + HRESULT UnlockDevice( + [in] HANDLE hDevice, + [in] BOOL fSaveState); + + HRESULT GetVideoService( + [in] HANDLE hDevice, + [in] REFIID riid, + [out] void** ppService); +} + +/***************************************************************************** + * IDirectXVideoAccelerationService interface + */ +[ + object, + uuid(fc51a550-d5e7-11d9-af55-00054e43ff02), + local +] +interface IDirectXVideoAccelerationService : IUnknown +{ + HRESULT CreateSurface( + [in] UINT width, + [in] UINT height, + [in] UINT backBuffers, + [in] D3DFORMAT format, + [in] D3DPOOL pool, + [in] DWORD usage, + [in] DWORD dxvaType, + [out] IDirect3DSurface9 **ppSurface, + [in, out] HANDLE *pSharedHandle); +} + +/***************************************************************************** + * IDirectXVideoDecoderService interface + */ +[ + object, + uuid(fc51a551-d5e7-11d9-af55-00054e43ff02), + local +] +interface IDirectXVideoDecoderService : IDirectXVideoAccelerationService +{ + HRESULT GetDecoderDeviceGuids( + [out] UINT *count, + [out] GUID **pGuids); + + HRESULT GetDecoderRenderTargets( + [in] REFGUID guid, + [out] UINT *pCount, + [out] D3DFORMAT **pFormats); + + HRESULT GetDecoderConfigurations( + [in] REFGUID guid, + [in] const DXVA2_VideoDesc *pVideoDesc, + [in] IUnknown *pReserved, + [out] UINT *pCount, + [out] DXVA2_ConfigPictureDecode **ppConfigs); + + HRESULT CreateVideoDecoder( + [in] REFGUID guid, + [in] const DXVA2_VideoDesc *pVideoDesc, + [in] DXVA2_ConfigPictureDecode *pConfig, + [in] IDirect3DSurface9 **ppDecoderRenderTargets, + [in] UINT NumSurfaces, + [out] IDirectXVideoDecoder **ppDecode); +} + +/***************************************************************************** + * IDirectXVideoDecoder interface + */ +[ + object, + uuid(f2b0810a-fd00-43c9-918c-df94e2d8ef7d), + local +] +interface IDirectXVideoDecoder : IUnknown +{ + HRESULT GetVideoDecoderService( + [out] IDirectXVideoDecoderService** ppService); + + HRESULT GetCreationParameters( + [out] GUID* pDeviceGuid, + [out] DXVA2_VideoDesc* pVideoDesc, + [out] DXVA2_ConfigPictureDecode* pConfig, + [out] IDirect3DSurface9*** pDecoderRenderTargets, + [out] UINT* pNumSurfaces); + + HRESULT GetBuffer( + [in] UINT BufferType, + [out] void** ppBuffer, + [out] UINT* pBufferSize); + + HRESULT ReleaseBuffer( + [in] UINT BufferType); + + HRESULT BeginFrame( + [in] IDirect3DSurface9* pRenderTarget, + [in] void* pvPVPData); + + HRESULT EndFrame( + [out] HANDLE* pHandleComplete); + + HRESULT Execute( + [in] const DXVA2_DecodeExecuteParams* pExecuteParams); +} + +/***************************************************************************** + * IDirectXVideoProcessorService interface + */ +[ + object, + uuid(fc51a552-d5e7-11d9-af55-00054e43ff02), + local +] +interface IDirectXVideoProcessorService : IDirectXVideoAccelerationService +{ + HRESULT RegisterVideoProcessorSoftwareDevice( + [in] void* pCallbacks); + + HRESULT GetVideoProcessorDeviceGuids( + [in] const DXVA2_VideoDesc* pVideoDesc, + [out] UINT* pCount, + [out] GUID** pGuids); + + HRESULT GetVideoProcessorRenderTargets( + [in] REFGUID VideoProcDeviceGuid, + [in] const DXVA2_VideoDesc* pVideoDesc, + [out] UINT* pCount, + [out] D3DFORMAT** pFormats); + + HRESULT GetVideoProcessorSubStreamFormats( + [in] REFGUID VideoProcDeviceGuid, + [in] const DXVA2_VideoDesc* pVideoDesc, + [in] D3DFORMAT RenderTargetFormat, + [out] UINT* pCount, + [out] D3DFORMAT** pFormats); + + HRESULT GetVideoProcessorCaps( + [in] REFGUID VideoProcDeviceGuid, + [in] const DXVA2_VideoDesc* pVideoDesc, + [in] D3DFORMAT RenderTargetFormat, + [out] DXVA2_VideoProcessorCaps* pCaps); + + HRESULT GetProcAmpRange( + [in] REFGUID VideoProcDeviceGuid, + [in] const DXVA2_VideoDesc* pVideoDesc, + [in] D3DFORMAT RenderTargetFormat, + [in] UINT ProcAmpCap, + [out] DXVA2_ValueRange* pRange); + + HRESULT GetFilterPropertyRange( + [in] REFGUID VideoProcDeviceGuid, + [in] const DXVA2_VideoDesc* pVideoDesc, + [in] D3DFORMAT renderTargetFormat, + [in] UINT FilterSetting, + [out] DXVA2_ValueRange* pRange); + + HRESULT CreateVideoProcessor( + [in] REFGUID VideoProcDeviceGuid, + [in] const DXVA2_VideoDesc* pVideoDesc, + [in] D3DFORMAT RenderTargetFormat, + [in] UINT MaxNumSubStreams, + [out] IDirectXVideoProcessor** ppVidProcess); +} + +/***************************************************************************** + * IDirectXVideoProcessor interface + */ +[ + object, + uuid(8c3a39f0-916e-4690-804f-4c8001355d25), + local +] +interface IDirectXVideoProcessor : IUnknown +{ + HRESULT GetVideoProcessorService( + [out] IDirectXVideoProcessorService** ppService); + + HRESULT GetCreationParameters( + [out] GUID* pDeviceGuid, + [out] DXVA2_VideoDesc* pVideoDesc, + [out] D3DFORMAT* pRenderTargetFormat, + [out] UINT* pMaxNumSubStreams); + + HRESULT GetVideoProcessorCaps( + [out] DXVA2_VideoProcessorCaps* pCaps); + + HRESULT GetProcAmpRange( + [in] UINT ProcAmpCap, + [out] DXVA2_ValueRange* pRange); + + HRESULT GetFilterPropertyRange( + [in] UINT FilterSetting, + [out] DXVA2_ValueRange* pRange); + + HRESULT VideoProcessBlt( + [in] IDirect3DSurface9* pRenderTarget, + [in] const DXVA2_VideoProcessBltParams* pBltParams, + [in] const DXVA2_VideoSample* pSamples, + [in] UINT NumSamples, + [out] HANDLE* pHandleCompleteIDirect3DDeviceManager9); +} + +/***************************************************************************** + * IDirectXVideoMemoryConfiguration interface + */ +[ + object, + uuid(b7f916dd-db3b-49c1-84d7-e45ef99ec726), + local +] +interface IDirectXVideoMemoryConfiguration : IUnknown +{ + HRESULT GetAvailableSurfaceTypeByIndex( + [in] DWORD wTypeIndex, + [out] DXVA2_SurfaceType *pdwType); + + HRESULT SetSurfaceType( + [in] DXVA2_SurfaceType dwType); +} diff --git a/sdk/include/psdk/winerror.h b/sdk/include/psdk/winerror.h index c3815c27e36..ebd25efc7a1 100644 --- a/sdk/include/psdk/winerror.h +++ b/sdk/include/psdk/winerror.h @@ -3311,6 +3311,104 @@ #define WINCODEC_ERR_WIN32ERROR _HRESULT_TYPEDEF_(0x88982f94) #define WINCODEC_ERR_INVALIDPROGRESSIVELEVEL _HRESULT_TYPEDEF_(0x88982f95) +#define DWRITE_E_FILEFORMAT _HRESULT_TYPEDEF_(0x88985000) +#define DWRITE_E_UNEXPECTED _HRESULT_TYPEDEF_(0x88985001) +#define DWRITE_E_NOFONT _HRESULT_TYPEDEF_(0x88985002) +#define DWRITE_E_FILENOTFOUND _HRESULT_TYPEDEF_(0x88985003) +#define DWRITE_E_FILEACCESS _HRESULT_TYPEDEF_(0x88985004) +#define DWRITE_E_FONTCOLLECTIONOBSOLETE _HRESULT_TYPEDEF_(0x88985005) +#define DWRITE_E_ALREADYREGISTERED _HRESULT_TYPEDEF_(0x88985006) +#define DWRITE_E_CACHEFORMAT _HRESULT_TYPEDEF_(0x88985007) +#define DWRITE_E_CACHEVERSION _HRESULT_TYPEDEF_(0x88985008) +#define DWRITE_E_UNSUPPORTEDOPERATION _HRESULT_TYPEDEF_(0x88985009) +#define DWRITE_E_TEXTRENDERERINCOMPATIBLE _HRESULT_TYPEDEF_(0x8898500A) +#define DWRITE_E_FLOWDIRECTIONCONFLICTS _HRESULT_TYPEDEF_(0x8898500B) +#define DWRITE_E_NOCOLOR _HRESULT_TYPEDEF_(0x8898500C) + +#define D2DERR_WRONG_STATE _HRESULT_TYPEDEF_(0x88990001) +#define D2DERR_NOT_INITIALIZED _HRESULT_TYPEDEF_(0x88990002) +#define D2DERR_UNSUPPORTED_OPERATION _HRESULT_TYPEDEF_(0x88990003) +#define D2DERR_SCANNER_FAILED _HRESULT_TYPEDEF_(0x88990004) +#define D2DERR_SCREEN_ACCESS_DENIED _HRESULT_TYPEDEF_(0x88990005) +#define D2DERR_DISPLAY_STATE_INVALID _HRESULT_TYPEDEF_(0x88990006) +#define D2DERR_ZERO_VECTOR _HRESULT_TYPEDEF_(0x88990007) +#define D2DERR_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x88990008) +#define D2DERR_DISPLAY_FORMAT_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x88990009) +#define D2DERR_INVALID_CALL _HRESULT_TYPEDEF_(0x8899000a) +#define D2DERR_NO_HARDWARE_DEVICE _HRESULT_TYPEDEF_(0x8899000b) +#define D2DERR_RECREATE_TARGET _HRESULT_TYPEDEF_(0x8899000c) +#define D2DERR_TOO_MANY_SHADER_ELEMENTS _HRESULT_TYPEDEF_(0x8899000d) +#define D2DERR_SHADER_COMPILE_FAILED _HRESULT_TYPEDEF_(0x8899000e) +#define D2DERR_MAX_TEXTURE_SIZE_EXCEEDED _HRESULT_TYPEDEF_(0x8899000f) +#define D2DERR_UNSUPPORTED_VERSION _HRESULT_TYPEDEF_(0x88990010) +#define D2DERR_BAD_NUMBER _HRESULT_TYPEDEF_(0x88990011) +#define D2DERR_WRONG_FACTORY _HRESULT_TYPEDEF_(0x88990012) +#define D2DERR_LAYER_ALREADY_IN_USE _HRESULT_TYPEDEF_(0x88990013) +#define D2DERR_POP_CALL_DID_NOT_MATCH_PUSH _HRESULT_TYPEDEF_(0x88990014) +#define D2DERR_WRONG_RESOURCE_DOMAIN _HRESULT_TYPEDEF_(0x88990015) +#define D2DERR_PUSH_POP_UNBALANCED _HRESULT_TYPEDEF_(0x88990016) +#define D2DERR_RENDER_TARGET_HAS_LAYER_OR_CLIPRECT _HRESULT_TYPEDEF_(0x88990017) +#define D2DERR_INCOMPATIBLE_BRUSH_TYPES _HRESULT_TYPEDEF_(0x88990018) +#define D2DERR_WIN32_ERROR _HRESULT_TYPEDEF_(0x88990019) +#define D2DERR_TARGET_NOT_GDI_COMPATIBLE _HRESULT_TYPEDEF_(0x8899001a) +#define D2DERR_TEXT_EFFECT_IS_WRONG_TYPE _HRESULT_TYPEDEF_(0x8899001b) +#define D2DERR_TEXT_RENDERER_NOT_RELEASED _HRESULT_TYPEDEF_(0x8899001c) +#define D2DERR_EXCEEDS_MAX_BITMAP_SIZE _HRESULT_TYPEDEF_(0x8899001d) +#define D2DERR_INVALID_GRAPH_CONFIGURATION _HRESULT_TYPEDEF_(0x8899001e) +#define D2DERR_INVALID_INTERNAL_GRAPH_CONFIGURATION _HRESULT_TYPEDEF_(0x8899001f) +#define D2DERR_CYCLIC_GRAPH _HRESULT_TYPEDEF_(0x88990020) +#define D2DERR_BITMAP_CANNOT_DRAW _HRESULT_TYPEDEF_(0x88990021) +#define D2DERR_OUTSTANDING_BITMAP_REFERENCES _HRESULT_TYPEDEF_(0x88990022) +#define D2DERR_ORIGINAL_TARGET_NOT_BOUND _HRESULT_TYPEDEF_(0x88990023) +#define D2DERR_INVALID_TARGET _HRESULT_TYPEDEF_(0x88990024) +#define D2DERR_BITMAP_BOUND_AS_TARGET _HRESULT_TYPEDEF_(0x88990025) +#define D2DERR_INSUFFICIENT_DEVICE_CAPABILITIES _HRESULT_TYPEDEF_(0x88990026) +#define D2DERR_INTERMEDIATE_TOO_LARGE _HRESULT_TYPEDEF_(0x88990027) +#define D2DERR_EFFECT_IS_NOT_REGISTERED _HRESULT_TYPEDEF_(0x88990028) +#define D2DERR_INVALID_PROPERTY _HRESULT_TYPEDEF_(0x88990029) +#define D2DERR_NO_SUBPROPERTIES _HRESULT_TYPEDEF_(0x8899002a) +#define D2DERR_PRINT_JOB_CLOSED _HRESULT_TYPEDEF_(0x8899002b) +#define D2DERR_PRINT_FORMAT_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8899002c) +#define D2DERR_TOO_MANY_TRANSFORM_INPUTS _HRESULT_TYPEDEF_(0x8899002d) + +#define DXGI_STATUS_OCCLUDED _HRESULT_TYPEDEF_(0x087a0001) +#define DXGI_STATUS_CLIPPED _HRESULT_TYPEDEF_(0x087a0002) +#define DXGI_STATUS_NO_REDIRECTION _HRESULT_TYPEDEF_(0x087a0004) +#define DXGI_STATUS_NO_DESKTOP_ACCESS _HRESULT_TYPEDEF_(0x087a0005) +#define DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE _HRESULT_TYPEDEF_(0x087a0006) +#define DXGI_STATUS_MODE_CHANGED _HRESULT_TYPEDEF_(0x087a0007) +#define DXGI_STATUS_MODE_CHANGE_IN_PROGRESS _HRESULT_TYPEDEF_(0x087a0008) +#define DXGI_STATUS_UNOCCLUDED _HRESULT_TYPEDEF_(0x087a0009) +#define DXGI_STATUS_DDA_WAS_STILL_DRAWING _HRESULT_TYPEDEF_(0x087a000a) +#define DXGI_STATUS_PRESENT_REQUIRED _HRESULT_TYPEDEF_(0x087a002f) + +#define DXGI_ERROR_INVALID_CALL _HRESULT_TYPEDEF_(0x887a0001) +#define DXGI_ERROR_NOT_FOUND _HRESULT_TYPEDEF_(0x887a0002) +#define DXGI_ERROR_MORE_DATA _HRESULT_TYPEDEF_(0x887a0003) +#define DXGI_ERROR_UNSUPPORTED _HRESULT_TYPEDEF_(0x887a0004) +#define DXGI_ERROR_DEVICE_REMOVED _HRESULT_TYPEDEF_(0x887a0005) +#define DXGI_ERROR_DEVICE_HUNG _HRESULT_TYPEDEF_(0x887a0006) +#define DXGI_ERROR_DEVICE_RESET _HRESULT_TYPEDEF_(0x887a0007) +#define DXGI_ERROR_WAS_STILL_DRAWING _HRESULT_TYPEDEF_(0x887a000a) +#define DXGI_ERROR_FRAME_STATISTICS_DISJOINT _HRESULT_TYPEDEF_(0x887a000b) +#define DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE _HRESULT_TYPEDEF_(0x887a000c) +#define DXGI_ERROR_DRIVER_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x887a0020) +#define DXGI_ERROR_NONEXCLUSIVE _HRESULT_TYPEDEF_(0x887a0021) +#define DXGI_ERROR_NOT_CURRENTLY_AVAILABLE _HRESULT_TYPEDEF_(0x887a0022) +#define DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED _HRESULT_TYPEDEF_(0x887a0023) +#define DXGI_ERROR_REMOTE_OUTOFMEMORY _HRESULT_TYPEDEF_(0x887a0024) +#define DXGI_ERROR_ACCESS_LOST _HRESULT_TYPEDEF_(0x887a0026) +#define DXGI_ERROR_WAIT_TIMEOUT _HRESULT_TYPEDEF_(0x887a0027) +#define DXGI_ERROR_SESSION_DISCONNECTED _HRESULT_TYPEDEF_(0x887a0028) +#define DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE _HRESULT_TYPEDEF_(0x887a0029) +#define DXGI_ERROR_CANNOT_PROTECT_CONTENT _HRESULT_TYPEDEF_(0x887a002a) +#define DXGI_ERROR_ACCESS_DENIED _HRESULT_TYPEDEF_(0x887a002b) +#define DXGI_ERROR_NAME_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x887a002c) +#define DXGI_ERROR_SDK_COMPONENT_MISSING _HRESULT_TYPEDEF_(0x887a002d) +#define DXGI_ERROR_NOT_CURRENT _HRESULT_TYPEDEF_(0x887a002e) +#define DXGI_ERROR_HW_PROTECTION_OUTOFMEMORY _HRESULT_TYPEDEF_(0x887a0030) +#define DXGI_ERROR_MODE_CHANGE_IN_PROGRESS _HRESULT_TYPEDEF_(0x887a0025) + #define ERROR_AUDITING_DISABLED _HRESULT_TYPEDEF_(0xC0090001L) #define ERROR_ALL_SIDS_FILTERED _HRESULT_TYPEDEF_(0xC0090002L) diff --git a/sdk/include/psdk/winuser.h b/sdk/include/psdk/winuser.h index c3978697e3f..c51983c70d1 100644 --- a/sdk/include/psdk/winuser.h +++ b/sdk/include/psdk/winuser.h @@ -2112,6 +2112,8 @@ extern "C" { #define DCX_INTERSECTRGN 128 #define DCX_VALIDATE 0x200000 #define DCX_EXCLUDEUPDATE 0x100 +#define DCX_USESTYLE 0x00010000 +#define DCX_NORECOMPUTE 0x00100000 #define GMDI_GOINTOPOPUPS 2 #define GMDI_USEDISABLED 1 #define FKF_AVAILABLE 2 diff --git a/sdk/include/reactos/wine/CMakeLists.txt b/sdk/include/reactos/wine/CMakeLists.txt index 709ed1b8c23..935968e132a 100644 --- a/sdk/include/reactos/wine/CMakeLists.txt +++ b/sdk/include/reactos/wine/CMakeLists.txt @@ -1,2 +1,2 @@ -add_idl_headers(wineheaders fil_data.idl itss.idl) +add_idl_headers(wineheaders winedxgi.idl fil_data.idl itss.idl) diff --git a/sdk/include/reactos/wine/vulkan.h b/sdk/include/reactos/wine/vulkan.h new file mode 100644 index 00000000000..011c8fa2e6d --- /dev/null +++ b/sdk/include/reactos/wine/vulkan.h @@ -0,0 +1,5927 @@ +/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! + * + * This file is generated from Vulkan vk.xml file covered + * by the following copyright and permission notice: + * + * Copyright (c) 2015-2019 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---- Exceptions to the Apache 2.0 License: ---- + * + * As an exception, if you use this Software to generate code and portions of + * this Software are embedded into the generated code as a result, you may + * redistribute such product without providing attribution as would otherwise + * be required by Sections 4(a), 4(b) and 4(d) of the License. + * + * In addition, if you combine or link code generated by this Software with + * software that is licensed under the GPLv2 or the LGPL v2.0 or 2.1 + * ("`Combined Software`") and if a court of competent jurisdiction determines + * that the patent provision (Section 3), the indemnity provision (Section 9) + * or other Section of the License conflicts with the conditions of the + * applicable GPL or LGPL license, you may retroactively and prospectively + * choose to deem waived or otherwise exclude such Section(s) of the License, + * but only in their entirety and only with respect to the Combined Software. + * + */ + +#ifndef __WINE_VULKAN_H +#define __WINE_VULKAN_H + +#include +#include + +/* Define WINE_VK_HOST to get 'host' headers. */ +#ifdef WINE_VK_HOST +#define VKAPI_CALL +#define WINE_VK_ALIGN(x) +#endif + +#ifndef VKAPI_CALL +#define VKAPI_CALL __stdcall +#endif + +#ifndef VKAPI_PTR +#define VKAPI_PTR VKAPI_CALL +#endif + +#ifndef WINE_VK_ALIGN +#define WINE_VK_ALIGN DECLSPEC_ALIGN +#endif + +#ifdef __REACTOS__ +#define USE_WIN32_VULKAN 1 +#endif + +#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 +#define VK_UUID_SIZE 16 +#define VK_LUID_SIZE 8 +#define VK_LUID_SIZE_KHR VK_LUID_SIZE +#define VK_MAX_EXTENSION_NAME_SIZE 256 +#define VK_MAX_DESCRIPTION_SIZE 256 +#define VK_MAX_MEMORY_TYPES 32 +#define VK_MAX_MEMORY_HEAPS 16 +#define VK_LOD_CLAMP_NONE 1000.0f +#define VK_REMAINING_MIP_LEVELS (~0U) +#define VK_REMAINING_ARRAY_LAYERS (~0U) +#define VK_WHOLE_SIZE (~0ULL) +#define VK_ATTACHMENT_UNUSED (~0U) +#define VK_TRUE 1 +#define VK_FALSE 0 +#define VK_QUEUE_FAMILY_IGNORED (~0U) +#define VK_QUEUE_FAMILY_EXTERNAL (~0U-1) +#define VK_QUEUE_FAMILY_EXTERNAL_KHR VK_QUEUE_FAMILY_EXTERNAL +#define VK_QUEUE_FAMILY_FOREIGN_EXT (~0U-2) +#define VK_SUBPASS_EXTERNAL (~0U) +#define VK_MAX_DEVICE_GROUP_SIZE 32 +#define VK_MAX_DEVICE_GROUP_SIZE_KHR VK_MAX_DEVICE_GROUP_SIZE +#define VK_MAX_DRIVER_NAME_SIZE_KHR 256 +#define VK_MAX_DRIVER_INFO_SIZE_KHR 256 +#define VK_SHADER_UNUSED_NV (~0U) +#define VK_KHR_SURFACE_SPEC_VERSION 25 +#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" +#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70 +#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" +#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 +#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" +#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 +#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" +#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1 +#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted" +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" +#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1 +#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" +#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1 +#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order" +#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1 +#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax" +#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1 +#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter" +#define VK_AMD_GCN_SHADER_SPEC_VERSION 1 +#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader" +#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1 +#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation" +#define VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION 1 +#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback" +#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 +#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" +#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1 +#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height" +#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 1 +#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float" +#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1 +#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot" +#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1 +#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod" +#define VK_AMD_SHADER_INFO_SPEC_VERSION 1 +#define VK_AMD_SHADER_INFO_EXTENSION_NAME "VK_AMD_shader_info" +#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION 1 +#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod" +#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2 +#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image" +#define VK_KHR_MULTIVIEW_SPEC_VERSION 1 +#define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview" +#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1 +#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc" +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2" +#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 3 +#define VK_KHR_DEVICE_GROUP_EXTENSION_NAME "VK_KHR_device_group" +#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1 +#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters" +#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot" +#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" +#define VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION 1 +#define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode" +#define VK_KHR_MAINTENANCE1_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1" +#define VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION 1 +#define VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHR_device_group_creation" +#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities" +#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory" +#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities" +#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore" +#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2 +#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor" +#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 1 +#define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" +#define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1 +#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" +#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 +#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage" +#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 +#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" +#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1 +#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template" +#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 +#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" +#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1 +#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage" +#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1 +#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough" +#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2" +#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle" +#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1 +#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles" +#define VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION 1 +#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME "VK_EXT_conservative_rasterization" +#define VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME "VK_EXT_depth_clip_enable" +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 3 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" +#define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 +#define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" +#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities" +#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence" +#define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" +#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1 +#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers" +#define VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION 1 +#define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME "VK_EXT_queue_family_foreign" +#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 +#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" +#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 1 +#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" +#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1 +#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class" +#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 1 +#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16" +#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1 +#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples" +#define VK_AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION 1 +#define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask" +#define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 +#define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" +#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1 +#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export" +#define VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION 1 +#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations" +#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1 +#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout" +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2" +#define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 +#define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" +#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2 +#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" +#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color" +#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1 +#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples" +#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1 +#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle" +#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1 +#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage" +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" +#define VK_KHR_BIND_MEMORY_2_SPEC_VERSION 1 +#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME "VK_KHR_bind_memory2" +#define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache" +#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2 +#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" +#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1 +#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer" +#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3 +#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image" +#define VK_NV_RAY_TRACING_SPEC_VERSION 3 +#define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1 +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test" +#define VK_KHR_MAINTENANCE3_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3" +#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 +#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count" +#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 1 +#define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic" +#define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 +#define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" +#define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1 +#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage" +#define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host" +#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1 +#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker" +#define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1 +#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64" +#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties" +#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION 1 +#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME "VK_AMD_memory_overallocation_behavior" +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 3 +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor" +#define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 +#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" +#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 1 +#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls" +#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1 +#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned" +#define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1 +#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve" +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" +#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 +#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives" +#define VK_NV_MESH_SHADER_SPEC_VERSION 1 +#define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader" +#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric" +#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 1 +#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint" +#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1 +#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive" +#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2 +#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints" +#define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3 +#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" +#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 2 +#define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info" +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" +#define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 +#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1 +#define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string" +#define VK_EXT_MEMORY_BUDGET_SPEC_VERSION 1 +#define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget" +#define VK_EXT_MEMORY_PRIORITY_SPEC_VERSION 1 +#define VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME "VK_EXT_memory_priority" +#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION 1 +#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME "VK_NV_dedicated_allocation_image_aliasing" +#define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2 +#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address" +#define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1 +#define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage" +#define VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION 1 +#define VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME "VK_NV_cooperative_matrix" +#define VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION 1 +#define VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME "VK_EXT_ycbcr_image_arrays" +#define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 +#define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset" + +#define VK_MAKE_VERSION(major, minor, patch) \ + (((major) << 22) | ((minor) << 12) | (patch)) +#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) +#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0) +#define VK_API_VERSION_1_1 VK_MAKE_VERSION(1, 1, 0) +#define VK_HEADER_VERSION 104 +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#define VK_NULL_HANDLE 0 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) +VK_DEFINE_HANDLE(VkCommandBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) +typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateKHR; +VK_DEFINE_HANDLE(VkDevice) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_HANDLE(VkPhysicalDevice) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) +VK_DEFINE_HANDLE(VkQueue) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) +typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) + +typedef uint32_t VkBool32; +typedef uint64_t VkDeviceAddress; +typedef uint64_t VkDeviceSize; +typedef uint32_t VkFlags; +typedef uint32_t VkSampleMask; + +typedef VkFlags VkAccessFlags; +typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; +typedef VkFlags VkAttachmentDescriptionFlags; +typedef VkFlags VkBufferCreateFlags; +typedef VkFlags VkBufferUsageFlags; +typedef VkFlags VkBufferViewCreateFlags; +typedef VkFlags VkBuildAccelerationStructureFlagsNV; +typedef VkFlags VkColorComponentFlags; +typedef VkFlags VkCommandBufferResetFlags; +typedef VkFlags VkCommandBufferUsageFlags; +typedef VkFlags VkCommandPoolCreateFlags; +typedef VkFlags VkCommandPoolResetFlags; +typedef VkFlags VkCommandPoolTrimFlags; +typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; +typedef VkFlags VkCompositeAlphaFlagsKHR; +typedef VkFlags VkConditionalRenderingFlagsEXT; +typedef VkFlags VkCullModeFlags; +typedef VkFlags VkDebugReportFlagsEXT; +typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; +typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; +typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; +typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; +typedef VkFlags VkDependencyFlags; +typedef VkFlags VkDescriptorBindingFlagsEXT; +typedef VkFlags VkDescriptorPoolCreateFlags; +typedef VkFlags VkDescriptorPoolResetFlags; +typedef VkFlags VkDescriptorSetLayoutCreateFlags; +typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; +typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpdateTemplateCreateFlagsKHR; +typedef VkFlags VkDeviceCreateFlags; +typedef VkFlags VkDeviceGroupPresentModeFlagsKHR; +typedef VkFlags VkDeviceQueueCreateFlags; +typedef VkFlags VkDisplayModeCreateFlagsKHR; +typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; +typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; +typedef VkFlags VkEventCreateFlags; +typedef VkFlags VkExternalFenceFeatureFlags; +typedef VkExternalFenceFeatureFlags VkExternalFenceFeatureFlagsKHR; +typedef VkFlags VkExternalFenceHandleTypeFlags; +typedef VkExternalFenceHandleTypeFlags VkExternalFenceHandleTypeFlagsKHR; +typedef VkFlags VkExternalMemoryFeatureFlags; +typedef VkExternalMemoryFeatureFlags VkExternalMemoryFeatureFlagsKHR; +typedef VkFlags VkExternalMemoryFeatureFlagsNV; +typedef VkFlags VkExternalMemoryHandleTypeFlags; +typedef VkExternalMemoryHandleTypeFlags VkExternalMemoryHandleTypeFlagsKHR; +typedef VkFlags VkExternalMemoryHandleTypeFlagsNV; +typedef VkFlags VkExternalSemaphoreFeatureFlags; +typedef VkExternalSemaphoreFeatureFlags VkExternalSemaphoreFeatureFlagsKHR; +typedef VkFlags VkExternalSemaphoreHandleTypeFlags; +typedef VkExternalSemaphoreHandleTypeFlags VkExternalSemaphoreHandleTypeFlagsKHR; +typedef VkFlags VkFenceCreateFlags; +typedef VkFlags VkFenceImportFlags; +typedef VkFenceImportFlags VkFenceImportFlagsKHR; +typedef VkFlags VkFormatFeatureFlags; +typedef VkFlags VkFramebufferCreateFlags; +typedef VkFlags VkGeometryFlagsNV; +typedef VkFlags VkGeometryInstanceFlagsNV; +typedef VkFlags VkIOSSurfaceCreateFlagsMVK; +typedef VkFlags VkImageAspectFlags; +typedef VkFlags VkImageCreateFlags; +typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA; +typedef VkFlags VkImageUsageFlags; +typedef VkFlags VkImageViewCreateFlags; +typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX; +typedef VkFlags VkInstanceCreateFlags; +typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; +typedef VkFlags VkMemoryAllocateFlags; +typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR; +typedef VkFlags VkMemoryHeapFlags; +typedef VkFlags VkMemoryMapFlags; +typedef VkFlags VkMemoryPropertyFlags; +typedef VkFlags VkMetalSurfaceCreateFlagsEXT; +typedef VkFlags VkObjectEntryUsageFlagsNVX; +typedef VkFlags VkPeerMemoryFeatureFlags; +typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR; +typedef VkFlags VkPipelineCacheCreateFlags; +typedef VkFlags VkPipelineColorBlendStateCreateFlags; +typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; +typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV; +typedef VkFlags VkPipelineCreateFlags; +typedef VkFlags VkPipelineCreationFeedbackFlagsEXT; +typedef VkFlags VkPipelineDepthStencilStateCreateFlags; +typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; +typedef VkFlags VkPipelineDynamicStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineLayoutCreateFlags; +typedef VkFlags VkPipelineMultisampleStateCreateFlags; +typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; +typedef VkFlags VkPipelineRasterizationDepthClipStateCreateFlagsEXT; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT; +typedef VkFlags VkPipelineShaderStageCreateFlags; +typedef VkFlags VkPipelineStageFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; +typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; +typedef VkFlags VkQueryControlFlags; +typedef VkFlags VkQueryPipelineStatisticFlags; +typedef VkFlags VkQueryPoolCreateFlags; +typedef VkFlags VkQueryResultFlags; +typedef VkFlags VkQueueFlags; +typedef VkFlags VkRenderPassCreateFlags; +typedef VkFlags VkResolveModeFlagsKHR; +typedef VkFlags VkSampleCountFlags; +typedef VkFlags VkSamplerCreateFlags; +typedef VkFlags VkSemaphoreCreateFlags; +typedef VkFlags VkSemaphoreImportFlags; +typedef VkSemaphoreImportFlags VkSemaphoreImportFlagsKHR; +typedef VkFlags VkShaderModuleCreateFlags; +typedef VkFlags VkShaderStageFlags; +typedef VkFlags VkSparseImageFormatFlags; +typedef VkFlags VkSparseMemoryBindFlags; +typedef VkFlags VkStencilFaceFlags; +typedef VkFlags VkSubgroupFeatureFlags; +typedef VkFlags VkSubpassDescriptionFlags; +typedef VkFlags VkSurfaceCounterFlagsEXT; +typedef VkFlags VkSurfaceTransformFlagsKHR; +typedef VkFlags VkSwapchainCreateFlagsKHR; +typedef VkFlags VkValidationCacheCreateFlagsEXT; +typedef VkFlags VkViSurfaceCreateFlagsNN; +typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; +typedef VkFlags VkWin32SurfaceCreateFlagsKHR; +typedef VkFlags VkXcbSurfaceCreateFlagsKHR; +typedef VkFlags VkXlibSurfaceCreateFlagsKHR; + +typedef enum VkAccelerationStructureMemoryRequirementsTypeNV +{ + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_NV_MAX_ENUM = 0x7fffffff, +} VkAccelerationStructureMemoryRequirementsTypeNV; + +typedef enum VkAccelerationStructureTypeNV +{ + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1, + VK_ACCELERATION_STRUCTURE_TYPE_NV_MAX_ENUM = 0x7fffffff, +} VkAccelerationStructureTypeNV; + +typedef enum VkAccessFlagBits +{ + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, + VK_ACCESS_INDEX_READ_BIT = 0x00000002, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, + VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, + VK_ACCESS_SHADER_READ_BIT = 0x00000020, + VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, + VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, + VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, + VK_ACCESS_HOST_READ_BIT = 0x00002000, + VK_ACCESS_HOST_WRITE_BIT = 0x00004000, + VK_ACCESS_MEMORY_READ_BIT = 0x00008000, + VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000, + VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000, + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkAccessFlagBits; + +typedef enum VkAttachmentDescriptionFlagBits +{ + VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, + VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkAttachmentDescriptionFlagBits; + +typedef enum VkAttachmentLoadOp +{ + VK_ATTACHMENT_LOAD_OP_LOAD = 0, + VK_ATTACHMENT_LOAD_OP_CLEAR = 1, + VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, + VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7fffffff, +} VkAttachmentLoadOp; + +typedef enum VkAttachmentStoreOp +{ + VK_ATTACHMENT_STORE_OP_STORE = 0, + VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, + VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7fffffff, +} VkAttachmentStoreOp; + +typedef enum VkBlendFactor +{ + VK_BLEND_FACTOR_ZERO = 0, + VK_BLEND_FACTOR_ONE = 1, + VK_BLEND_FACTOR_SRC_COLOR = 2, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, + VK_BLEND_FACTOR_DST_COLOR = 4, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, + VK_BLEND_FACTOR_SRC_ALPHA = 6, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, + VK_BLEND_FACTOR_DST_ALPHA = 8, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, + VK_BLEND_FACTOR_CONSTANT_COLOR = 10, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, + VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, + VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, + VK_BLEND_FACTOR_SRC1_COLOR = 15, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, + VK_BLEND_FACTOR_SRC1_ALPHA = 17, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, + VK_BLEND_FACTOR_MAX_ENUM = 0x7fffffff, +} VkBlendFactor; + +typedef enum VkBlendOp +{ + VK_BLEND_OP_ADD = 0, + VK_BLEND_OP_SUBTRACT = 1, + VK_BLEND_OP_REVERSE_SUBTRACT = 2, + VK_BLEND_OP_MIN = 3, + VK_BLEND_OP_MAX = 4, + VK_BLEND_OP_ZERO_EXT = 1000148000, + VK_BLEND_OP_SRC_EXT = 1000148001, + VK_BLEND_OP_DST_EXT = 1000148002, + VK_BLEND_OP_SRC_OVER_EXT = 1000148003, + VK_BLEND_OP_DST_OVER_EXT = 1000148004, + VK_BLEND_OP_SRC_IN_EXT = 1000148005, + VK_BLEND_OP_DST_IN_EXT = 1000148006, + VK_BLEND_OP_SRC_OUT_EXT = 1000148007, + VK_BLEND_OP_DST_OUT_EXT = 1000148008, + VK_BLEND_OP_SRC_ATOP_EXT = 1000148009, + VK_BLEND_OP_DST_ATOP_EXT = 1000148010, + VK_BLEND_OP_XOR_EXT = 1000148011, + VK_BLEND_OP_MULTIPLY_EXT = 1000148012, + VK_BLEND_OP_SCREEN_EXT = 1000148013, + VK_BLEND_OP_OVERLAY_EXT = 1000148014, + VK_BLEND_OP_DARKEN_EXT = 1000148015, + VK_BLEND_OP_LIGHTEN_EXT = 1000148016, + VK_BLEND_OP_COLORDODGE_EXT = 1000148017, + VK_BLEND_OP_COLORBURN_EXT = 1000148018, + VK_BLEND_OP_HARDLIGHT_EXT = 1000148019, + VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020, + VK_BLEND_OP_DIFFERENCE_EXT = 1000148021, + VK_BLEND_OP_EXCLUSION_EXT = 1000148022, + VK_BLEND_OP_INVERT_EXT = 1000148023, + VK_BLEND_OP_INVERT_RGB_EXT = 1000148024, + VK_BLEND_OP_LINEARDODGE_EXT = 1000148025, + VK_BLEND_OP_LINEARBURN_EXT = 1000148026, + VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027, + VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028, + VK_BLEND_OP_PINLIGHT_EXT = 1000148029, + VK_BLEND_OP_HARDMIX_EXT = 1000148030, + VK_BLEND_OP_HSL_HUE_EXT = 1000148031, + VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032, + VK_BLEND_OP_HSL_COLOR_EXT = 1000148033, + VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034, + VK_BLEND_OP_PLUS_EXT = 1000148035, + VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036, + VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037, + VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038, + VK_BLEND_OP_MINUS_EXT = 1000148039, + VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040, + VK_BLEND_OP_CONTRAST_EXT = 1000148041, + VK_BLEND_OP_INVERT_OVG_EXT = 1000148042, + VK_BLEND_OP_RED_EXT = 1000148043, + VK_BLEND_OP_GREEN_EXT = 1000148044, + VK_BLEND_OP_BLUE_EXT = 1000148045, + VK_BLEND_OP_MAX_ENUM = 0x7fffffff, +} VkBlendOp; + +typedef enum VkBlendOverlapEXT +{ + VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, + VK_BLEND_OVERLAP_DISJOINT_EXT = 1, + VK_BLEND_OVERLAP_CONJOINT_EXT = 2, + VK_BLEND_OVERLAP_EXT_MAX_ENUM = 0x7fffffff, +} VkBlendOverlapEXT; + +typedef enum VkBorderColor +{ + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, + VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, + VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, + VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, + VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, + VK_BORDER_COLOR_MAX_ENUM = 0x7fffffff, +} VkBorderColor; + +typedef enum VkBufferCreateFlagBits +{ + VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000010, + VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkBufferCreateFlagBits; + +typedef enum VkBufferUsageFlagBits +{ + VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200, + VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = 0x00020000, + VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkBufferUsageFlagBits; + +typedef enum VkBuildAccelerationStructureFlagBitsNV +{ + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = 0x00000001, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = 0x00000002, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = 0x00000004, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = 0x00000008, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = 0x00000010, + VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_NV_MAX_ENUM = 0x7fffffff, +} VkBuildAccelerationStructureFlagBitsNV; + +typedef enum VkChromaLocation +{ + VK_CHROMA_LOCATION_COSITED_EVEN = 0, + VK_CHROMA_LOCATION_MIDPOINT = 1, + VK_CHROMA_LOCATION_MAX_ENUM = 0x7fffffff, +} VkChromaLocation; + +typedef enum VkCoarseSampleOrderTypeNV +{ + VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0, + VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1, + VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2, + VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3, + VK_COARSE_SAMPLE_ORDER_TYPE_NV_MAX_ENUM = 0x7fffffff, +} VkCoarseSampleOrderTypeNV; + +typedef enum VkColorComponentFlagBits +{ + VK_COLOR_COMPONENT_R_BIT = 0x00000001, + VK_COLOR_COMPONENT_G_BIT = 0x00000002, + VK_COLOR_COMPONENT_B_BIT = 0x00000004, + VK_COLOR_COMPONENT_A_BIT = 0x00000008, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkColorComponentFlagBits; + +typedef enum VkColorSpaceKHR +{ + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, + VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002, + VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104003, + VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004, + VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005, + VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006, + VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007, + VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008, + VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009, + VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010, + VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, + VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, + VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, + VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, + VK_COLOR_SPACE_KHR_MAX_ENUM = 0x7fffffff, +} VkColorSpaceKHR; + +typedef enum VkCommandBufferLevel +{ + VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, + VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7fffffff, +} VkCommandBufferLevel; + +typedef enum VkCommandBufferResetFlagBits +{ + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkCommandBufferResetFlagBits; + +typedef enum VkCommandBufferUsageFlagBits +{ + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, + VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkCommandBufferUsageFlagBits; + +typedef enum VkCommandPoolCreateFlagBits +{ + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, + VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004, + VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkCommandPoolCreateFlagBits; + +typedef enum VkCommandPoolResetFlagBits +{ + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkCommandPoolResetFlagBits; + +typedef enum VkCompareOp +{ + VK_COMPARE_OP_NEVER = 0, + VK_COMPARE_OP_LESS = 1, + VK_COMPARE_OP_EQUAL = 2, + VK_COMPARE_OP_LESS_OR_EQUAL = 3, + VK_COMPARE_OP_GREATER = 4, + VK_COMPARE_OP_NOT_EQUAL = 5, + VK_COMPARE_OP_GREATER_OR_EQUAL = 6, + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_MAX_ENUM = 0x7fffffff, +} VkCompareOp; + +typedef enum VkComponentSwizzle +{ + VK_COMPONENT_SWIZZLE_IDENTITY = 0, + VK_COMPONENT_SWIZZLE_ZERO = 1, + VK_COMPONENT_SWIZZLE_ONE = 2, + VK_COMPONENT_SWIZZLE_R = 3, + VK_COMPONENT_SWIZZLE_G = 4, + VK_COMPONENT_SWIZZLE_B = 5, + VK_COMPONENT_SWIZZLE_A = 6, + VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7fffffff, +} VkComponentSwizzle; + +typedef enum VkComponentTypeNV +{ + VK_COMPONENT_TYPE_FLOAT16_NV = 0, + VK_COMPONENT_TYPE_FLOAT32_NV = 1, + VK_COMPONENT_TYPE_FLOAT64_NV = 2, + VK_COMPONENT_TYPE_SINT8_NV = 3, + VK_COMPONENT_TYPE_SINT16_NV = 4, + VK_COMPONENT_TYPE_SINT32_NV = 5, + VK_COMPONENT_TYPE_SINT64_NV = 6, + VK_COMPONENT_TYPE_UINT8_NV = 7, + VK_COMPONENT_TYPE_UINT16_NV = 8, + VK_COMPONENT_TYPE_UINT32_NV = 9, + VK_COMPONENT_TYPE_UINT64_NV = 10, + VK_COMPONENT_TYPE_NV_MAX_ENUM = 0x7fffffff, +} VkComponentTypeNV; + +typedef enum VkCompositeAlphaFlagBitsKHR +{ + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, + VK_COMPOSITE_ALPHA_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkCompositeAlphaFlagBitsKHR; + +typedef enum VkConditionalRenderingFlagBitsEXT +{ + VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001, + VK_CONDITIONAL_RENDERING_FLAG_BITS_EXT_MAX_ENUM = 0x7fffffff, +} VkConditionalRenderingFlagBitsEXT; + +typedef enum VkConservativeRasterizationModeEXT +{ + VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0, + VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1, + VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2, + VK_CONSERVATIVE_RASTERIZATION_MODE_EXT_MAX_ENUM = 0x7fffffff, +} VkConservativeRasterizationModeEXT; + +typedef enum VkCopyAccelerationStructureModeNV +{ + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1, + VK_COPY_ACCELERATION_STRUCTURE_MODE_NV_MAX_ENUM = 0x7fffffff, +} VkCopyAccelerationStructureModeNV; + +typedef enum VkCoverageModulationModeNV +{ + VK_COVERAGE_MODULATION_MODE_NONE_NV = 0, + VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, + VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, + VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, + VK_COVERAGE_MODULATION_MODE_NV_MAX_ENUM = 0x7fffffff, +} VkCoverageModulationModeNV; + +typedef enum VkCullModeFlagBits +{ + VK_CULL_MODE_NONE = 0, + VK_CULL_MODE_FRONT_BIT = 0x00000001, + VK_CULL_MODE_BACK_BIT = 0x00000002, + VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, + VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkCullModeFlagBits; + +typedef enum VkDependencyFlagBits +{ + VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, + VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, + VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, + VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkDependencyFlagBits; + +typedef enum VkDescriptorPoolCreateFlagBits +{ + VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002, + VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkDescriptorPoolCreateFlagBits; + +typedef enum VkDescriptorSetLayoutCreateFlagBits +{ + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkDescriptorSetLayoutCreateFlagBits; + +typedef enum VkDescriptorType +{ + VK_DESCRIPTOR_TYPE_SAMPLER = 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7fffffff, +} VkDescriptorType; + +typedef enum VkDescriptorUpdateTemplateType +{ + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7fffffff, +} VkDescriptorUpdateTemplateType; + +typedef enum VkDeviceGroupPresentModeFlagBitsKHR +{ + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 0x00000001, + VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 0x00000002, + VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 0x00000004, + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 0x00000008, + VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkDeviceGroupPresentModeFlagBitsKHR; + +typedef enum VkDeviceQueueCreateFlagBits +{ + VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001, + VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkDeviceQueueCreateFlagBits; + +typedef enum VkDiscardRectangleModeEXT +{ + VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, + VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, + VK_DISCARD_RECTANGLE_MODE_EXT_MAX_ENUM = 0x7fffffff, +} VkDiscardRectangleModeEXT; + +typedef enum VkDriverIdKHR +{ + VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1, + VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2, + VK_DRIVER_ID_MESA_RADV_KHR = 3, + VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8, + VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9, + VK_DRIVER_ID_GOOGLE_PASTEL_KHR = 10, + VK_DRIVER_ID_KHR_MAX_ENUM = 0x7fffffff, +} VkDriverIdKHR; + +typedef enum VkDynamicState +{ + VK_DYNAMIC_STATE_VIEWPORT = 0, + VK_DYNAMIC_STATE_SCISSOR = 1, + VK_DYNAMIC_STATE_LINE_WIDTH = 2, + VK_DYNAMIC_STATE_DEPTH_BIAS = 3, + VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, + VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, + VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, + VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, + VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, + VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004, + VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, + VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, + VK_DYNAMIC_STATE_MAX_ENUM = 0x7fffffff, +} VkDynamicState; + +typedef enum VkExternalFenceFeatureFlagBits +{ + VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 0x00000001, + VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkExternalFenceFeatureFlagBits; + +typedef enum VkExternalFenceHandleTypeFlagBits +{ + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000008, + VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkExternalFenceHandleTypeFlagBits; + +typedef enum VkExternalMemoryFeatureFlagBits +{ + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 0x00000001, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 0x00000004, + VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkExternalMemoryFeatureFlagBits; + +typedef enum VkExternalMemoryHandleTypeFlagBits +{ + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 0x00000008, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 0x00000010, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkExternalMemoryHandleTypeFlagBits; + +typedef enum VkExternalSemaphoreFeatureFlagBits +{ + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 0x00000001, + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkExternalSemaphoreFeatureFlagBits; + +typedef enum VkExternalSemaphoreHandleTypeFlagBits +{ + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkExternalSemaphoreHandleTypeFlagBits; + +typedef enum VkFenceCreateFlagBits +{ + VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, + VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkFenceCreateFlagBits; + +typedef enum VkFenceImportFlagBits +{ + VK_FENCE_IMPORT_TEMPORARY_BIT = 0x00000001, + VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkFenceImportFlagBits; + +typedef enum VkFilter +{ + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_CUBIC_IMG = 1000015000, + VK_FILTER_MAX_ENUM = 0x7fffffff, +} VkFilter; + +typedef enum VkFormat +{ + VK_FORMAT_UNDEFINED = 0, + VK_FORMAT_R4G4_UNORM_PACK8 = 1, + VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, + VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, + VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, + VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, + VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, + VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, + VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, + VK_FORMAT_R8_UNORM = 9, + VK_FORMAT_R8_SNORM = 10, + VK_FORMAT_R8_USCALED = 11, + VK_FORMAT_R8_SSCALED = 12, + VK_FORMAT_R8_UINT = 13, + VK_FORMAT_R8_SINT = 14, + VK_FORMAT_R8_SRGB = 15, + VK_FORMAT_R8G8_UNORM = 16, + VK_FORMAT_R8G8_SNORM = 17, + VK_FORMAT_R8G8_USCALED = 18, + VK_FORMAT_R8G8_SSCALED = 19, + VK_FORMAT_R8G8_UINT = 20, + VK_FORMAT_R8G8_SINT = 21, + VK_FORMAT_R8G8_SRGB = 22, + VK_FORMAT_R8G8B8_UNORM = 23, + VK_FORMAT_R8G8B8_SNORM = 24, + VK_FORMAT_R8G8B8_USCALED = 25, + VK_FORMAT_R8G8B8_SSCALED = 26, + VK_FORMAT_R8G8B8_UINT = 27, + VK_FORMAT_R8G8B8_SINT = 28, + VK_FORMAT_R8G8B8_SRGB = 29, + VK_FORMAT_B8G8R8_UNORM = 30, + VK_FORMAT_B8G8R8_SNORM = 31, + VK_FORMAT_B8G8R8_USCALED = 32, + VK_FORMAT_B8G8R8_SSCALED = 33, + VK_FORMAT_B8G8R8_UINT = 34, + VK_FORMAT_B8G8R8_SINT = 35, + VK_FORMAT_B8G8R8_SRGB = 36, + VK_FORMAT_R8G8B8A8_UNORM = 37, + VK_FORMAT_R8G8B8A8_SNORM = 38, + VK_FORMAT_R8G8B8A8_USCALED = 39, + VK_FORMAT_R8G8B8A8_SSCALED = 40, + VK_FORMAT_R8G8B8A8_UINT = 41, + VK_FORMAT_R8G8B8A8_SINT = 42, + VK_FORMAT_R8G8B8A8_SRGB = 43, + VK_FORMAT_B8G8R8A8_UNORM = 44, + VK_FORMAT_B8G8R8A8_SNORM = 45, + VK_FORMAT_B8G8R8A8_USCALED = 46, + VK_FORMAT_B8G8R8A8_SSCALED = 47, + VK_FORMAT_B8G8R8A8_UINT = 48, + VK_FORMAT_B8G8R8A8_SINT = 49, + VK_FORMAT_B8G8R8A8_SRGB = 50, + VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, + VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, + VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, + VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, + VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, + VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, + VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, + VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, + VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, + VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, + VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, + VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, + VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, + VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, + VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, + VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, + VK_FORMAT_R16_UNORM = 70, + VK_FORMAT_R16_SNORM = 71, + VK_FORMAT_R16_USCALED = 72, + VK_FORMAT_R16_SSCALED = 73, + VK_FORMAT_R16_UINT = 74, + VK_FORMAT_R16_SINT = 75, + VK_FORMAT_R16_SFLOAT = 76, + VK_FORMAT_R16G16_UNORM = 77, + VK_FORMAT_R16G16_SNORM = 78, + VK_FORMAT_R16G16_USCALED = 79, + VK_FORMAT_R16G16_SSCALED = 80, + VK_FORMAT_R16G16_UINT = 81, + VK_FORMAT_R16G16_SINT = 82, + VK_FORMAT_R16G16_SFLOAT = 83, + VK_FORMAT_R16G16B16_UNORM = 84, + VK_FORMAT_R16G16B16_SNORM = 85, + VK_FORMAT_R16G16B16_USCALED = 86, + VK_FORMAT_R16G16B16_SSCALED = 87, + VK_FORMAT_R16G16B16_UINT = 88, + VK_FORMAT_R16G16B16_SINT = 89, + VK_FORMAT_R16G16B16_SFLOAT = 90, + VK_FORMAT_R16G16B16A16_UNORM = 91, + VK_FORMAT_R16G16B16A16_SNORM = 92, + VK_FORMAT_R16G16B16A16_USCALED = 93, + VK_FORMAT_R16G16B16A16_SSCALED = 94, + VK_FORMAT_R16G16B16A16_UINT = 95, + VK_FORMAT_R16G16B16A16_SINT = 96, + VK_FORMAT_R16G16B16A16_SFLOAT = 97, + VK_FORMAT_R32_UINT = 98, + VK_FORMAT_R32_SINT = 99, + VK_FORMAT_R32_SFLOAT = 100, + VK_FORMAT_R32G32_UINT = 101, + VK_FORMAT_R32G32_SINT = 102, + VK_FORMAT_R32G32_SFLOAT = 103, + VK_FORMAT_R32G32B32_UINT = 104, + VK_FORMAT_R32G32B32_SINT = 105, + VK_FORMAT_R32G32B32_SFLOAT = 106, + VK_FORMAT_R32G32B32A32_UINT = 107, + VK_FORMAT_R32G32B32A32_SINT = 108, + VK_FORMAT_R32G32B32A32_SFLOAT = 109, + VK_FORMAT_R64_UINT = 110, + VK_FORMAT_R64_SINT = 111, + VK_FORMAT_R64_SFLOAT = 112, + VK_FORMAT_R64G64_UINT = 113, + VK_FORMAT_R64G64_SINT = 114, + VK_FORMAT_R64G64_SFLOAT = 115, + VK_FORMAT_R64G64B64_UINT = 116, + VK_FORMAT_R64G64B64_SINT = 117, + VK_FORMAT_R64G64B64_SFLOAT = 118, + VK_FORMAT_R64G64B64A64_UINT = 119, + VK_FORMAT_R64G64B64A64_SINT = 120, + VK_FORMAT_R64G64B64A64_SFLOAT = 121, + VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, + VK_FORMAT_D16_UNORM = 124, + VK_FORMAT_X8_D24_UNORM_PACK32 = 125, + VK_FORMAT_D32_SFLOAT = 126, + VK_FORMAT_S8_UINT = 127, + VK_FORMAT_D16_UNORM_S8_UINT = 128, + VK_FORMAT_D24_UNORM_S8_UINT = 129, + VK_FORMAT_D32_SFLOAT_S8_UINT = 130, + VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, + VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, + VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, + VK_FORMAT_BC2_UNORM_BLOCK = 135, + VK_FORMAT_BC2_SRGB_BLOCK = 136, + VK_FORMAT_BC3_UNORM_BLOCK = 137, + VK_FORMAT_BC3_SRGB_BLOCK = 138, + VK_FORMAT_BC4_UNORM_BLOCK = 139, + VK_FORMAT_BC4_SNORM_BLOCK = 140, + VK_FORMAT_BC5_UNORM_BLOCK = 141, + VK_FORMAT_BC5_SNORM_BLOCK = 142, + VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, + VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, + VK_FORMAT_BC7_UNORM_BLOCK = 145, + VK_FORMAT_BC7_SRGB_BLOCK = 146, + VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, + VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, + VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, + VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, + VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, + VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, + VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, + VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, + VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, + VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, + VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, + VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, + VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, + VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, + VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, + VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, + VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, + VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, + VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, + VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, + VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, + VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, + VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, + VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, + VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, + VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, + VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, + VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, + VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, + VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, + VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, + VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, + VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, + VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, + VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, + VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, + VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, + VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, + VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, + VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, + VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003, + VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004, + VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, + VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, + VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, + VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000, + VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006, + VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016, + VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026, + VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027, + VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_MAX_ENUM = 0x7fffffff, +} VkFormat; + +typedef enum VkFormatFeatureFlagBits +{ + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, + VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, + VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, + VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, + VK_FORMAT_FEATURE_TRANSFER_SRC_BIT = 0x00004000, + VK_FORMAT_FEATURE_TRANSFER_DST_BIT = 0x00008000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, + VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000, + VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, + VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, + VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, + VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkFormatFeatureFlagBits; + +typedef enum VkFrontFace +{ + VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_MAX_ENUM = 0x7fffffff, +} VkFrontFace; + +typedef enum VkGeometryFlagBitsNV +{ + VK_GEOMETRY_OPAQUE_BIT_NV = 0x00000001, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = 0x00000002, + VK_GEOMETRY_FLAG_BITS_NV_MAX_ENUM = 0x7fffffff, +} VkGeometryFlagBitsNV; + +typedef enum VkGeometryInstanceFlagBitsNV +{ + VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = 0x00000001, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = 0x00000004, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = 0x00000008, + VK_GEOMETRY_INSTANCE_FLAG_BITS_NV_MAX_ENUM = 0x7fffffff, +} VkGeometryInstanceFlagBitsNV; + +typedef enum VkGeometryTypeNV +{ + VK_GEOMETRY_TYPE_TRIANGLES_NV = 0, + VK_GEOMETRY_TYPE_AABBS_NV = 1, + VK_GEOMETRY_TYPE_NV_MAX_ENUM = 0x7fffffff, +} VkGeometryTypeNV; + +typedef enum VkImageAspectFlagBits +{ + VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, + VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, + VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, + VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, + VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, + VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, + VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkImageAspectFlagBits; + +typedef enum VkImageCreateFlagBits +{ + VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, + VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, + VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020, + VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040, + VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080, + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100, + VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, + VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400, + VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, + VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, + VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, + VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, + VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkImageCreateFlagBits; + +typedef enum VkImageLayout +{ + VK_IMAGE_LAYOUT_UNDEFINED = 0, + VK_IMAGE_LAYOUT_GENERAL = 1, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, + VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7fffffff, +} VkImageLayout; + +typedef enum VkImageTiling +{ + VK_IMAGE_TILING_OPTIMAL = 0, + VK_IMAGE_TILING_LINEAR = 1, + VK_IMAGE_TILING_MAX_ENUM = 0x7fffffff, +} VkImageTiling; + +typedef enum VkImageType +{ + VK_IMAGE_TYPE_1D = 0, + VK_IMAGE_TYPE_2D = 1, + VK_IMAGE_TYPE_3D = 2, + VK_IMAGE_TYPE_MAX_ENUM = 0x7fffffff, +} VkImageType; + +typedef enum VkImageUsageFlagBits +{ + VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, + VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, + VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100, + VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, + VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkImageUsageFlagBits; + +typedef enum VkImageViewCreateFlagBits +{ + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, + VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkImageViewCreateFlagBits; + +typedef enum VkImageViewType +{ + VK_IMAGE_VIEW_TYPE_1D = 0, + VK_IMAGE_VIEW_TYPE_2D = 1, + VK_IMAGE_VIEW_TYPE_3D = 2, + VK_IMAGE_VIEW_TYPE_CUBE = 3, + VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, + VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7fffffff, +} VkImageViewType; + +typedef enum VkIndexType +{ + VK_INDEX_TYPE_UINT16 = 0, + VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_NONE_NV = 1000165000, + VK_INDEX_TYPE_MAX_ENUM = 0x7fffffff, +} VkIndexType; + +typedef enum VkInternalAllocationType +{ + VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, + VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7fffffff, +} VkInternalAllocationType; + +typedef enum VkLogicOp +{ + VK_LOGIC_OP_CLEAR = 0, + VK_LOGIC_OP_AND = 1, + VK_LOGIC_OP_AND_REVERSE = 2, + VK_LOGIC_OP_COPY = 3, + VK_LOGIC_OP_AND_INVERTED = 4, + VK_LOGIC_OP_NO_OP = 5, + VK_LOGIC_OP_XOR = 6, + VK_LOGIC_OP_OR = 7, + VK_LOGIC_OP_NOR = 8, + VK_LOGIC_OP_EQUIVALENT = 9, + VK_LOGIC_OP_INVERT = 10, + VK_LOGIC_OP_OR_REVERSE = 11, + VK_LOGIC_OP_COPY_INVERTED = 12, + VK_LOGIC_OP_OR_INVERTED = 13, + VK_LOGIC_OP_NAND = 14, + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_MAX_ENUM = 0x7fffffff, +} VkLogicOp; + +typedef enum VkMemoryAllocateFlagBits +{ + VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, + VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkMemoryAllocateFlagBits; + +typedef enum VkMemoryHeapFlagBits +{ + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002, + VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkMemoryHeapFlagBits; + +typedef enum VkMemoryOverallocationBehaviorAMD +{ + VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_AMD_MAX_ENUM = 0x7fffffff, +} VkMemoryOverallocationBehaviorAMD; + +typedef enum VkMemoryPropertyFlagBits +{ + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, + VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, + VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, + VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkMemoryPropertyFlagBits; + +typedef enum VkObjectType +{ + VK_OBJECT_TYPE_UNKNOWN = 0, + VK_OBJECT_TYPE_INSTANCE = 1, + VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, + VK_OBJECT_TYPE_DEVICE = 3, + VK_OBJECT_TYPE_QUEUE = 4, + VK_OBJECT_TYPE_SEMAPHORE = 5, + VK_OBJECT_TYPE_COMMAND_BUFFER = 6, + VK_OBJECT_TYPE_FENCE = 7, + VK_OBJECT_TYPE_DEVICE_MEMORY = 8, + VK_OBJECT_TYPE_BUFFER = 9, + VK_OBJECT_TYPE_IMAGE = 10, + VK_OBJECT_TYPE_EVENT = 11, + VK_OBJECT_TYPE_QUERY_POOL = 12, + VK_OBJECT_TYPE_BUFFER_VIEW = 13, + VK_OBJECT_TYPE_IMAGE_VIEW = 14, + VK_OBJECT_TYPE_SHADER_MODULE = 15, + VK_OBJECT_TYPE_PIPELINE_CACHE = 16, + VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, + VK_OBJECT_TYPE_RENDER_PASS = 18, + VK_OBJECT_TYPE_PIPELINE = 19, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, + VK_OBJECT_TYPE_SAMPLER = 21, + VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, + VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, + VK_OBJECT_TYPE_FRAMEBUFFER = 24, + VK_OBJECT_TYPE_COMMAND_POOL = 25, + VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, + VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, + VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, + VK_OBJECT_TYPE_MAX_ENUM = 0x7fffffff, +} VkObjectType; + +typedef enum VkPeerMemoryFeatureFlagBits +{ + VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 0x00000001, + VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 0x00000002, + VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 0x00000004, + VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 0x00000008, + VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkPeerMemoryFeatureFlagBits; + +typedef enum VkPhysicalDeviceType +{ + VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, + VK_PHYSICAL_DEVICE_TYPE_CPU = 4, + VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7fffffff, +} VkPhysicalDeviceType; + +typedef enum VkPipelineBindPoint +{ + VK_PIPELINE_BIND_POINT_GRAPHICS = 0, + VK_PIPELINE_BIND_POINT_COMPUTE = 1, + VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = 1000165000, + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7fffffff, +} VkPipelineBindPoint; + +typedef enum VkPipelineCacheHeaderVersion +{ + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7fffffff, +} VkPipelineCacheHeaderVersion; + +typedef enum VkPipelineCreateFlagBits +{ + VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, + VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, + VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, + VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, + VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010, + VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, + VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkPipelineCreateFlagBits; + +typedef enum VkPipelineStageFlagBits +{ + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, + VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, + VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, + VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, + VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, + VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = 0x00200000, + VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000, + VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000, + VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkPipelineStageFlagBits; + +typedef enum VkPointClippingBehavior +{ + VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, + VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, + VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7fffffff, +} VkPointClippingBehavior; + +typedef enum VkPolygonMode +{ + VK_POLYGON_MODE_FILL = 0, + VK_POLYGON_MODE_LINE = 1, + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, + VK_POLYGON_MODE_MAX_ENUM = 0x7fffffff, +} VkPolygonMode; + +typedef enum VkPresentModeKHR +{ + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_KHR_MAX_ENUM = 0x7fffffff, +} VkPresentModeKHR; + +typedef enum VkPrimitiveTopology +{ + VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7fffffff, +} VkPrimitiveTopology; + +typedef enum VkQueryControlFlagBits +{ + VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, + VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkQueryControlFlagBits; + +typedef enum VkQueryPipelineStatisticFlagBits +{ + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, + VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, + VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, + VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, + VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkQueryPipelineStatisticFlagBits; + +typedef enum VkQueryResultFlagBits +{ + VK_QUERY_RESULT_64_BIT = 0x00000001, + VK_QUERY_RESULT_WAIT_BIT = 0x00000002, + VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, + VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, + VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkQueryResultFlagBits; + +typedef enum VkQueryType +{ + VK_QUERY_TYPE_OCCLUSION = 0, + VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, + VK_QUERY_TYPE_TIMESTAMP = 2, + VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, + VK_QUERY_TYPE_MAX_ENUM = 0x7fffffff, +} VkQueryType; + +typedef enum VkQueueFlagBits +{ + VK_QUEUE_GRAPHICS_BIT = 0x00000001, + VK_QUEUE_COMPUTE_BIT = 0x00000002, + VK_QUEUE_TRANSFER_BIT = 0x00000004, + VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, + VK_QUEUE_PROTECTED_BIT = 0x00000010, + VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkQueueFlagBits; + +typedef enum VkQueueGlobalPriorityEXT +{ + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, + VK_QUEUE_GLOBAL_PRIORITY_EXT_MAX_ENUM = 0x7fffffff, +} VkQueueGlobalPriorityEXT; + +typedef enum VkRasterizationOrderAMD +{ + VK_RASTERIZATION_ORDER_STRICT_AMD = 0, + VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, + VK_RASTERIZATION_ORDER_AMD_MAX_ENUM = 0x7fffffff, +} VkRasterizationOrderAMD; + +typedef enum VkRayTracingShaderGroupTypeNV +{ + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = 0, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = 1, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = 2, + VK_RAY_TRACING_SHADER_GROUP_TYPE_NV_MAX_ENUM = 0x7fffffff, +} VkRayTracingShaderGroupTypeNV; + +typedef enum VkResolveModeFlagBitsKHR +{ + VK_RESOLVE_MODE_NONE_KHR = 0, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = 0x00000001, + VK_RESOLVE_MODE_AVERAGE_BIT_KHR = 0x00000002, + VK_RESOLVE_MODE_MIN_BIT_KHR = 0x00000004, + VK_RESOLVE_MODE_MAX_BIT_KHR = 0x00000008, + VK_RESOLVE_MODE_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkResolveModeFlagBitsKHR; + +typedef enum VkResult +{ + VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = -1000244000, + VK_ERROR_NOT_PERMITTED_EXT = -1000174001, + VK_ERROR_FRAGMENTATION_EXT = -1000161000, + VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, + VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, + VK_ERROR_INVALID_SHADER_NV = -1000012000, + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, + VK_ERROR_SURFACE_LOST_KHR = -1000000000, + VK_ERROR_FRAGMENTED_POOL = -12, + VK_ERROR_FORMAT_NOT_SUPPORTED = -11, + VK_ERROR_TOO_MANY_OBJECTS = -10, + VK_ERROR_INCOMPATIBLE_DRIVER = -9, + VK_ERROR_FEATURE_NOT_PRESENT = -8, + VK_ERROR_EXTENSION_NOT_PRESENT = -7, + VK_ERROR_LAYER_NOT_PRESENT = -6, + VK_ERROR_MEMORY_MAP_FAILED = -5, + VK_ERROR_DEVICE_LOST = -4, + VK_ERROR_INITIALIZATION_FAILED = -3, + VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, + VK_ERROR_OUT_OF_HOST_MEMORY = -1, + VK_SUCCESS = 0, + VK_NOT_READY = 1, + VK_TIMEOUT = 2, + VK_EVENT_SET = 3, + VK_EVENT_RESET = 4, + VK_INCOMPLETE = 5, + VK_SUBOPTIMAL_KHR = 1000001003, + VK_RESULT_MAX_ENUM = 0x7fffffff, +} VkResult; + +typedef enum VkSampleCountFlagBits +{ + VK_SAMPLE_COUNT_1_BIT = 0x00000001, + VK_SAMPLE_COUNT_2_BIT = 0x00000002, + VK_SAMPLE_COUNT_4_BIT = 0x00000004, + VK_SAMPLE_COUNT_8_BIT = 0x00000008, + VK_SAMPLE_COUNT_16_BIT = 0x00000010, + VK_SAMPLE_COUNT_32_BIT = 0x00000020, + VK_SAMPLE_COUNT_64_BIT = 0x00000040, + VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSampleCountFlagBits; + +typedef enum VkSamplerAddressMode +{ + VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7fffffff, +} VkSamplerAddressMode; + +typedef enum VkSamplerCreateFlagBits +{ + VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, + VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, + VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSamplerCreateFlagBits; + +typedef enum VkSamplerMipmapMode +{ + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7fffffff, +} VkSamplerMipmapMode; + +typedef enum VkSamplerReductionModeEXT +{ + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0, + VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1, + VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2, + VK_SAMPLER_REDUCTION_MODE_EXT_MAX_ENUM = 0x7fffffff, +} VkSamplerReductionModeEXT; + +typedef enum VkSamplerYcbcrModelConversion +{ + VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7fffffff, +} VkSamplerYcbcrModelConversion; + +typedef enum VkSamplerYcbcrRange +{ + VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, + VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, + VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7fffffff, +} VkSamplerYcbcrRange; + +typedef enum VkScopeNV +{ + VK_SCOPE_DEVICE_NV = 1, + VK_SCOPE_WORKGROUP_NV = 2, + VK_SCOPE_SUBGROUP_NV = 3, + VK_SCOPE_QUEUE_FAMILY_NV = 5, + VK_SCOPE_NV_MAX_ENUM = 0x7fffffff, +} VkScopeNV; + +typedef enum VkSemaphoreImportFlagBits +{ + VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 0x00000001, + VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSemaphoreImportFlagBits; + +typedef enum VkShaderInfoTypeAMD +{ + VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0, + VK_SHADER_INFO_TYPE_BINARY_AMD = 1, + VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2, + VK_SHADER_INFO_TYPE_AMD_MAX_ENUM = 0x7fffffff, +} VkShaderInfoTypeAMD; + +typedef enum VkShaderStageFlagBits +{ + VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, + VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, + VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, + VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001f, + VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, + VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040, + VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080, + VK_SHADER_STAGE_RAYGEN_BIT_NV = 0x00000100, + VK_SHADER_STAGE_ANY_HIT_BIT_NV = 0x00000200, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = 0x00000400, + VK_SHADER_STAGE_MISS_BIT_NV = 0x00000800, + VK_SHADER_STAGE_INTERSECTION_BIT_NV = 0x00001000, + VK_SHADER_STAGE_CALLABLE_BIT_NV = 0x00002000, + VK_SHADER_STAGE_ALL = 0x7fffffff, + VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkShaderStageFlagBits; + +typedef enum VkShadingRatePaletteEntryNV +{ + VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0, + VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1, + VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2, + VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3, + VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11, + VK_SHADING_RATE_PALETTE_ENTRY_NV_MAX_ENUM = 0x7fffffff, +} VkShadingRatePaletteEntryNV; + +typedef enum VkSharingMode +{ + VK_SHARING_MODE_EXCLUSIVE = 0, + VK_SHARING_MODE_CONCURRENT = 1, + VK_SHARING_MODE_MAX_ENUM = 0x7fffffff, +} VkSharingMode; + +typedef enum VkSparseImageFormatFlagBits +{ + VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, + VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, + VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, + VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSparseImageFormatFlagBits; + +typedef enum VkSparseMemoryBindFlagBits +{ + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSparseMemoryBindFlagBits; + +typedef enum VkStencilFaceFlagBits +{ + VK_STENCIL_FACE_FRONT_BIT = 0x00000001, + VK_STENCIL_FACE_BACK_BIT = 0x00000002, + VK_STENCIL_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkStencilFaceFlagBits; + +typedef enum VkStencilOp +{ + VK_STENCIL_OP_KEEP = 0, + VK_STENCIL_OP_ZERO = 1, + VK_STENCIL_OP_REPLACE = 2, + VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, + VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, + VK_STENCIL_OP_INVERT = 5, + VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_MAX_ENUM = 0x7fffffff, +} VkStencilOp; + +typedef enum VkStructureType +{ + VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, + VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, + VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, + VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, + VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, + VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, + VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, + VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, + VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, + VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, + VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, + VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005, + VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, + VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, + VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, + VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, + VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = 1000063000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, + VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, + VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, + VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, + VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, + VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = 1000082000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, + VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, + VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, + VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, + VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001, + VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, + VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, + VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = 1000120000, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, + VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, + VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, + VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, + VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, + VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, + VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, + VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, + VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, + VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001, + VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, + VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, + VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003, + VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004, + VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005, + VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, + VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, + VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, + VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, + VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, + VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, + VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = 1000244000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = 1000244001, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, + VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = 1000261000, + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7fffffff, +} VkStructureType; + +typedef enum VkSubgroupFeatureFlagBits +{ + VK_SUBGROUP_FEATURE_BASIC_BIT = 0x00000001, + VK_SUBGROUP_FEATURE_VOTE_BIT = 0x00000002, + VK_SUBGROUP_FEATURE_ARITHMETIC_BIT = 0x00000004, + VK_SUBGROUP_FEATURE_BALLOT_BIT = 0x00000008, + VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 0x00000010, + VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020, + VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040, + VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080, + VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100, + VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSubgroupFeatureFlagBits; + +typedef enum VkSubpassContents +{ + VK_SUBPASS_CONTENTS_INLINE = 0, + VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, + VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7fffffff, +} VkSubpassContents; + +typedef enum VkSubpassDescriptionFlagBits +{ + VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkSubpassDescriptionFlagBits; + +typedef enum VkSurfaceTransformFlagBitsKHR +{ + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, + VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, + VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, + VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, + VK_SURFACE_TRANSFORM_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkSurfaceTransformFlagBitsKHR; + +typedef enum VkSwapchainCreateFlagBitsKHR +{ + VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, + VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, + VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, + VK_SWAPCHAIN_CREATE_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkSwapchainCreateFlagBitsKHR; + +typedef enum VkSystemAllocationScope +{ + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, + VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, + VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7fffffff, +} VkSystemAllocationScope; + +typedef enum VkTessellationDomainOrigin +{ + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, + VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7fffffff, +} VkTessellationDomainOrigin; + +typedef enum VkValidationCacheHeaderVersionEXT +{ + VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, + VK_VALIDATION_CACHE_HEADER_VERSION_EXT_MAX_ENUM = 0x7fffffff, +} VkValidationCacheHeaderVersionEXT; + +typedef enum VkVendorId +{ + VK_VENDOR_ID_VIV = 0x00010001, + VK_VENDOR_ID_VSI = 0x00010002, + VK_VENDOR_ID_KAZAN = 0x00010003, + VK_VENDOR_ID_MAX_ENUM = 0x7fffffff, +} VkVendorId; + +typedef enum VkVertexInputRate +{ + VK_VERTEX_INPUT_RATE_VERTEX = 0, + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7fffffff, +} VkVertexInputRate; + +typedef enum VkViewportCoordinateSwizzleNV +{ + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, + VK_VIEWPORT_COORDINATE_SWIZZLE_NV_MAX_ENUM = 0x7fffffff, +} VkViewportCoordinateSwizzleNV; + +typedef void* (VKAPI_PTR * PFN_vkAllocationFunction)( + void *pUserData, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); +typedef void (VKAPI_PTR * PFN_vkFreeFunction)( + void *pUserData, + void *pMemory); +typedef void (VKAPI_PTR * PFN_vkInternalAllocationNotification)( + void *pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); +typedef void (VKAPI_PTR * PFN_vkInternalFreeNotification)( + void *pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); +typedef void* (VKAPI_PTR * PFN_vkReallocationFunction)( + void *pUserData, + void *pOriginal, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); +typedef void (VKAPI_PTR * PFN_vkVoidFunction)( +void); + +typedef struct VkAccelerationStructureMemoryRequirementsInfoNV +{ + VkStructureType sType; + const void *pNext; + VkAccelerationStructureMemoryRequirementsTypeNV type; + VkAccelerationStructureNV WINE_VK_ALIGN(8) accelerationStructure; +} VkAccelerationStructureMemoryRequirementsInfoNV; + +typedef struct VkAllocationCallbacks +{ + void *pUserData; + PFN_vkAllocationFunction pfnAllocation; + PFN_vkReallocationFunction pfnReallocation; + PFN_vkFreeFunction pfnFree; + PFN_vkInternalAllocationNotification pfnInternalAllocation; + PFN_vkInternalFreeNotification pfnInternalFree; +} VkAllocationCallbacks; + +typedef struct VkAttachmentDescription +{ + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription; + +typedef struct VkAttachmentReference +{ + uint32_t attachment; + VkImageLayout layout; +} VkAttachmentReference; + +typedef struct VkBaseInStructure +{ + VkStructureType sType; + const struct VkBaseInStructure *pNext; +} VkBaseInStructure; + +typedef struct VkBindAccelerationStructureMemoryInfoNV +{ + VkStructureType sType; + const void *pNext; + VkAccelerationStructureNV WINE_VK_ALIGN(8) accelerationStructure; + VkDeviceMemory WINE_VK_ALIGN(8) memory; + VkDeviceSize WINE_VK_ALIGN(8) memoryOffset; + uint32_t deviceIndexCount; + const uint32_t *pDeviceIndices; +} VkBindAccelerationStructureMemoryInfoNV; + +typedef struct VkBindImagePlaneMemoryInfo +{ + VkStructureType sType; + const void *pNext; + VkImageAspectFlagBits planeAspect; +} VkBindImagePlaneMemoryInfo; + +typedef struct VkBufferCopy +{ + VkDeviceSize WINE_VK_ALIGN(8) srcOffset; + VkDeviceSize WINE_VK_ALIGN(8) dstOffset; + VkDeviceSize WINE_VK_ALIGN(8) size; +} VkBufferCopy; + +typedef struct VkBufferDeviceAddressCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkDeviceAddress deviceAddress; +} VkBufferDeviceAddressCreateInfoEXT; + +typedef struct VkBufferMemoryBarrier +{ + VkStructureType sType; + const void *pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer WINE_VK_ALIGN(8) buffer; + VkDeviceSize WINE_VK_ALIGN(8) offset; + VkDeviceSize WINE_VK_ALIGN(8) size; +} VkBufferMemoryBarrier; + +typedef union VkClearColorValue +{ + float float32[4]; + int32_t int32[4]; + uint32_t uint32[4]; +} VkClearColorValue; + +typedef struct VkCoarseSampleLocationNV +{ + uint32_t pixelX; + uint32_t pixelY; + uint32_t sample; +} VkCoarseSampleLocationNV; + +typedef struct VkCommandBufferAllocateInfo +{ + VkStructureType sType; + const void *pNext; + VkCommandPool WINE_VK_ALIGN(8) commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo; + +typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkBool32 conditionalRenderingEnable; +} VkCommandBufferInheritanceConditionalRenderingInfoEXT; + +typedef struct VkCommandPoolCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkCommandPoolCreateFlags flags; + uint32_t queueFamilyIndex; +} VkCommandPoolCreateInfo; + +typedef struct VkConditionalRenderingBeginInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkBuffer WINE_VK_ALIGN(8) buffer; + VkDeviceSize WINE_VK_ALIGN(8) offset; + VkConditionalRenderingFlagsEXT flags; +} VkConditionalRenderingBeginInfoEXT; + +typedef struct VkCooperativeMatrixPropertiesNV +{ + VkStructureType sType; + void *pNext; + uint32_t MSize; + uint32_t NSize; + uint32_t KSize; + VkComponentTypeNV AType; + VkComponentTypeNV BType; + VkComponentTypeNV CType; + VkComponentTypeNV DType; + VkScopeNV scope; +} VkCooperativeMatrixPropertiesNV; + +typedef struct VkDedicatedAllocationBufferCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkBool32 dedicatedAllocation; +} VkDedicatedAllocationBufferCreateInfoNV; + +typedef struct VkDedicatedAllocationMemoryAllocateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkImage WINE_VK_ALIGN(8) image; + VkBuffer WINE_VK_ALIGN(8) buffer; +} VkDedicatedAllocationMemoryAllocateInfoNV; + +typedef struct VkDescriptorImageInfo +{ + VkSampler WINE_VK_ALIGN(8) sampler; + VkImageView WINE_VK_ALIGN(8) imageView; + VkImageLayout imageLayout; +} VkDescriptorImageInfo; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfoEXT; + +typedef struct VkDescriptorSetAllocateInfo +{ + VkStructureType sType; + const void *pNext; + VkDescriptorPool WINE_VK_ALIGN(8) descriptorPool; + uint32_t descriptorSetCount; + const VkDescriptorSetLayout *pSetLayouts; +} VkDescriptorSetAllocateInfo; + +typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + uint32_t bindingCount; + const VkDescriptorBindingFlagsEXT *pBindingFlags; +} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; + +typedef struct VkDescriptorSetLayoutSupport +{ + VkStructureType sType; + void *pNext; + VkBool32 supported; +} VkDescriptorSetLayoutSupport; + +typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT +{ + VkStructureType sType; + const void *pNext; + uint32_t descriptorSetCount; + const uint32_t *pDescriptorCounts; +} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; + +typedef struct VkDeviceGroupPresentInfoKHR +{ + VkStructureType sType; + const void *pNext; + uint32_t swapchainCount; + const uint32_t *pDeviceMasks; + VkDeviceGroupPresentModeFlagBitsKHR mode; +} VkDeviceGroupPresentInfoKHR; + +typedef struct VkDeviceMemoryOverallocationCreateInfoAMD +{ + VkStructureType sType; + const void *pNext; + VkMemoryOverallocationBehaviorAMD overallocationBehavior; +} VkDeviceMemoryOverallocationCreateInfoAMD; + +typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkQueueGlobalPriorityEXT globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfoEXT; + +typedef struct VkDispatchIndirectCommand +{ + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkDrawIndirectCommand +{ + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +} VkDrawIndirectCommand; + +typedef struct VkEventCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo; + +typedef struct VkExportMemoryAllocateInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExportMemoryAllocateInfo; + +typedef struct VkExtensionProperties +{ + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; +} VkExtensionProperties; + +typedef struct VkExtent3D +{ + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D; + +typedef struct VkExternalMemoryBufferCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryBufferCreateInfo; + +typedef struct VkExternalMemoryImageCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryImageCreateInfo; + +typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 filterCubic; + VkBool32 filterCubicMinmax; +} VkFilterCubicImageViewImageFormatPropertiesEXT; + +typedef struct VkGeometryAABBNV +{ + VkStructureType sType; + const void *pNext; + VkBuffer WINE_VK_ALIGN(8) aabbData; + uint32_t numAABBs; + uint32_t stride; + VkDeviceSize WINE_VK_ALIGN(8) offset; +} VkGeometryAABBNV; + +typedef struct VkGeometryTrianglesNV +{ + VkStructureType sType; + const void *pNext; + VkBuffer WINE_VK_ALIGN(8) vertexData; + VkDeviceSize WINE_VK_ALIGN(8) vertexOffset; + uint32_t vertexCount; + VkDeviceSize WINE_VK_ALIGN(8) vertexStride; + VkFormat vertexFormat; + VkBuffer WINE_VK_ALIGN(8) indexData; + VkDeviceSize WINE_VK_ALIGN(8) indexOffset; + uint32_t indexCount; + VkIndexType indexType; + VkBuffer WINE_VK_ALIGN(8) transformData; + VkDeviceSize WINE_VK_ALIGN(8) transformOffset; +} VkGeometryTrianglesNV; + +typedef struct VkImageCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkImageCreateFlags flags; + VkImageType imageType; + VkFormat format; + VkExtent3D extent; + uint32_t mipLevels; + uint32_t arrayLayers; + VkSampleCountFlagBits samples; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t *pQueueFamilyIndices; + VkImageLayout initialLayout; +} VkImageCreateInfo; + +typedef struct VkImageFormatListCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + uint32_t viewFormatCount; + const VkFormat *pViewFormats; +} VkImageFormatListCreateInfoKHR; + +typedef struct VkImageMemoryRequirementsInfo2 +{ + VkStructureType sType; + const void *pNext; + VkImage WINE_VK_ALIGN(8) image; +} VkImageMemoryRequirementsInfo2; + +typedef struct VkImageSparseMemoryRequirementsInfo2 +{ + VkStructureType sType; + const void *pNext; + VkImage WINE_VK_ALIGN(8) image; +} VkImageSparseMemoryRequirementsInfo2; + +typedef struct VkImageStencilUsageCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkImageUsageFlags stencilUsage; +} VkImageStencilUsageCreateInfoEXT; + +typedef struct VkImageSubresourceLayers +{ + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceLayers; + +typedef struct VkImageSwapchainCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkSwapchainKHR WINE_VK_ALIGN(8) swapchain; +} VkImageSwapchainCreateInfoKHR; + +typedef struct VkLayerProperties +{ + char layerName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; + uint32_t implementationVersion; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkLayerProperties; + +typedef struct VkMappedMemoryRange +{ + VkStructureType sType; + const void *pNext; + VkDeviceMemory WINE_VK_ALIGN(8) memory; + VkDeviceSize WINE_VK_ALIGN(8) offset; + VkDeviceSize WINE_VK_ALIGN(8) size; +} VkMappedMemoryRange; + +typedef struct VkMemoryBarrier +{ + VkStructureType sType; + const void *pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkMemoryHostPointerPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t memoryTypeBits; +} VkMemoryHostPointerPropertiesEXT; + +typedef struct VkMemoryRequirements +{ + VkDeviceSize WINE_VK_ALIGN(8) size; + VkDeviceSize WINE_VK_ALIGN(8) alignment; + uint32_t memoryTypeBits; +} VkMemoryRequirements; + +typedef struct VkMemoryRequirements2KHR +{ + VkStructureType sType; + void *pNext; + VkMemoryRequirements WINE_VK_ALIGN(8) memoryRequirements; +} VkMemoryRequirements2KHR; + +typedef struct VkOffset2D +{ + int32_t x; + int32_t y; +} VkOffset2D; + +typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 decodeModeSharedExponent; +} VkPhysicalDeviceASTCDecodeFeaturesEXT; + +typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t advancedBlendMaxColorAttachments; + VkBool32 advancedBlendIndependentBlend; + VkBool32 advancedBlendNonPremultipliedSrcColor; + VkBool32 advancedBlendNonPremultipliedDstColor; + VkBool32 advancedBlendCorrelatedOverlap; + VkBool32 advancedBlendAllOperations; +} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT; + +typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 computeDerivativeGroupQuads; + VkBool32 computeDerivativeGroupLinear; +} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV; + +typedef struct VkPhysicalDeviceConservativeRasterizationPropertiesEXT +{ + VkStructureType sType; + void *pNext; + float primitiveOverestimationSize; + float maxExtraPrimitiveOverestimationSize; + float extraPrimitiveOverestimationSizeGranularity; + VkBool32 primitiveUnderestimation; + VkBool32 conservativePointAndLineRasterization; + VkBool32 degenerateTrianglesRasterized; + VkBool32 degenerateLinesRasterized; + VkBool32 fullyCoveredFragmentShaderInputVariable; + VkBool32 conservativeRasterizationPostDepthCoverage; +} VkPhysicalDeviceConservativeRasterizationPropertiesEXT; + +typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesNV +{ + VkStructureType sType; + void *pNext; + VkShaderStageFlags cooperativeMatrixSupportedStages; +} VkPhysicalDeviceCooperativeMatrixPropertiesNV; + +typedef struct VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 dedicatedAllocationImageAliasing; +} VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV; + +typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR +{ + VkStructureType sType; + void *pNext; + VkResolveModeFlagsKHR supportedDepthResolveModes; + VkResolveModeFlagsKHR supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; +} VkPhysicalDeviceDepthStencilResolvePropertiesKHR; + +typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; +} VkPhysicalDeviceDescriptorIndexingPropertiesEXT; + +typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 exclusiveScissor; +} VkPhysicalDeviceExclusiveScissorFeaturesNV; + +typedef struct VkPhysicalDeviceExternalSemaphoreInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalSemaphoreInfo; + +typedef struct VkPhysicalDeviceFeatures +{ + VkBool32 robustBufferAccess; + VkBool32 fullDrawIndexUint32; + VkBool32 imageCubeArray; + VkBool32 independentBlend; + VkBool32 geometryShader; + VkBool32 tessellationShader; + VkBool32 sampleRateShading; + VkBool32 dualSrcBlend; + VkBool32 logicOp; + VkBool32 multiDrawIndirect; + VkBool32 drawIndirectFirstInstance; + VkBool32 depthClamp; + VkBool32 depthBiasClamp; + VkBool32 fillModeNonSolid; + VkBool32 depthBounds; + VkBool32 wideLines; + VkBool32 largePoints; + VkBool32 alphaToOne; + VkBool32 multiViewport; + VkBool32 samplerAnisotropy; + VkBool32 textureCompressionETC2; + VkBool32 textureCompressionASTC_LDR; + VkBool32 textureCompressionBC; + VkBool32 occlusionQueryPrecise; + VkBool32 pipelineStatisticsQuery; + VkBool32 vertexPipelineStoresAndAtomics; + VkBool32 fragmentStoresAndAtomics; + VkBool32 shaderTessellationAndGeometryPointSize; + VkBool32 shaderImageGatherExtended; + VkBool32 shaderStorageImageExtendedFormats; + VkBool32 shaderStorageImageMultisample; + VkBool32 shaderStorageImageReadWithoutFormat; + VkBool32 shaderStorageImageWriteWithoutFormat; + VkBool32 shaderUniformBufferArrayDynamicIndexing; + VkBool32 shaderSampledImageArrayDynamicIndexing; + VkBool32 shaderStorageBufferArrayDynamicIndexing; + VkBool32 shaderStorageImageArrayDynamicIndexing; + VkBool32 shaderClipDistance; + VkBool32 shaderCullDistance; + VkBool32 shaderFloat64; + VkBool32 shaderInt64; + VkBool32 shaderInt16; + VkBool32 shaderResourceResidency; + VkBool32 shaderResourceMinLod; + VkBool32 sparseBinding; + VkBool32 sparseResidencyBuffer; + VkBool32 sparseResidencyImage2D; + VkBool32 sparseResidencyImage3D; + VkBool32 sparseResidency2Samples; + VkBool32 sparseResidency4Samples; + VkBool32 sparseResidency8Samples; + VkBool32 sparseResidency16Samples; + VkBool32 sparseResidencyAliased; + VkBool32 variableMultisampleRate; + VkBool32 inheritedQueries; +} VkPhysicalDeviceFeatures; + +typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR +{ + VkStructureType sType; + void *pNext; + VkBool32 separateDenormSettings; + VkBool32 separateRoundingModeSettings; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; +} VkPhysicalDeviceFloatControlsPropertiesKHR; + +typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 fragmentShaderBarycentric; +} VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV; + +typedef struct VkPhysicalDeviceIDProperties +{ + VkStructureType sType; + void *pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; +} VkPhysicalDeviceIDProperties; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeaturesEXT; + +typedef struct VkPhysicalDeviceLimits +{ + uint32_t maxImageDimension1D; + uint32_t maxImageDimension2D; + uint32_t maxImageDimension3D; + uint32_t maxImageDimensionCube; + uint32_t maxImageArrayLayers; + uint32_t maxTexelBufferElements; + uint32_t maxUniformBufferRange; + uint32_t maxStorageBufferRange; + uint32_t maxPushConstantsSize; + uint32_t maxMemoryAllocationCount; + uint32_t maxSamplerAllocationCount; + VkDeviceSize WINE_VK_ALIGN(8) bufferImageGranularity; + VkDeviceSize WINE_VK_ALIGN(8) sparseAddressSpaceSize; + uint32_t maxBoundDescriptorSets; + uint32_t maxPerStageDescriptorSamplers; + uint32_t maxPerStageDescriptorUniformBuffers; + uint32_t maxPerStageDescriptorStorageBuffers; + uint32_t maxPerStageDescriptorSampledImages; + uint32_t maxPerStageDescriptorStorageImages; + uint32_t maxPerStageDescriptorInputAttachments; + uint32_t maxPerStageResources; + uint32_t maxDescriptorSetSamplers; + uint32_t maxDescriptorSetUniformBuffers; + uint32_t maxDescriptorSetUniformBuffersDynamic; + uint32_t maxDescriptorSetStorageBuffers; + uint32_t maxDescriptorSetStorageBuffersDynamic; + uint32_t maxDescriptorSetSampledImages; + uint32_t maxDescriptorSetStorageImages; + uint32_t maxDescriptorSetInputAttachments; + uint32_t maxVertexInputAttributes; + uint32_t maxVertexInputBindings; + uint32_t maxVertexInputAttributeOffset; + uint32_t maxVertexInputBindingStride; + uint32_t maxVertexOutputComponents; + uint32_t maxTessellationGenerationLevel; + uint32_t maxTessellationPatchSize; + uint32_t maxTessellationControlPerVertexInputComponents; + uint32_t maxTessellationControlPerVertexOutputComponents; + uint32_t maxTessellationControlPerPatchOutputComponents; + uint32_t maxTessellationControlTotalOutputComponents; + uint32_t maxTessellationEvaluationInputComponents; + uint32_t maxTessellationEvaluationOutputComponents; + uint32_t maxGeometryShaderInvocations; + uint32_t maxGeometryInputComponents; + uint32_t maxGeometryOutputComponents; + uint32_t maxGeometryOutputVertices; + uint32_t maxGeometryTotalOutputComponents; + uint32_t maxFragmentInputComponents; + uint32_t maxFragmentOutputAttachments; + uint32_t maxFragmentDualSrcAttachments; + uint32_t maxFragmentCombinedOutputResources; + uint32_t maxComputeSharedMemorySize; + uint32_t maxComputeWorkGroupCount[3]; + uint32_t maxComputeWorkGroupInvocations; + uint32_t maxComputeWorkGroupSize[3]; + uint32_t subPixelPrecisionBits; + uint32_t subTexelPrecisionBits; + uint32_t mipmapPrecisionBits; + uint32_t maxDrawIndexedIndexValue; + uint32_t maxDrawIndirectCount; + float maxSamplerLodBias; + float maxSamplerAnisotropy; + uint32_t maxViewports; + uint32_t maxViewportDimensions[2]; + float viewportBoundsRange[2]; + uint32_t viewportSubPixelBits; + size_t minMemoryMapAlignment; + VkDeviceSize WINE_VK_ALIGN(8) minTexelBufferOffsetAlignment; + VkDeviceSize WINE_VK_ALIGN(8) minUniformBufferOffsetAlignment; + VkDeviceSize WINE_VK_ALIGN(8) minStorageBufferOffsetAlignment; + int32_t minTexelOffset; + uint32_t maxTexelOffset; + int32_t minTexelGatherOffset; + uint32_t maxTexelGatherOffset; + float minInterpolationOffset; + float maxInterpolationOffset; + uint32_t subPixelInterpolationOffsetBits; + uint32_t maxFramebufferWidth; + uint32_t maxFramebufferHeight; + uint32_t maxFramebufferLayers; + VkSampleCountFlags framebufferColorSampleCounts; + VkSampleCountFlags framebufferDepthSampleCounts; + VkSampleCountFlags framebufferStencilSampleCounts; + VkSampleCountFlags framebufferNoAttachmentsSampleCounts; + uint32_t maxColorAttachments; + VkSampleCountFlags sampledImageColorSampleCounts; + VkSampleCountFlags sampledImageIntegerSampleCounts; + VkSampleCountFlags sampledImageDepthSampleCounts; + VkSampleCountFlags sampledImageStencilSampleCounts; + VkSampleCountFlags storageImageSampleCounts; + uint32_t maxSampleMaskWords; + VkBool32 timestampComputeAndGraphics; + float timestampPeriod; + uint32_t maxClipDistances; + uint32_t maxCullDistances; + uint32_t maxCombinedClipAndCullDistances; + uint32_t discreteQueuePriorities; + float pointSizeRange[2]; + float lineWidthRange[2]; + float pointSizeGranularity; + float lineWidthGranularity; + VkBool32 strictLines; + VkBool32 standardSampleLocations; + VkDeviceSize WINE_VK_ALIGN(8) optimalBufferCopyOffsetAlignment; + VkDeviceSize WINE_VK_ALIGN(8) optimalBufferCopyRowPitchAlignment; + VkDeviceSize WINE_VK_ALIGN(8) nonCoherentAtomSize; +} VkPhysicalDeviceLimits; + +typedef struct VkPhysicalDeviceMemoryPriorityFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 memoryPriority; +} VkPhysicalDeviceMemoryPriorityFeaturesEXT; + +typedef struct VkPhysicalDeviceMeshShaderPropertiesNV +{ + VkStructureType sType; + void *pNext; + uint32_t maxDrawMeshTasksCount; + uint32_t maxTaskWorkGroupInvocations; + uint32_t maxTaskWorkGroupSize[3]; + uint32_t maxTaskTotalMemorySize; + uint32_t maxTaskOutputCount; + uint32_t maxMeshWorkGroupInvocations; + uint32_t maxMeshWorkGroupSize[3]; + uint32_t maxMeshTotalMemorySize; + uint32_t maxMeshOutputVertices; + uint32_t maxMeshOutputPrimitives; + uint32_t maxMeshMultiviewViewCount; + uint32_t meshOutputPerVertexGranularity; + uint32_t meshOutputPerPrimitiveGranularity; +} VkPhysicalDeviceMeshShaderPropertiesNV; + +typedef struct VkPhysicalDeviceMultiviewProperties +{ + VkStructureType sType; + void *pNext; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; +} VkPhysicalDeviceMultiviewProperties; + +typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t pciDomain; + uint32_t pciBus; + uint32_t pciDevice; + uint32_t pciFunction; +} VkPhysicalDevicePCIBusInfoPropertiesEXT; + +typedef struct VkPhysicalDeviceProtectedMemoryProperties +{ + VkStructureType sType; + void *pNext; + VkBool32 protectedNoFault; +} VkPhysicalDeviceProtectedMemoryProperties; + +typedef struct VkPhysicalDeviceRayTracingPropertiesNV +{ + VkStructureType sType; + void *pNext; + uint32_t shaderGroupHandleSize; + uint32_t maxRecursionDepth; + uint32_t maxShaderGroupStride; + uint32_t shaderGroupBaseAlignment; + uint64_t WINE_VK_ALIGN(8) maxGeometryCount; + uint64_t WINE_VK_ALIGN(8) maxInstanceCount; + uint64_t WINE_VK_ALIGN(8) maxTriangleCount; + uint32_t maxDescriptorSetAccelerationStructures; +} VkPhysicalDeviceRayTracingPropertiesNV; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; + +typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR +{ + VkStructureType sType; + void *pNext; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; +} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + +typedef struct VkPhysicalDeviceShaderDrawParameterFeatures +{ + VkStructureType sType; + void *pNext; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceShaderDrawParameterFeatures; + +typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 shadingRateImage; + VkBool32 shadingRateCoarseSampleOrder; +} VkPhysicalDeviceShadingRateImageFeaturesNV; + +typedef struct VkPhysicalDeviceSparseImageFormatInfo2 +{ + VkStructureType sType; + const void *pNext; + VkFormat format; + VkImageType type; + VkSampleCountFlagBits samples; + VkImageUsageFlags usage; + VkImageTiling tiling; +} VkPhysicalDeviceSparseImageFormatInfo2; + +typedef struct VkPhysicalDeviceSparseProperties +{ + VkBool32 residencyStandard2DBlockShape; + VkBool32 residencyStandard2DMultisampleBlockShape; + VkBool32 residencyStandard3DBlockShape; + VkBool32 residencyAlignedMipSize; + VkBool32 residencyNonResidentStrict; +} VkPhysicalDeviceSparseProperties; + +typedef struct VkPhysicalDeviceTransformFeedbackPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t maxTransformFeedbackStreams; + uint32_t maxTransformFeedbackBuffers; + VkDeviceSize WINE_VK_ALIGN(8) maxTransformFeedbackBufferSize; + uint32_t maxTransformFeedbackStreamDataSize; + uint32_t maxTransformFeedbackBufferDataSize; + uint32_t maxTransformFeedbackBufferDataStride; + VkBool32 transformFeedbackQueries; + VkBool32 transformFeedbackStreamsLinesTriangles; + VkBool32 transformFeedbackRasterizationStreamSelect; + VkBool32 transformFeedbackDraw; +} VkPhysicalDeviceTransformFeedbackPropertiesEXT; + +typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t maxVertexAttribDivisor; +} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT; + +typedef struct VkPhysicalDeviceYcbcrImageArraysFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 ycbcrImageArrays; +} VkPhysicalDeviceYcbcrImageArraysFeaturesEXT; + +typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkBool32 srcPremultiplied; + VkBool32 dstPremultiplied; + VkBlendOverlapEXT blendOverlap; +} VkPipelineColorBlendAdvancedStateCreateInfoEXT; + +typedef struct VkPipelineCoverageModulationStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkPipelineCoverageModulationStateCreateFlagsNV flags; + VkCoverageModulationModeNV coverageModulationMode; + VkBool32 coverageModulationTableEnable; + uint32_t coverageModulationTableCount; + const float *pCoverageModulationTable; +} VkPipelineCoverageModulationStateCreateInfoNV; + +typedef struct VkPipelineDynamicStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineDynamicStateCreateFlags flags; + uint32_t dynamicStateCount; + const VkDynamicState *pDynamicStates; +} VkPipelineDynamicStateCreateInfo; + +typedef struct VkPipelineMultisampleStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineMultisampleStateCreateFlags flags; + VkSampleCountFlagBits rasterizationSamples; + VkBool32 sampleShadingEnable; + float minSampleShading; + const VkSampleMask *pSampleMask; + VkBool32 alphaToCoverageEnable; + VkBool32 alphaToOneEnable; +} VkPipelineMultisampleStateCreateInfo; + +typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags; + VkBool32 depthClipEnable; +} VkPipelineRasterizationDepthClipStateCreateInfoEXT; + +typedef struct VkPipelineRasterizationStateRasterizationOrderAMD +{ + VkStructureType sType; + const void *pNext; + VkRasterizationOrderAMD rasterizationOrder; +} VkPipelineRasterizationStateRasterizationOrderAMD; + +typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkBool32 representativeFragmentTestEnable; +} VkPipelineRepresentativeFragmentTestStateCreateInfoNV; + +typedef struct VkPipelineTessellationDomainOriginStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkTessellationDomainOrigin domainOrigin; +} VkPipelineTessellationDomainOriginStateCreateInfo; + +typedef struct VkPipelineTessellationStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineTessellationStateCreateFlags flags; + uint32_t patchControlPoints; +} VkPipelineTessellationStateCreateInfo; + +typedef struct VkPresentInfoKHR +{ + VkStructureType sType; + const void *pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore *pWaitSemaphores; + uint32_t swapchainCount; + const VkSwapchainKHR *pSwapchains; + const uint32_t *pImageIndices; + VkResult *pResults; +} VkPresentInfoKHR; + +typedef struct VkProtectedSubmitInfo +{ + VkStructureType sType; + const void *pNext; + VkBool32 protectedSubmit; +} VkProtectedSubmitInfo; + +typedef struct VkQueryPoolCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkQueryPoolCreateFlags flags; + VkQueryType queryType; + uint32_t queryCount; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkQueryPoolCreateInfo; + +typedef struct VkQueueFamilyProperties +{ + VkQueueFlags queueFlags; + uint32_t queueCount; + uint32_t timestampValidBits; + VkExtent3D minImageTransferGranularity; +} VkQueueFamilyProperties; + +typedef struct VkRayTracingShaderGroupCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkRayTracingShaderGroupTypeNV type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; +} VkRayTracingShaderGroupCreateInfoNV; + +typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkAttachmentReference fragmentDensityMapAttachment; +} VkRenderPassFragmentDensityMapCreateInfoEXT; + +typedef struct VkSampleLocationEXT +{ + float x; + float y; +} VkSampleLocationEXT; + +typedef struct VkSamplerCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkSamplerCreateFlags flags; + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU; + VkSamplerAddressMode addressModeV; + VkSamplerAddressMode addressModeW; + float mipLodBias; + VkBool32 anisotropyEnable; + float maxAnisotropy; + VkBool32 compareEnable; + VkCompareOp compareOp; + float minLod; + float maxLod; + VkBorderColor borderColor; + VkBool32 unnormalizedCoordinates; +} VkSamplerCreateInfo; + +typedef struct VkShaderModuleCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkShaderModuleCreateFlags flags; + size_t codeSize; + const uint32_t *pCode; +} VkShaderModuleCreateInfo; + +typedef struct VkShaderResourceUsageAMD +{ + uint32_t numUsedVgprs; + uint32_t numUsedSgprs; + uint32_t ldsSizePerLocalWorkGroup; + size_t ldsUsageSizeInBytes; + size_t scratchMemUsageInBytes; +} VkShaderResourceUsageAMD; + +typedef struct VkShadingRatePaletteNV +{ + uint32_t shadingRatePaletteEntryCount; + const VkShadingRatePaletteEntryNV *pShadingRatePaletteEntries; +} VkShadingRatePaletteNV; + +typedef struct VkSparseImageFormatProperties +{ + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +typedef struct VkSparseImageMemoryRequirements +{ + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize WINE_VK_ALIGN(8) imageMipTailSize; + VkDeviceSize WINE_VK_ALIGN(8) imageMipTailOffset; + VkDeviceSize WINE_VK_ALIGN(8) imageMipTailStride; +} VkSparseImageMemoryRequirements; + +typedef struct VkSparseMemoryBind +{ + VkDeviceSize WINE_VK_ALIGN(8) resourceOffset; + VkDeviceSize WINE_VK_ALIGN(8) size; + VkDeviceMemory WINE_VK_ALIGN(8) memory; + VkDeviceSize WINE_VK_ALIGN(8) memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseMemoryBind; + +typedef struct VkSpecializationMapEntry +{ + uint32_t constantID; + uint32_t offset; + size_t size; +} VkSpecializationMapEntry; + +typedef struct VkSubmitInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore *pWaitSemaphores; + const VkPipelineStageFlags *pWaitDstStageMask; + uint32_t commandBufferCount; + const VkCommandBuffer *pCommandBuffers; + uint32_t signalSemaphoreCount; + const VkSemaphore *pSignalSemaphores; +} VkSubmitInfo; + +typedef struct VkSubpassDependency +{ + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; +} VkSubpassDependency; + +typedef struct VkSubpassDescription +{ + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t inputAttachmentCount; + const VkAttachmentReference *pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference *pColorAttachments; + const VkAttachmentReference *pResolveAttachments; + const VkAttachmentReference *pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t *pPreserveAttachments; +} VkSubpassDescription; + +typedef struct VkSubpassEndInfoKHR +{ + VkStructureType sType; + const void *pNext; +} VkSubpassEndInfoKHR; + +typedef struct VkSubresourceLayout +{ + VkDeviceSize WINE_VK_ALIGN(8) offset; + VkDeviceSize WINE_VK_ALIGN(8) size; + VkDeviceSize WINE_VK_ALIGN(8) rowPitch; + VkDeviceSize WINE_VK_ALIGN(8) arrayPitch; + VkDeviceSize WINE_VK_ALIGN(8) depthPitch; +} VkSubresourceLayout; + +typedef struct VkValidationCacheCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkValidationCacheCreateFlagsEXT flags; + size_t initialDataSize; + const void *pInitialData; +} VkValidationCacheCreateInfoEXT; + +typedef struct VkVertexInputBindingDescription +{ + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; +} VkVertexInputBindingDescription; + +typedef struct VkViewportSwizzleNV +{ + VkViewportCoordinateSwizzleNV x; + VkViewportCoordinateSwizzleNV y; + VkViewportCoordinateSwizzleNV z; + VkViewportCoordinateSwizzleNV w; +} VkViewportSwizzleNV; + +typedef struct VkWriteDescriptorSetAccelerationStructureNV +{ + VkStructureType sType; + const void *pNext; + uint32_t accelerationStructureCount; + const VkAccelerationStructureNV *pAccelerationStructures; +} VkWriteDescriptorSetAccelerationStructureNV; + +typedef struct VkAcquireNextImageInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkSwapchainKHR WINE_VK_ALIGN(8) swapchain; + uint64_t WINE_VK_ALIGN(8) timeout; + VkSemaphore WINE_VK_ALIGN(8) semaphore; + VkFence WINE_VK_ALIGN(8) fence; + uint32_t deviceMask; +} VkAcquireNextImageInfoKHR; + +typedef struct VkAttachmentDescription2KHR +{ + VkStructureType sType; + const void *pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2KHR; + +typedef struct VkBaseOutStructure +{ + VkStructureType sType; + struct VkBaseOutStructure *pNext; +} VkBaseOutStructure; + +typedef struct VkBindBufferMemoryInfo +{ + VkStructureType sType; + const void *pNext; + VkBuffer WINE_VK_ALIGN(8) buffer; + VkDeviceMemory WINE_VK_ALIGN(8) memory; + VkDeviceSize WINE_VK_ALIGN(8) memoryOffset; +} VkBindBufferMemoryInfo; + +typedef struct VkBindImageMemoryInfo +{ + VkStructureType sType; + const void *pNext; + VkImage WINE_VK_ALIGN(8) image; + VkDeviceMemory WINE_VK_ALIGN(8) memory; + VkDeviceSize WINE_VK_ALIGN(8) memoryOffset; +} VkBindImageMemoryInfo; + +typedef struct VkBufferCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkBufferCreateFlags flags; + VkDeviceSize WINE_VK_ALIGN(8) size; + VkBufferUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t *pQueueFamilyIndices; +} VkBufferCreateInfo; + +typedef struct VkBufferMemoryRequirementsInfo2 +{ + VkStructureType sType; + const void *pNext; + VkBuffer WINE_VK_ALIGN(8) buffer; +} VkBufferMemoryRequirementsInfo2; + +typedef struct VkCheckpointDataNV +{ + VkStructureType sType; + void *pNext; + VkPipelineStageFlagBits stage; + void *pCheckpointMarker; +} VkCheckpointDataNV; + +typedef struct VkClearDepthStencilValue +{ + float depth; + uint32_t stencil; +} VkClearDepthStencilValue; + +typedef union VkClearValue +{ + VkClearColorValue color; + VkClearDepthStencilValue depthStencil; +} VkClearValue; + +typedef struct VkCoarseSampleOrderCustomNV +{ + VkShadingRatePaletteEntryNV shadingRate; + uint32_t sampleCount; + uint32_t sampleLocationCount; + const VkCoarseSampleLocationNV *pSampleLocations; +} VkCoarseSampleOrderCustomNV; + +typedef struct VkCommandBufferInheritanceInfo +{ + VkStructureType sType; + const void *pNext; + VkRenderPass WINE_VK_ALIGN(8) renderPass; + uint32_t subpass; + VkFramebuffer WINE_VK_ALIGN(8) framebuffer; + VkBool32 occlusionQueryEnable; + VkQueryControlFlags queryFlags; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkCommandBufferInheritanceInfo; + +typedef struct VkConformanceVersionKHR +{ + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersionKHR; + +typedef struct VkDescriptorBufferInfo +{ + VkBuffer WINE_VK_ALIGN(8) buffer; + VkDeviceSize WINE_VK_ALIGN(8) offset; + VkDeviceSize WINE_VK_ALIGN(8) range; +} VkDescriptorBufferInfo; + +typedef struct VkDescriptorPoolSize +{ + VkDescriptorType type; + uint32_t descriptorCount; +} VkDescriptorPoolSize; + +typedef struct VkDescriptorUpdateTemplateEntry +{ + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + size_t offset; + size_t stride; +} VkDescriptorUpdateTemplateEntry; + +typedef struct VkDeviceGroupCommandBufferBeginInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t deviceMask; +} VkDeviceGroupCommandBufferBeginInfo; + +typedef struct VkDeviceGroupPresentCapabilitiesKHR +{ + VkStructureType sType; + const void *pNext; + uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE]; + VkDeviceGroupPresentModeFlagsKHR modes; +} VkDeviceGroupPresentCapabilitiesKHR; + +typedef struct VkDeviceGroupSubmitInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t waitSemaphoreCount; + const uint32_t *pWaitSemaphoreDeviceIndices; + uint32_t commandBufferCount; + const uint32_t *pCommandBufferDeviceMasks; + uint32_t signalSemaphoreCount; + const uint32_t *pSignalSemaphoreDeviceIndices; +} VkDeviceGroupSubmitInfo; + +typedef struct VkDeviceQueueCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + const float *pQueuePriorities; +} VkDeviceQueueCreateInfo; + +typedef struct VkDrawIndexedIndirectCommand +{ + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} VkDrawIndexedIndirectCommand; + +typedef struct VkExternalFenceProperties +{ + VkStructureType sType; + void *pNext; + VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes; + VkExternalFenceHandleTypeFlags compatibleHandleTypes; + VkExternalFenceFeatureFlags externalFenceFeatures; +} VkExternalFenceProperties; + +typedef struct VkExternalSemaphoreProperties +{ + VkStructureType sType; + void *pNext; + VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes; + VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes; + VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; +} VkExternalSemaphoreProperties; + +typedef struct VkFramebufferCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkFramebufferCreateFlags flags; + VkRenderPass WINE_VK_ALIGN(8) renderPass; + uint32_t attachmentCount; + const VkImageView *pAttachments; + uint32_t width; + uint32_t height; + uint32_t layers; +} VkFramebufferCreateInfo; + +typedef struct VkImageFormatProperties +{ + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize WINE_VK_ALIGN(8) maxResourceSize; +} VkImageFormatProperties; + +typedef struct VkImageSubresourceRange +{ + VkImageAspectFlags aspectMask; + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceRange; + +typedef struct VkImageViewUsageCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkImageUsageFlags usage; +} VkImageViewUsageCreateInfo; + +typedef struct VkMemoryAllocateInfo +{ + VkStructureType sType; + const void *pNext; + VkDeviceSize WINE_VK_ALIGN(8) allocationSize; + uint32_t memoryTypeIndex; +} VkMemoryAllocateInfo; + +typedef struct VkMemoryDedicatedRequirements +{ + VkStructureType sType; + void *pNext; + VkBool32 prefersDedicatedAllocation; + VkBool32 requiresDedicatedAllocation; +} VkMemoryDedicatedRequirements; + +typedef struct VkMemoryPriorityAllocateInfoEXT +{ + VkStructureType sType; + const void *pNext; + float priority; +} VkMemoryPriorityAllocateInfoEXT; + +typedef struct VkMemoryType +{ + VkMemoryPropertyFlags propertyFlags; + uint32_t heapIndex; +} VkMemoryType; + +typedef struct VkOffset3D +{ + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D; + +typedef struct VkPhysicalDevice8BitStorageFeaturesKHR +{ + VkStructureType sType; + void *pNext; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; +} VkPhysicalDevice8BitStorageFeaturesKHR; + +typedef struct VkPhysicalDeviceBufferAddressFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferAddressFeaturesEXT; + +typedef struct VkPhysicalDeviceCooperativeMatrixFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 cooperativeMatrix; + VkBool32 cooperativeMatrixRobustBufferAccess; +} VkPhysicalDeviceCooperativeMatrixFeaturesNV; + +typedef struct VkPhysicalDeviceDepthClipEnableFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 depthClipEnable; +} VkPhysicalDeviceDepthClipEnableFeaturesEXT; + +typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t maxDiscardRectangles; +} VkPhysicalDeviceDiscardRectanglePropertiesEXT; + +typedef struct VkPhysicalDeviceExternalBufferInfo +{ + VkStructureType sType; + const void *pNext; + VkBufferCreateFlags flags; + VkBufferUsageFlags usage; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalBufferInfo; + +typedef struct VkPhysicalDeviceExternalImageFormatInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalImageFormatInfo; + +typedef struct VkPhysicalDeviceFloat16Int8FeaturesKHR +{ + VkStructureType sType; + void *pNext; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; +} VkPhysicalDeviceFloat16Int8FeaturesKHR; + +typedef struct VkPhysicalDeviceGroupProperties +{ + VkStructureType sType; + void *pNext; + uint32_t physicalDeviceCount; + VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE]; + VkBool32 subsetAllocation; +} VkPhysicalDeviceGroupProperties; + +typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT +{ + VkStructureType sType; + void *pNext; + VkImageViewType imageViewType; +} VkPhysicalDeviceImageViewImageFormatInfoEXT; + +typedef struct VkPhysicalDeviceMaintenance3Properties +{ + VkStructureType sType; + void *pNext; + uint32_t maxPerSetDescriptors; + VkDeviceSize WINE_VK_ALIGN(8) maxMemoryAllocationSize; +} VkPhysicalDeviceMaintenance3Properties; + +typedef struct VkPhysicalDeviceMeshShaderFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 taskShader; + VkBool32 meshShader; +} VkPhysicalDeviceMeshShaderFeaturesNV; + +typedef struct VkPhysicalDevicePointClippingProperties +{ + VkStructureType sType; + void *pNext; + VkPointClippingBehavior pointClippingBehavior; +} VkPhysicalDevicePointClippingProperties; + +typedef struct VkPhysicalDeviceProtectedMemoryFeatures +{ + VkStructureType sType; + void *pNext; + VkBool32 protectedMemory; +} VkPhysicalDeviceProtectedMemoryFeatures; + +typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 representativeFragmentTest; +} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV; + +typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures +{ + VkStructureType sType; + void *pNext; + VkBool32 samplerYcbcrConversion; +} VkPhysicalDeviceSamplerYcbcrConversionFeatures; + +typedef struct VkPhysicalDeviceShaderCorePropertiesAMD +{ + VkStructureType sType; + void *pNext; + uint32_t shaderEngineCount; + uint32_t shaderArraysPerEngineCount; + uint32_t computeUnitsPerShaderArray; + uint32_t simdPerComputeUnit; + uint32_t wavefrontsPerSimd; + uint32_t wavefrontSize; + uint32_t sgprsPerSimd; + uint32_t minSgprAllocation; + uint32_t maxSgprAllocation; + uint32_t sgprAllocationGranularity; + uint32_t vgprsPerSimd; + uint32_t minVgprAllocation; + uint32_t maxVgprAllocation; + uint32_t vgprAllocationGranularity; +} VkPhysicalDeviceShaderCorePropertiesAMD; + +typedef struct VkPhysicalDeviceTransformFeedbackFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 transformFeedback; + VkBool32 geometryStreams; +} VkPhysicalDeviceTransformFeedbackFeaturesEXT; + +typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 vertexAttributeInstanceRateDivisor; + VkBool32 vertexAttributeInstanceRateZeroDivisor; +} VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT; + +typedef struct VkPipelineCacheCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineCacheCreateFlags flags; + size_t initialDataSize; + const void *pInitialData; +} VkPipelineCacheCreateInfo; + +typedef struct VkPipelineCoverageToColorStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkPipelineCoverageToColorStateCreateFlagsNV flags; + VkBool32 coverageToColorEnable; + uint32_t coverageToColorLocation; +} VkPipelineCoverageToColorStateCreateInfoNV; + +typedef struct VkPipelineInputAssemblyStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineInputAssemblyStateCreateFlags flags; + VkPrimitiveTopology topology; + VkBool32 primitiveRestartEnable; +} VkPipelineInputAssemblyStateCreateInfo; + +typedef struct VkPipelineRasterizationConservativeStateCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkPipelineRasterizationConservativeStateCreateFlagsEXT flags; + VkConservativeRasterizationModeEXT conservativeRasterizationMode; + float extraPrimitiveOverestimationSize; +} VkPipelineRasterizationConservativeStateCreateInfoEXT; + +typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkPipelineRasterizationStateStreamCreateFlagsEXT flags; + uint32_t rasterizationStream; +} VkPipelineRasterizationStateStreamCreateInfoEXT; + +typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkCoarseSampleOrderTypeNV sampleOrderType; + uint32_t customSampleOrderCount; + const VkCoarseSampleOrderCustomNV *pCustomSampleOrders; +} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV; + +typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkBool32 shadingRateImageEnable; + uint32_t viewportCount; + const VkShadingRatePaletteNV *pShadingRatePalettes; +} VkPipelineViewportShadingRateImageStateCreateInfoNV; + +typedef struct VkPipelineViewportSwizzleStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkPipelineViewportSwizzleStateCreateFlagsNV flags; + uint32_t viewportCount; + const VkViewportSwizzleNV *pViewportSwizzles; +} VkPipelineViewportSwizzleStateCreateInfoNV; + +typedef struct VkQueueFamilyCheckpointPropertiesNV +{ + VkStructureType sType; + void *pNext; + VkPipelineStageFlags checkpointExecutionStageMask; +} VkQueueFamilyCheckpointPropertiesNV; + +typedef struct VkRenderPassCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription *pAttachments; + uint32_t subpassCount; + const VkSubpassDescription *pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency *pDependencies; +} VkRenderPassCreateInfo; + +typedef struct VkRenderPassMultiviewCreateInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t subpassCount; + const uint32_t *pViewMasks; + uint32_t dependencyCount; + const int32_t *pViewOffsets; + uint32_t correlationMaskCount; + const uint32_t *pCorrelationMasks; +} VkRenderPassMultiviewCreateInfo; + +typedef struct VkSamplerReductionModeCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkSamplerReductionModeEXT reductionMode; +} VkSamplerReductionModeCreateInfoEXT; + +typedef struct VkSamplerYcbcrConversionImageFormatProperties +{ + VkStructureType sType; + void *pNext; + uint32_t combinedImageSamplerDescriptorCount; +} VkSamplerYcbcrConversionImageFormatProperties; + +typedef struct VkSemaphoreCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkSemaphoreCreateFlags flags; +} VkSemaphoreCreateInfo; + +typedef struct VkShaderModuleValidationCacheCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkValidationCacheEXT WINE_VK_ALIGN(8) validationCache; +} VkShaderModuleValidationCacheCreateInfoEXT; + +typedef struct VkSparseImageFormatProperties2 +{ + VkStructureType sType; + void *pNext; + VkSparseImageFormatProperties properties; +} VkSparseImageFormatProperties2; + +typedef struct VkSparseImageMemoryRequirements2 +{ + VkStructureType sType; + void *pNext; + VkSparseImageMemoryRequirements WINE_VK_ALIGN(8) memoryRequirements; +} VkSparseImageMemoryRequirements2; + +typedef struct VkSpecializationInfo +{ + uint32_t mapEntryCount; + const VkSpecializationMapEntry *pMapEntries; + size_t dataSize; + const void *pData; +} VkSpecializationInfo; + +typedef struct VkSubpassBeginInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkSubpassContents contents; +} VkSubpassBeginInfoKHR; + +typedef struct VkSurfaceFormatKHR +{ + VkFormat format; + VkColorSpaceKHR colorSpace; +} VkSurfaceFormatKHR; + +typedef struct VkTextureLODGatherFormatPropertiesAMD +{ + VkStructureType sType; + void *pNext; + VkBool32 supportsTextureGatherLODBiasAMD; +} VkTextureLODGatherFormatPropertiesAMD; + +typedef struct VkVertexInputAttributeDescription +{ + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription; + +typedef struct VkViewport +{ + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} VkViewport; + +typedef struct VkWriteDescriptorSet +{ + VkStructureType sType; + const void *pNext; + VkDescriptorSet WINE_VK_ALIGN(8) dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + const VkDescriptorImageInfo *pImageInfo; + const VkDescriptorBufferInfo *pBufferInfo; + const VkBufferView *pTexelBufferView; +} VkWriteDescriptorSet; + +typedef struct VkAttachmentReference2KHR +{ + VkStructureType sType; + const void *pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2KHR; + +typedef struct VkBindBufferMemoryDeviceGroupInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t deviceIndexCount; + const uint32_t *pDeviceIndices; +} VkBindBufferMemoryDeviceGroupInfo; + +typedef struct VkBindImageMemorySwapchainInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkSwapchainKHR WINE_VK_ALIGN(8) swapchain; + uint32_t imageIndex; +} VkBindImageMemorySwapchainInfoKHR; + +typedef struct VkBufferDeviceAddressInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkBuffer WINE_VK_ALIGN(8) buffer; +} VkBufferDeviceAddressInfoEXT; + +typedef struct VkBufferViewCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkBufferViewCreateFlags flags; + VkBuffer WINE_VK_ALIGN(8) buffer; + VkFormat format; + VkDeviceSize WINE_VK_ALIGN(8) offset; + VkDeviceSize WINE_VK_ALIGN(8) range; +} VkBufferViewCreateInfo; + +typedef struct VkComponentMapping +{ + VkComponentSwizzle r; + VkComponentSwizzle g; + VkComponentSwizzle b; + VkComponentSwizzle a; +} VkComponentMapping; + +typedef struct VkCopyDescriptorSet +{ + VkStructureType sType; + const void *pNext; + VkDescriptorSet WINE_VK_ALIGN(8) srcSet; + uint32_t srcBinding; + uint32_t srcArrayElement; + VkDescriptorSet WINE_VK_ALIGN(8) dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; +} VkCopyDescriptorSet; + +typedef struct VkDescriptorPoolCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkDescriptorPoolCreateFlags flags; + uint32_t maxSets; + uint32_t poolSizeCount; + const VkDescriptorPoolSize *pPoolSizes; +} VkDescriptorPoolCreateInfo; + +typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT +{ + VkStructureType sType; + void *pNext; + uint32_t maxVariableDescriptorCount; +} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; + +typedef struct VkDeviceCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkDeviceCreateFlags flags; + uint32_t queueCreateInfoCount; + const VkDeviceQueueCreateInfo *pQueueCreateInfos; + uint32_t enabledLayerCount; + const char * const*ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char * const*ppEnabledExtensionNames; + const VkPhysicalDeviceFeatures *pEnabledFeatures; +} VkDeviceCreateInfo; + +typedef struct VkDeviceGroupDeviceCreateInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t physicalDeviceCount; + const VkPhysicalDevice *pPhysicalDevices; +} VkDeviceGroupDeviceCreateInfo; + +typedef struct VkDeviceGroupSwapchainCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkDeviceGroupPresentModeFlagsKHR modes; +} VkDeviceGroupSwapchainCreateInfoKHR; + +typedef struct VkDrawMeshTasksIndirectCommandNV +{ + uint32_t taskCount; + uint32_t firstTask; +} VkDrawMeshTasksIndirectCommandNV; + +typedef struct VkExtent2D +{ + uint32_t width; + uint32_t height; +} VkExtent2D; + +typedef struct VkFenceCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkFenceCreateFlags flags; +} VkFenceCreateInfo; + +typedef struct VkGeometryDataNV +{ + VkGeometryTrianglesNV WINE_VK_ALIGN(8) triangles; + VkGeometryAABBNV WINE_VK_ALIGN(8) aabbs; +} VkGeometryDataNV; + +typedef struct VkImageBlit +{ + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit; + +typedef struct VkImageMemoryBarrier +{ + VkStructureType sType; + const void *pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage WINE_VK_ALIGN(8) image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier; + +typedef struct VkImageResolve +{ + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve; + +typedef struct VkImageViewASTCDecodeModeEXT +{ + VkStructureType sType; + const void *pNext; + VkFormat decodeMode; +} VkImageViewASTCDecodeModeEXT; + +typedef struct VkMemoryAllocateFlagsInfo +{ + VkStructureType sType; + const void *pNext; + VkMemoryAllocateFlags flags; + uint32_t deviceMask; +} VkMemoryAllocateFlagsInfo; + +typedef struct VkMemoryRequirements2 +{ + VkStructureType sType; + void *pNext; + VkMemoryRequirements WINE_VK_ALIGN(8) memoryRequirements; +} VkMemoryRequirements2; + +typedef struct VkMultisamplePropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkExtent2D maxSampleLocationGridSize; +} VkMultisamplePropertiesEXT; + +typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 advancedBlendCoherentOperations; +} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT; + +typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 cornerSampledImage; +} VkPhysicalDeviceCornerSampledImageFeaturesNV; + +typedef struct VkPhysicalDeviceDriverPropertiesKHR +{ + VkStructureType sType; + void *pNext; + VkDriverIdKHR driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE_KHR]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR]; + VkConformanceVersionKHR conformanceVersion; +} VkPhysicalDeviceDriverPropertiesKHR; + +typedef struct VkPhysicalDeviceExternalMemoryHostPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkDeviceSize WINE_VK_ALIGN(8) minImportedHostPointerAlignment; +} VkPhysicalDeviceExternalMemoryHostPropertiesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 fragmentDensityMap; + VkBool32 fragmentDensityMapDynamic; + VkBool32 fragmentDensityMapNonSubsampledImages; +} VkPhysicalDeviceFragmentDensityMapFeaturesEXT; + +typedef struct VkPhysicalDeviceHostQueryResetFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 hostQueryReset; +} VkPhysicalDeviceHostQueryResetFeaturesEXT; + +typedef struct VkPhysicalDeviceInlineUniformBlockPropertiesEXT +{ + VkStructureType sType; + void *pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockPropertiesEXT; + +typedef struct VkPhysicalDeviceMultiviewFeatures +{ + VkStructureType sType; + void *pNext; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; +} VkPhysicalDeviceMultiviewFeatures; + +typedef struct VkPhysicalDeviceProperties +{ + uint32_t apiVersion; + uint32_t driverVersion; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceType deviceType; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + VkPhysicalDeviceLimits WINE_VK_ALIGN(8) limits; + VkPhysicalDeviceSparseProperties sparseProperties; +} VkPhysicalDeviceProperties; + +typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR +{ + VkStructureType sType; + void *pNext; + uint32_t maxPushDescriptors; +} VkPhysicalDevicePushDescriptorPropertiesKHR; + +typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; + +typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV +{ + VkStructureType sType; + void *pNext; + VkExtent2D shadingRateTexelSize; + uint32_t shadingRatePaletteSize; + uint32_t shadingRateMaxCoarseSamples; +} VkPhysicalDeviceShadingRateImagePropertiesNV; + +typedef struct VkPhysicalDeviceVariablePointerFeatures +{ + VkStructureType sType; + void *pNext; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; +} VkPhysicalDeviceVariablePointerFeatures; + +typedef struct VkPipelineColorBlendAttachmentState +{ + VkBool32 blendEnable; + VkBlendFactor srcColorBlendFactor; + VkBlendFactor dstColorBlendFactor; + VkBlendOp colorBlendOp; + VkBlendFactor srcAlphaBlendFactor; + VkBlendFactor dstAlphaBlendFactor; + VkBlendOp alphaBlendOp; + VkColorComponentFlags colorWriteMask; +} VkPipelineColorBlendAttachmentState; + +typedef struct VkPipelineRasterizationStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineRasterizationStateCreateFlags flags; + VkBool32 depthClampEnable; + VkBool32 rasterizerDiscardEnable; + VkPolygonMode polygonMode; + VkCullModeFlags cullMode; + VkFrontFace frontFace; + VkBool32 depthBiasEnable; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; + float lineWidth; +} VkPipelineRasterizationStateCreateInfo; + +typedef struct VkPipelineShaderStageCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineShaderStageCreateFlags flags; + VkShaderStageFlagBits stage; + VkShaderModule WINE_VK_ALIGN(8) module; + const char *pName; + const VkSpecializationInfo *pSpecializationInfo; +} VkPipelineShaderStageCreateInfo; + +typedef struct VkPipelineVertexInputStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineVertexInputStateCreateFlags flags; + uint32_t vertexBindingDescriptionCount; + const VkVertexInputBindingDescription *pVertexBindingDescriptions; + uint32_t vertexAttributeDescriptionCount; + const VkVertexInputAttributeDescription *pVertexAttributeDescriptions; +} VkPipelineVertexInputStateCreateInfo; + +typedef struct VkPushConstantRange +{ + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; +} VkPushConstantRange; + +typedef struct VkRayTracingPipelineCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo *pStages; + uint32_t groupCount; + const VkRayTracingShaderGroupCreateInfoNV *pGroups; + uint32_t maxRecursionDepth; + VkPipelineLayout WINE_VK_ALIGN(8) layout; + VkPipeline WINE_VK_ALIGN(8) basePipelineHandle; + int32_t basePipelineIndex; +} VkRayTracingPipelineCreateInfoNV; + +typedef struct VkRectLayerKHR +{ + VkOffset2D offset; + VkExtent2D extent; + uint32_t layer; +} VkRectLayerKHR; + +typedef struct VkSampleLocationsInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkSampleCountFlagBits sampleLocationsPerPixel; + VkExtent2D sampleLocationGridSize; + uint32_t sampleLocationsCount; + const VkSampleLocationEXT *pSampleLocations; +} VkSampleLocationsInfoEXT; + +typedef struct VkSamplerYcbcrConversionInfo +{ + VkStructureType sType; + const void *pNext; + VkSamplerYcbcrConversion WINE_VK_ALIGN(8) conversion; +} VkSamplerYcbcrConversionInfo; + +typedef struct VkShaderStatisticsInfoAMD +{ + VkShaderStageFlags shaderStageMask; + VkShaderResourceUsageAMD resourceUsage; + uint32_t numPhysicalVgprs; + uint32_t numPhysicalSgprs; + uint32_t numAvailableVgprs; + uint32_t numAvailableSgprs; + uint32_t computeWorkGroupSize[3]; +} VkShaderStatisticsInfoAMD; + +typedef struct VkSparseImageOpaqueMemoryBindInfo +{ + VkImage WINE_VK_ALIGN(8) image; + uint32_t bindCount; + const VkSparseMemoryBind *pBinds; +} VkSparseImageOpaqueMemoryBindInfo; + +typedef struct VkSubpassDependency2KHR +{ + VkStructureType sType; + const void *pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2KHR; + +typedef struct VkSubpassDescriptionDepthStencilResolveKHR +{ + VkStructureType sType; + const void *pNext; + VkResolveModeFlagBitsKHR depthResolveMode; + VkResolveModeFlagBitsKHR stencilResolveMode; + const VkAttachmentReference2KHR *pDepthStencilResolveAttachment; +} VkSubpassDescriptionDepthStencilResolveKHR; + +typedef struct VkViewportWScalingNV +{ + float xcoeff; + float ycoeff; +} VkViewportWScalingNV; + +typedef struct VkWriteDescriptorSetInlineUniformBlockEXT +{ + VkStructureType sType; + const void *pNext; + uint32_t dataSize; + const void *pData; +} VkWriteDescriptorSetInlineUniformBlockEXT; + +typedef struct VkApplicationInfo +{ + VkStructureType sType; + const void *pNext; + const char *pApplicationName; + uint32_t applicationVersion; + const char *pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo; + +typedef struct VkBufferImageCopy +{ + VkDeviceSize WINE_VK_ALIGN(8) bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy; + +typedef struct VkCommandBufferBeginInfo +{ + VkStructureType sType; + const void *pNext; + VkCommandBufferUsageFlags flags; + const VkCommandBufferInheritanceInfo *pInheritanceInfo; +} VkCommandBufferBeginInfo; + +typedef struct VkDescriptorSetLayoutBinding +{ + uint32_t binding; + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + const VkSampler *pImmutableSamplers; +} VkDescriptorSetLayoutBinding; + +typedef struct VkDescriptorUpdateTemplateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkDescriptorUpdateTemplateCreateFlags flags; + uint32_t descriptorUpdateEntryCount; + const VkDescriptorUpdateTemplateEntry *pDescriptorUpdateEntries; + VkDescriptorUpdateTemplateType templateType; + VkDescriptorSetLayout WINE_VK_ALIGN(8) descriptorSetLayout; + VkPipelineBindPoint pipelineBindPoint; + VkPipelineLayout WINE_VK_ALIGN(8) pipelineLayout; + uint32_t set; +} VkDescriptorUpdateTemplateCreateInfo; + +typedef struct VkDeviceQueueInfo2 +{ + VkStructureType sType; + const void *pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueIndex; +} VkDeviceQueueInfo2; + +typedef struct VkExportSemaphoreCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalSemaphoreHandleTypeFlags handleTypes; +} VkExportSemaphoreCreateInfo; + +typedef struct VkExternalMemoryProperties +{ + VkExternalMemoryFeatureFlags externalMemoryFeatures; + VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; + VkExternalMemoryHandleTypeFlags compatibleHandleTypes; +} VkExternalMemoryProperties; + +typedef struct VkGeometryNV +{ + VkStructureType sType; + const void *pNext; + VkGeometryTypeNV geometryType; + VkGeometryDataNV WINE_VK_ALIGN(8) geometry; + VkGeometryFlagsNV flags; +} VkGeometryNV; + +typedef struct VkImageCopy +{ + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + +typedef struct VkImagePlaneMemoryRequirementsInfo +{ + VkStructureType sType; + const void *pNext; + VkImageAspectFlagBits planeAspect; +} VkImagePlaneMemoryRequirementsInfo; + +typedef struct VkImageViewCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkImageViewCreateFlags flags; + VkImage WINE_VK_ALIGN(8) image; + VkImageViewType viewType; + VkFormat format; + VkComponentMapping components; + VkImageSubresourceRange subresourceRange; +} VkImageViewCreateInfo; + +typedef struct VkInputAttachmentAspectReference +{ + uint32_t subpass; + uint32_t inputAttachmentIndex; + VkImageAspectFlags aspectMask; +} VkInputAttachmentAspectReference; + +typedef struct VkMemoryDedicatedAllocateInfo +{ + VkStructureType sType; + const void *pNext; + VkImage WINE_VK_ALIGN(8) image; + VkBuffer WINE_VK_ALIGN(8) buffer; +} VkMemoryDedicatedAllocateInfo; + +typedef struct VkPhysicalDevice16BitStorageFeatures +{ + VkStructureType sType; + void *pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; +} VkPhysicalDevice16BitStorageFeatures; + +typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; +} VkPhysicalDeviceDescriptorIndexingFeaturesEXT; + +typedef struct VkPhysicalDeviceFeatures2 +{ + VkStructureType sType; + void *pNext; + VkPhysicalDeviceFeatures features; +} VkPhysicalDeviceFeatures2; + +typedef struct VkPhysicalDeviceImageFormatInfo2 +{ + VkStructureType sType; + const void *pNext; + VkFormat format; + VkImageType type; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkImageCreateFlags flags; +} VkPhysicalDeviceImageFormatInfo2; + +typedef struct VkPhysicalDeviceSampleLocationsPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkSampleCountFlags sampleLocationSampleCounts; + VkExtent2D maxSampleLocationGridSize; + float sampleLocationCoordinateRange[2]; + uint32_t sampleLocationSubPixelBits; + VkBool32 variableSampleLocations; +} VkPhysicalDeviceSampleLocationsPropertiesEXT; + +typedef struct VkPhysicalDeviceSubgroupProperties +{ + VkStructureType sType; + void *pNext; + uint32_t subgroupSize; + VkShaderStageFlags supportedStages; + VkSubgroupFeatureFlags supportedOperations; + VkBool32 quadOperationsInAllStages; +} VkPhysicalDeviceSubgroupProperties; + +typedef struct VkPipelineColorBlendStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineColorBlendStateCreateFlags flags; + VkBool32 logicOpEnable; + VkLogicOp logicOp; + uint32_t attachmentCount; + const VkPipelineColorBlendAttachmentState *pAttachments; + float blendConstants[4]; +} VkPipelineColorBlendStateCreateInfo; + +typedef struct VkPipelineLayoutCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineLayoutCreateFlags flags; + uint32_t setLayoutCount; + const VkDescriptorSetLayout *pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange *pPushConstantRanges; +} VkPipelineLayoutCreateInfo; + +typedef struct VkPipelineViewportWScalingStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkBool32 viewportWScalingEnable; + uint32_t viewportCount; + const VkViewportWScalingNV *pViewportWScalings; +} VkPipelineViewportWScalingStateCreateInfoNV; + +typedef struct VkQueueFamilyProperties2 +{ + VkStructureType sType; + void *pNext; + VkQueueFamilyProperties queueFamilyProperties; +} VkQueueFamilyProperties2; + +typedef struct VkRenderPassInputAttachmentAspectCreateInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t aspectReferenceCount; + const VkInputAttachmentAspectReference *pAspectReferences; +} VkRenderPassInputAttachmentAspectCreateInfo; + +typedef struct VkSamplerYcbcrConversionCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkFormat format; + VkSamplerYcbcrModelConversion ycbcrModel; + VkSamplerYcbcrRange ycbcrRange; + VkComponentMapping components; + VkChromaLocation xChromaOffset; + VkChromaLocation yChromaOffset; + VkFilter chromaFilter; + VkBool32 forceExplicitReconstruction; +} VkSamplerYcbcrConversionCreateInfo; + +typedef struct VkSparseBufferMemoryBindInfo +{ + VkBuffer WINE_VK_ALIGN(8) buffer; + uint32_t bindCount; + const VkSparseMemoryBind *pBinds; +} VkSparseBufferMemoryBindInfo; + +typedef struct VkStencilOpState +{ + VkStencilOp failOp; + VkStencilOp passOp; + VkStencilOp depthFailOp; + VkCompareOp compareOp; + uint32_t compareMask; + uint32_t writeMask; + uint32_t reference; +} VkStencilOpState; + +typedef struct VkSubpassSampleLocationsEXT +{ + uint32_t subpassIndex; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkSubpassSampleLocationsEXT; + +typedef struct VkSwapchainCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR WINE_VK_ALIGN(8) surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t *pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR WINE_VK_ALIGN(8) oldSwapchain; +} VkSwapchainCreateInfoKHR; + +typedef struct VkWin32SurfaceCreateInfoKHR +{ + VkStructureType sType; + const void *pNext; + VkWin32SurfaceCreateFlagsKHR flags; + HINSTANCE hinstance; + HWND hwnd; +} VkWin32SurfaceCreateInfoKHR; + +typedef struct VkAccelerationStructureInfoNV +{ + VkStructureType sType; + const void *pNext; + VkAccelerationStructureTypeNV type; + VkBuildAccelerationStructureFlagsNV flags; + uint32_t instanceCount; + uint32_t geometryCount; + const VkGeometryNV *pGeometries; +} VkAccelerationStructureInfoNV; + +typedef struct VkClearAttachment +{ + VkImageAspectFlags aspectMask; + uint32_t colorAttachment; + VkClearValue clearValue; +} VkClearAttachment; + +typedef struct VkComputePipelineCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineCreateFlags flags; + VkPipelineShaderStageCreateInfo WINE_VK_ALIGN(8) stage; + VkPipelineLayout WINE_VK_ALIGN(8) layout; + VkPipeline WINE_VK_ALIGN(8) basePipelineHandle; + int32_t basePipelineIndex; +} VkComputePipelineCreateInfo; + +typedef struct VkDescriptorSetLayoutCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkDescriptorSetLayoutCreateFlags flags; + uint32_t bindingCount; + const VkDescriptorSetLayoutBinding *pBindings; +} VkDescriptorSetLayoutCreateInfo; + +typedef struct VkExternalBufferProperties +{ + VkStructureType sType; + void *pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalBufferProperties; + +typedef struct VkFormatProperties +{ + VkFormatFeatureFlags linearTilingFeatures; + VkFormatFeatureFlags optimalTilingFeatures; + VkFormatFeatureFlags bufferFeatures; +} VkFormatProperties; + +typedef struct VkImageFormatProperties2 +{ + VkStructureType sType; + void *pNext; + VkImageFormatProperties WINE_VK_ALIGN(8) imageFormatProperties; +} VkImageFormatProperties2; + +typedef struct VkImportMemoryHostPointerInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + void *pHostPointer; +} VkImportMemoryHostPointerInfoEXT; + +typedef struct VkMemoryHeap +{ + VkDeviceSize WINE_VK_ALIGN(8) size; + VkMemoryHeapFlags flags; +} VkMemoryHeap; + +typedef struct VkPhysicalDeviceConditionalRenderingFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 conditionalRendering; + VkBool32 inheritedConditionalRendering; +} VkPhysicalDeviceConditionalRenderingFeaturesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMapPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkExtent2D minFragmentDensityTexelSize; + VkExtent2D maxFragmentDensityTexelSize; + VkBool32 fragmentDensityInvocations; +} VkPhysicalDeviceFragmentDensityMapPropertiesEXT; + +typedef struct VkPhysicalDeviceMemoryProperties +{ + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap WINE_VK_ALIGN(8) memoryHeaps[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryProperties; + +typedef struct VkPhysicalDeviceProperties2 +{ + VkStructureType sType; + void *pNext; + VkPhysicalDeviceProperties WINE_VK_ALIGN(8) properties; +} VkPhysicalDeviceProperties2; + +typedef struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR +{ + VkStructureType sType; + void *pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; +} VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; + +typedef struct VkPipelineSampleLocationsStateCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkBool32 sampleLocationsEnable; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkPipelineSampleLocationsStateCreateInfoEXT; + +typedef struct VkPresentRegionKHR +{ + uint32_t rectangleCount; + const VkRectLayerKHR *pRectangles; +} VkPresentRegionKHR; + +typedef struct VkRect2D +{ + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D; + +typedef struct VkSubpassDescription2KHR +{ + VkStructureType sType; + const void *pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2KHR *pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2KHR *pColorAttachments; + const VkAttachmentReference2KHR *pResolveAttachments; + const VkAttachmentReference2KHR *pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t *pPreserveAttachments; +} VkSubpassDescription2KHR; + +typedef struct VkVertexInputBindingDivisorDescriptionEXT +{ + uint32_t binding; + uint32_t divisor; +} VkVertexInputBindingDivisorDescriptionEXT; + +typedef struct VkAccelerationStructureCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkDeviceSize WINE_VK_ALIGN(8) compactedSize; + VkAccelerationStructureInfoNV info; +} VkAccelerationStructureCreateInfoNV; + +typedef struct VkBindImageMemoryDeviceGroupInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t deviceIndexCount; + const uint32_t *pDeviceIndices; + uint32_t splitInstanceBindRegionCount; + const VkRect2D *pSplitInstanceBindRegions; +} VkBindImageMemoryDeviceGroupInfo; + +typedef struct VkClearRect +{ + VkRect2D rect; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkClearRect; + +typedef struct VkDeviceGroupBindSparseInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t resourceDeviceIndex; + uint32_t memoryDeviceIndex; +} VkDeviceGroupBindSparseInfo; + +typedef struct VkExportFenceCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalFenceHandleTypeFlags handleTypes; +} VkExportFenceCreateInfo; + +typedef struct VkFormatProperties2 +{ + VkStructureType sType; + void *pNext; + VkFormatProperties formatProperties; +} VkFormatProperties2; + +typedef struct VkImageSubresource +{ + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t arrayLayer; +} VkImageSubresource; + +typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkDeviceSize WINE_VK_ALIGN(8) heapBudget[VK_MAX_MEMORY_HEAPS]; + VkDeviceSize WINE_VK_ALIGN(8) heapUsage[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryBudgetPropertiesEXT; + +typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 imageFootprint; +} VkPhysicalDeviceShaderImageFootprintFeaturesNV; + +typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + VkPipelineDiscardRectangleStateCreateFlagsEXT flags; + VkDiscardRectangleModeEXT discardRectangleMode; + uint32_t discardRectangleCount; + const VkRect2D *pDiscardRectangles; +} VkPipelineDiscardRectangleStateCreateInfoEXT; + +typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + uint32_t exclusiveScissorCount; + const VkRect2D *pExclusiveScissors; +} VkPipelineViewportExclusiveScissorStateCreateInfoNV; + +typedef struct VkPresentRegionsKHR +{ + VkStructureType sType; + const void *pNext; + uint32_t swapchainCount; + const VkPresentRegionKHR *pRegions; +} VkPresentRegionsKHR; + +typedef struct VkRenderPassCreateInfo2KHR +{ + VkStructureType sType; + const void *pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2KHR *pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2KHR *pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2KHR *pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t *pCorrelatedViewMasks; +} VkRenderPassCreateInfo2KHR; + +typedef struct VkSparseImageMemoryBind +{ + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + VkDeviceMemory WINE_VK_ALIGN(8) memory; + VkDeviceSize WINE_VK_ALIGN(8) memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseImageMemoryBind; + +typedef struct VkSurfaceCapabilitiesKHR +{ + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; +} VkSurfaceCapabilitiesKHR; + +typedef struct VkAttachmentSampleLocationsEXT +{ + uint32_t attachmentIndex; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkAttachmentSampleLocationsEXT; + +typedef struct VkDedicatedAllocationImageCreateInfoNV +{ + VkStructureType sType; + const void *pNext; + VkBool32 dedicatedAllocation; +} VkDedicatedAllocationImageCreateInfoNV; + +typedef struct VkExternalImageFormatProperties +{ + VkStructureType sType; + void *pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalImageFormatProperties; + +typedef struct VkInstanceCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkInstanceCreateFlags flags; + const VkApplicationInfo *pApplicationInfo; + uint32_t enabledLayerCount; + const char * const*ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char * const*ppEnabledExtensionNames; +} VkInstanceCreateInfo; + +typedef struct VkPhysicalDeviceMemoryProperties2 +{ + VkStructureType sType; + void *pNext; + VkPhysicalDeviceMemoryProperties WINE_VK_ALIGN(8) memoryProperties; +} VkPhysicalDeviceMemoryProperties2; + +typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT +{ + VkStructureType sType; + const void *pNext; + uint32_t vertexBindingDivisorCount; + const VkVertexInputBindingDivisorDescriptionEXT *pVertexBindingDivisors; +} VkPipelineVertexInputDivisorStateCreateInfoEXT; + +typedef struct VkRenderPassBeginInfo +{ + VkStructureType sType; + const void *pNext; + VkRenderPass WINE_VK_ALIGN(8) renderPass; + VkFramebuffer WINE_VK_ALIGN(8) framebuffer; + VkRect2D renderArea; + uint32_t clearValueCount; + const VkClearValue *pClearValues; +} VkRenderPassBeginInfo; + +typedef struct VkSparseImageMemoryBindInfo +{ + VkImage WINE_VK_ALIGN(8) image; + uint32_t bindCount; + const VkSparseImageMemoryBind *pBinds; +} VkSparseImageMemoryBindInfo; + +typedef struct VkBindSparseInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore *pWaitSemaphores; + uint32_t bufferBindCount; + const VkSparseBufferMemoryBindInfo *pBufferBinds; + uint32_t imageOpaqueBindCount; + const VkSparseImageOpaqueMemoryBindInfo *pImageOpaqueBinds; + uint32_t imageBindCount; + const VkSparseImageMemoryBindInfo *pImageBinds; + uint32_t signalSemaphoreCount; + const VkSemaphore *pSignalSemaphores; +} VkBindSparseInfo; + +typedef struct VkPhysicalDeviceExternalFenceInfo +{ + VkStructureType sType; + const void *pNext; + VkExternalFenceHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalFenceInfo; + +typedef struct VkPipelineViewportStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineViewportStateCreateFlags flags; + uint32_t viewportCount; + const VkViewport *pViewports; + uint32_t scissorCount; + const VkRect2D *pScissors; +} VkPipelineViewportStateCreateInfo; + +typedef struct VkDeviceGroupRenderPassBeginInfo +{ + VkStructureType sType; + const void *pNext; + uint32_t deviceMask; + uint32_t deviceRenderAreaCount; + const VkRect2D *pDeviceRenderAreas; +} VkDeviceGroupRenderPassBeginInfo; + +typedef struct VkPipelineDepthStencilStateCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineDepthStencilStateCreateFlags flags; + VkBool32 depthTestEnable; + VkBool32 depthWriteEnable; + VkCompareOp depthCompareOp; + VkBool32 depthBoundsTestEnable; + VkBool32 stencilTestEnable; + VkStencilOpState front; + VkStencilOpState back; + float minDepthBounds; + float maxDepthBounds; +} VkPipelineDepthStencilStateCreateInfo; + +typedef struct VkGraphicsPipelineCreateInfo +{ + VkStructureType sType; + const void *pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo *pStages; + const VkPipelineVertexInputStateCreateInfo *pVertexInputState; + const VkPipelineInputAssemblyStateCreateInfo *pInputAssemblyState; + const VkPipelineTessellationStateCreateInfo *pTessellationState; + const VkPipelineViewportStateCreateInfo *pViewportState; + const VkPipelineRasterizationStateCreateInfo *pRasterizationState; + const VkPipelineMultisampleStateCreateInfo *pMultisampleState; + const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState; + const VkPipelineColorBlendStateCreateInfo *pColorBlendState; + const VkPipelineDynamicStateCreateInfo *pDynamicState; + VkPipelineLayout WINE_VK_ALIGN(8) layout; + VkRenderPass WINE_VK_ALIGN(8) renderPass; + uint32_t subpass; + VkPipeline WINE_VK_ALIGN(8) basePipelineHandle; + int32_t basePipelineIndex; +} VkGraphicsPipelineCreateInfo; + +typedef struct VkRenderPassSampleLocationsBeginInfoEXT +{ + VkStructureType sType; + const void *pNext; + uint32_t attachmentInitialSampleLocationsCount; + const VkAttachmentSampleLocationsEXT *pAttachmentInitialSampleLocations; + uint32_t postSubpassSampleLocationsCount; + const VkSubpassSampleLocationsEXT *pPostSubpassSampleLocations; +} VkRenderPassSampleLocationsBeginInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice, const VkAcquireNextImageInfoKHR *, uint32_t *); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t *); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice, const VkCommandBufferAllocateInfo *, VkCommandBuffer *); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice, const VkDescriptorSetAllocateInfo *, VkDescriptorSet *); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice, const VkMemoryAllocateInfo *, const VkAllocationCallbacks *, VkDeviceMemory *); +typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer, const VkCommandBufferBeginInfo *); +typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice, uint32_t, const VkBindAccelerationStructureMemoryInfoNV *); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice, VkBuffer, VkDeviceMemory, VkDeviceSize); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2)(VkDevice, uint32_t, const VkBindBufferMemoryInfo *); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice, uint32_t, const VkBindBufferMemoryInfo *); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice, VkImage, VkDeviceMemory, VkDeviceSize); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2)(VkDevice, uint32_t, const VkBindImageMemoryInfo *); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice, uint32_t, const VkBindImageMemoryInfo *); +typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer, const VkConditionalRenderingBeginInfoEXT *); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer, VkQueryPool, uint32_t, VkQueryControlFlags); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQueryIndexedEXT)(VkCommandBuffer, VkQueryPool, uint32_t, VkQueryControlFlags, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer, const VkRenderPassBeginInfo *, VkSubpassContents); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer, const VkRenderPassBeginInfo *, const VkSubpassBeginInfoKHR *); +typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedbackEXT)(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer *, const VkDeviceSize *); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t, const VkDescriptorSet *, uint32_t, const uint32_t *); +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkIndexType); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer, VkPipelineBindPoint, VkPipeline); +typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer, VkImageView, VkImageLayout); +typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffersEXT)(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer *, const VkDeviceSize *, const VkDeviceSize *); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer *, const VkDeviceSize *); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer, VkImage, VkImageLayout, VkImage, VkImageLayout, uint32_t, const VkImageBlit *, VkFilter); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer, const VkAccelerationStructureInfoNV *, VkBuffer, VkDeviceSize, VkBool32, VkAccelerationStructureNV, VkAccelerationStructureNV, VkBuffer, VkDeviceSize); +typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer, uint32_t, const VkClearAttachment *, uint32_t, const VkClearRect *); +typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer, VkImage, VkImageLayout, const VkClearColorValue *, uint32_t, const VkImageSubresourceRange *); +typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer, VkImage, VkImageLayout, const VkClearDepthStencilValue *, uint32_t, const VkImageSubresourceRange *); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer, VkAccelerationStructureNV, VkAccelerationStructureNV, VkCopyAccelerationStructureModeNV); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer, VkBuffer, VkBuffer, uint32_t, const VkBufferCopy *); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer, VkBuffer, VkImage, VkImageLayout, uint32_t, const VkBufferImageCopy *); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer, VkImage, VkImageLayout, VkImage, VkImageLayout, uint32_t, const VkImageCopy *); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer, VkImage, VkImageLayout, VkBuffer, uint32_t, const VkBufferImageCopy *); +typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer, VkQueryPool, uint32_t, uint32_t, VkBuffer, VkDeviceSize, VkDeviceSize, VkQueryResultFlags); +typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer, uint32_t, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHR)(VkCommandBuffer, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer, VkBuffer, VkDeviceSize); +typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer, uint32_t, uint32_t, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer, uint32_t, uint32_t, uint32_t, int32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer, uint32_t, uint32_t, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer, VkBuffer, VkDeviceSize, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer, VkQueryPool, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer, VkQueryPool, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer, const VkSubpassEndInfoKHR *); +typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedbackEXT)(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer *, const VkDeviceSize *); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer, uint32_t, const VkCommandBuffer *); +typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkDeviceSize, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer, VkSubpassContents); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer, const VkSubpassBeginInfoKHR *, const VkSubpassEndInfoKHR *); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer, VkPipelineStageFlags, VkPipelineStageFlags, VkDependencyFlags, uint32_t, const VkMemoryBarrier *, uint32_t, const VkBufferMemoryBarrier *, uint32_t, const VkImageMemoryBarrier *); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer, VkPipelineLayout, VkShaderStageFlags, uint32_t, uint32_t, const void *); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t, const VkWriteDescriptorSet *); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer, VkDescriptorUpdateTemplate, VkPipelineLayout, uint32_t, const void *); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer, VkEvent, VkPipelineStageFlags); +typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer, VkQueryPool, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer, VkImage, VkImageLayout, VkImage, VkImageLayout, uint32_t, const VkImageResolve *); +typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer, const float[4]); +typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer, const void *); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer, VkCoarseSampleOrderTypeNV, uint32_t, const VkCoarseSampleOrderCustomNV *); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer, float, float, float); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer, float, float); +typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHR)(VkCommandBuffer, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer, uint32_t, uint32_t, const VkRect2D *); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer, VkEvent, VkPipelineStageFlags); +typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer, uint32_t, uint32_t, const VkRect2D *); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer, float); +typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer, const VkSampleLocationsInfoEXT *); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer, uint32_t, uint32_t, const VkRect2D *); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer, VkStencilFaceFlags, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer, VkStencilFaceFlags, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer, VkStencilFaceFlags, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer, uint32_t, uint32_t, const VkViewport *); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer, uint32_t, uint32_t, const VkShadingRatePaletteNV *); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer, uint32_t, uint32_t, const VkViewportWScalingNV *); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkBuffer, VkDeviceSize, VkDeviceSize, VkBuffer, VkDeviceSize, VkDeviceSize, VkBuffer, VkDeviceSize, VkDeviceSize, uint32_t, uint32_t, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkDeviceSize, const void *); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer, uint32_t, const VkEvent *, VkPipelineStageFlags, VkPipelineStageFlags, uint32_t, const VkMemoryBarrier *, uint32_t, const VkBufferMemoryBarrier *, uint32_t, const VkImageMemoryBarrier *); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer, uint32_t, const VkAccelerationStructureNV *, VkQueryType, VkQueryPool, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer, VkPipelineStageFlagBits, VkBuffer, VkDeviceSize, uint32_t); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer, VkPipelineStageFlagBits, VkQueryPool, uint32_t); +typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice, VkPipeline, uint32_t); +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice, const VkAccelerationStructureCreateInfoNV *, const VkAllocationCallbacks *, VkAccelerationStructureNV *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice, const VkBufferCreateInfo *, const VkAllocationCallbacks *, VkBuffer *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice, const VkBufferViewCreateInfo *, const VkAllocationCallbacks *, VkBufferView *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice, const VkCommandPoolCreateInfo *, const VkAllocationCallbacks *, VkCommandPool *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice, VkPipelineCache, uint32_t, const VkComputePipelineCreateInfo *, const VkAllocationCallbacks *, VkPipeline *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice, const VkDescriptorPoolCreateInfo *, const VkAllocationCallbacks *, VkDescriptorPool *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice, const VkDescriptorSetLayoutCreateInfo *, const VkAllocationCallbacks *, VkDescriptorSetLayout *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice, const VkDescriptorUpdateTemplateCreateInfo *, const VkAllocationCallbacks *, VkDescriptorUpdateTemplate *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice, const VkDescriptorUpdateTemplateCreateInfo *, const VkAllocationCallbacks *, VkDescriptorUpdateTemplate *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice, const VkDeviceCreateInfo *, const VkAllocationCallbacks *, VkDevice *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice, const VkEventCreateInfo *, const VkAllocationCallbacks *, VkEvent *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice, const VkFenceCreateInfo *, const VkAllocationCallbacks *, VkFence *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice, const VkFramebufferCreateInfo *, const VkAllocationCallbacks *, VkFramebuffer *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice, VkPipelineCache, uint32_t, const VkGraphicsPipelineCreateInfo *, const VkAllocationCallbacks *, VkPipeline *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice, const VkImageCreateInfo *, const VkAllocationCallbacks *, VkImage *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice, const VkImageViewCreateInfo *, const VkAllocationCallbacks *, VkImageView *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice, const VkPipelineCacheCreateInfo *, const VkAllocationCallbacks *, VkPipelineCache *); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice, const VkPipelineLayoutCreateInfo *, const VkAllocationCallbacks *, VkPipelineLayout *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice, const VkQueryPoolCreateInfo *, const VkAllocationCallbacks *, VkQueryPool *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice, VkPipelineCache, uint32_t, const VkRayTracingPipelineCreateInfoNV *, const VkAllocationCallbacks *, VkPipeline *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice, const VkRenderPassCreateInfo *, const VkAllocationCallbacks *, VkRenderPass *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice, const VkRenderPassCreateInfo2KHR *, const VkAllocationCallbacks *, VkRenderPass *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice, const VkSamplerCreateInfo *, const VkAllocationCallbacks *, VkSampler *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice, const VkSamplerYcbcrConversionCreateInfo *, const VkAllocationCallbacks *, VkSamplerYcbcrConversion *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice, const VkSamplerYcbcrConversionCreateInfo *, const VkAllocationCallbacks *, VkSamplerYcbcrConversion *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice, const VkSemaphoreCreateInfo *, const VkAllocationCallbacks *, VkSemaphore *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice, const VkShaderModuleCreateInfo *, const VkAllocationCallbacks *, VkShaderModule *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateValidationCacheEXT)(VkDevice, const VkValidationCacheCreateInfoEXT *, const VkAllocationCallbacks *, VkValidationCacheEXT *); +typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice, VkAccelerationStructureNV, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice, VkBuffer, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice, VkBufferView, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice, VkCommandPool, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice, VkDescriptorPool, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice, VkDescriptorSetLayout, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice, VkDescriptorUpdateTemplate, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice, VkDescriptorUpdateTemplate, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice, VkEvent, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice, VkFence, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice, VkFramebuffer, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice, VkImage, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice, VkImageView, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice, VkPipeline, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice, VkPipelineCache, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice, VkPipelineLayout, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice, VkQueryPool, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice, VkRenderPass, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice, VkSampler, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice, VkSamplerYcbcrConversion, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice, VkSamplerYcbcrConversion, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice, VkSemaphore, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice, VkShaderModule, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *); +typedef void (VKAPI_PTR *PFN_vkDestroyValidationCacheEXT)(VkDevice, VkValidationCacheEXT, const VkAllocationCallbacks *); +typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice); +typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice, const char *, uint32_t *, VkExtensionProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice, uint32_t *, VkLayerProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t *, VkLayerProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance, uint32_t *, VkPhysicalDevice *); +typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice, uint32_t, const VkMappedMemoryRange *); +typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice, VkCommandPool, uint32_t, const VkCommandBuffer *); +typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice, VkDescriptorPool, uint32_t, const VkDescriptorSet *); +typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice, VkDeviceMemory, const VkAllocationCallbacks *); +typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice, VkAccelerationStructureNV, size_t, void *); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice, const VkAccelerationStructureMemoryRequirementsInfoNV *, VkMemoryRequirements2KHR *); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice, const VkBufferDeviceAddressInfoEXT *); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice, VkBuffer, VkMemoryRequirements *); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice, const VkBufferMemoryRequirementsInfo2 *, VkMemoryRequirements2 *); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice, const VkBufferMemoryRequirementsInfo2 *, VkMemoryRequirements2 *); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice, const VkDescriptorSetLayoutCreateInfo *, VkDescriptorSetLayoutSupport *); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice, const VkDescriptorSetLayoutCreateInfo *, VkDescriptorSetLayoutSupport *); +typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice, uint32_t, uint32_t, uint32_t, VkPeerMemoryFeatureFlags *); +typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)(VkDevice, uint32_t, uint32_t, uint32_t, VkPeerMemoryFeatureFlags *); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice, VkDeviceGroupPresentCapabilitiesKHR *); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR *); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice, VkDeviceMemory, VkDeviceSize *); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice, const char *); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice, uint32_t, uint32_t, VkQueue *); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue2)(VkDevice, const VkDeviceQueueInfo2 *, VkQueue *); +typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice, VkEvent); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice, VkFence); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice, VkImage, VkMemoryRequirements *); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice, const VkImageMemoryRequirementsInfo2 *, VkMemoryRequirements2 *); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice, const VkImageMemoryRequirementsInfo2 *, VkMemoryRequirements2 *); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice, VkImage, uint32_t *, VkSparseImageMemoryRequirements *); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice, const VkImageSparseMemoryRequirementsInfo2 *, uint32_t *, VkSparseImageMemoryRequirements2 *); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice, const VkImageSparseMemoryRequirementsInfo2 *, uint32_t *, VkSparseImageMemoryRequirements2 *); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice, VkImage, const VkImageSubresource *, VkSubresourceLayout *); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance, const char *); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryHostPointerPropertiesEXT)(VkDevice, VkExternalMemoryHandleTypeFlagBits, const void *, VkMemoryHostPointerPropertiesEXT *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)(VkPhysicalDevice, uint32_t *, VkCooperativeMatrixPropertiesNV *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice, const VkPhysicalDeviceExternalBufferInfo *, VkExternalBufferProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice, const VkPhysicalDeviceExternalBufferInfo *, VkExternalBufferProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice, const VkPhysicalDeviceExternalFenceInfo *, VkExternalFenceProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice, const VkPhysicalDeviceExternalFenceInfo *, VkExternalFenceProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *, VkExternalSemaphoreProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *, VkExternalSemaphoreProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice, VkPhysicalDeviceFeatures *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice, VkPhysicalDeviceFeatures2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice, VkPhysicalDeviceFeatures2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice, VkFormat, VkFormatProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice, VkFormat, VkFormatProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice, VkFormat, VkFormatProperties2 *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice, VkFormat, VkImageType, VkImageTiling, VkImageUsageFlags, VkImageCreateFlags, VkImageFormatProperties *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice, const VkPhysicalDeviceImageFormatInfo2 *, VkImageFormatProperties2 *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice, const VkPhysicalDeviceImageFormatInfo2 *, VkImageFormatProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice, VkPhysicalDeviceMemoryProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice, VkPhysicalDeviceMemoryProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice, VkPhysicalDeviceMemoryProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice, VkSampleCountFlagBits, VkMultisamplePropertiesEXT *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkRect2D *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice, VkPhysicalDeviceProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice, VkPhysicalDeviceProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice, VkPhysicalDeviceProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice, uint32_t *, VkQueueFamilyProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice, uint32_t *, VkQueueFamilyProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice, uint32_t *, VkQueueFamilyProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice, VkFormat, VkImageType, VkSampleCountFlagBits, VkImageUsageFlags, VkImageTiling, uint32_t *, VkSparseImageFormatProperties *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *, uint32_t *, VkSparseImageFormatProperties2 *); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *, uint32_t *, VkSparseImageFormatProperties2 *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkSurfaceFormatKHR *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkPresentModeKHR *); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice, VkPipelineCache, size_t *, void *); +typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice, VkQueryPool, uint32_t, uint32_t, size_t, void *, VkDeviceSize, VkQueryResultFlags); +typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue, uint32_t *, VkCheckpointDataNV *); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice, VkPipeline, uint32_t, uint32_t, size_t, void *); +typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice, VkRenderPass, VkExtent2D *); +typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInfoAMD)(VkDevice, VkPipeline, VkShaderStageFlagBits, VkShaderInfoTypeAMD, size_t *, void *); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *); +typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice, VkValidationCacheEXT, size_t *, void *); +typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice, uint32_t, const VkMappedMemoryRange *); +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void **); +typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice, VkPipelineCache, uint32_t, const VkPipelineCache *); +typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice, VkValidationCacheEXT, uint32_t, const VkValidationCacheEXT *); +typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue, uint32_t, const VkBindSparseInfo *, VkFence); +typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue, uint32_t, const VkSubmitInfo *, VkFence); +typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer, VkCommandBufferResetFlags); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice, VkCommandPool, VkCommandPoolResetFlags); +typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice, VkDescriptorPool, VkDescriptorPoolResetFlags); +typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice, VkEvent); +typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice, uint32_t, const VkFence *); +typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice, VkQueryPool, uint32_t, uint32_t); +typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice, VkEvent); +typedef void (VKAPI_PTR *PFN_vkTrimCommandPool)(VkDevice, VkCommandPool, VkCommandPoolTrimFlags); +typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice, VkCommandPool, VkCommandPoolTrimFlags); +typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice, VkDeviceMemory); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice, VkDescriptorSet, VkDescriptorUpdateTemplate, const void *); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice, VkDescriptorSet, VkDescriptorUpdateTemplate, const void *); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice, uint32_t, const VkWriteDescriptorSet *, uint32_t, const VkCopyDescriptorSet *); +typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice, uint32_t, const VkFence *, VkBool32, uint64_t); + +#ifndef VK_NO_PROTOTYPES +VkResult VKAPI_CALL vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex); +VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex); +VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers); +VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets); +VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory); +VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo); +VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV *pBindInfos); +VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); +VkResult VKAPI_CALL vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo *pBindInfos); +VkResult VKAPI_CALL vkBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo *pBindInfos); +VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); +VkResult VKAPI_CALL vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo *pBindInfos); +VkResult VKAPI_CALL vkBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo *pBindInfos); +void VKAPI_CALL vkCmdBeginConditionalRenderingEXT(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin); +void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); +void VKAPI_CALL vkCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index); +void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents); +void VKAPI_CALL vkCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, const VkSubpassBeginInfoKHR *pSubpassBeginInfo); +void VKAPI_CALL vkCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer *pCounterBuffers, const VkDeviceSize *pCounterBufferOffsets); +void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets); +void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); +void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +void VKAPI_CALL vkCmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); +void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers, const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes); +void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers, const VkDeviceSize *pOffsets); +void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter); +void VKAPI_CALL vkCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); +void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment *pAttachments, uint32_t rectCount, const VkClearRect *pRects); +void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue *pColor, uint32_t rangeCount, const VkImageSubresourceRange *pRanges); +void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange *pRanges); +void VKAPI_CALL vkCmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeNV mode); +void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions); +void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions); +void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions); +void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions); +void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); +void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +void VKAPI_CALL vkCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +void VKAPI_CALL vkCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +void VKAPI_CALL vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +void VKAPI_CALL vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); +void VKAPI_CALL vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride); +void VKAPI_CALL vkCmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +void VKAPI_CALL vkCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask); +void VKAPI_CALL vkCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer); +void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); +void VKAPI_CALL vkCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index); +void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer); +void VKAPI_CALL vkCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR *pSubpassEndInfo); +void VKAPI_CALL vkCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer *pCounterBuffers, const VkDeviceSize *pCounterBufferOffsets); +void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); +void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents); +void VKAPI_CALL vkCmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR *pSubpassBeginInfo, const VkSubpassEndInfoKHR *pSubpassEndInfo); +void VKAPI_CALL vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers); +void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void *pValues); +void VKAPI_CALL vkCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites); +void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void *pData); +void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +void VKAPI_CALL vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions); +void VKAPI_CALL vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]); +void VKAPI_CALL vkCmdSetCheckpointNV(VkCommandBuffer commandBuffer, const void *pCheckpointMarker); +void VKAPI_CALL vkCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV *pCustomSampleOrders); +void VKAPI_CALL vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); +void VKAPI_CALL vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); +void VKAPI_CALL vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask); +void VKAPI_CALL vkCmdSetDeviceMaskKHR(VkCommandBuffer commandBuffer, uint32_t deviceMask); +void VKAPI_CALL vkCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D *pDiscardRectangles); +void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +void VKAPI_CALL vkCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D *pExclusiveScissors); +void VKAPI_CALL vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth); +void VKAPI_CALL vkCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT *pSampleLocationsInfo); +void VKAPI_CALL vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors); +void VKAPI_CALL vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); +void VKAPI_CALL vkCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); +void VKAPI_CALL vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); +void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports); +void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV *pShadingRatePalettes); +void VKAPI_CALL vkCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV *pViewportWScalings); +void VKAPI_CALL vkCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth); +void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData); +void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers); +void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV *pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +void VKAPI_CALL vkCmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); +VkResult VKAPI_CALL vkCompileDeferredNV(VkDevice device, VkPipeline pipeline, uint32_t shader); +VkResult VKAPI_CALL vkCreateAccelerationStructureNV(VkDevice device, const VkAccelerationStructureCreateInfoNV *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkAccelerationStructureNV *pAccelerationStructure); +VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer); +VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBufferView *pView); +VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); +VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); +VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool); +VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout); +VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate); +VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate); +VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); +VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent); +VkResult VKAPI_CALL vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFence *pFence); +VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer); +VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); +VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage); +VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImageView *pView); +VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance); +VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache); +VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout); +VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool); +VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); +VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); +VkResult VKAPI_CALL vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); +VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSampler *pSampler); +VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSamplerYcbcrConversion *pYcbcrConversion); +VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSamplerYcbcrConversion *pYcbcrConversion); +VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore); +VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule); +VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); +VkResult VKAPI_CALL vkCreateValidationCacheEXT(VkDevice device, const VkValidationCacheCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkValidationCacheEXT *pValidationCache); +VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); +void VKAPI_CALL vkDestroyAccelerationStructureNV(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator); +void VKAPI_CALL vkDestroyValidationCacheEXT(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks *pAllocator); +VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device); +VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer); +VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); +VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties); +VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); +VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount, VkLayerProperties *pProperties); +VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t *pApiVersion); +VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties); +VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties); +VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices); +VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges); +void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); +VkResult VKAPI_CALL vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets); +void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator); +VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void *pData); +void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV *pInfo, VkMemoryRequirements2KHR *pMemoryRequirements); +VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo); +void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements); +void VKAPI_CALL vkGetBufferMemoryRequirements2(VkDevice device, const VkBufferMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements); +void VKAPI_CALL vkGetBufferMemoryRequirements2KHR(VkDevice device, const VkBufferMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements); +void VKAPI_CALL vkGetDescriptorSetLayoutSupport(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, VkDescriptorSetLayoutSupport *pSupport); +void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, VkDescriptorSetLayoutSupport *pSupport); +void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags *pPeerMemoryFeatures); +void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHR(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags *pPeerMemoryFeatures); +VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities); +VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes); +void VKAPI_CALL vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize *pCommittedMemoryInBytes); +PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *pName); +void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue); +void VKAPI_CALL vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue); +VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event); +VkResult VKAPI_CALL vkGetFenceStatus(VkDevice device, VkFence fence); +void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements); +void VKAPI_CALL vkGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements); +void VKAPI_CALL vkGetImageMemoryRequirements2KHR(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements); +void VKAPI_CALL vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements *pSparseMemoryRequirements); +void VKAPI_CALL vkGetImageSparseMemoryRequirements2(VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements); +void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR(VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements); +void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout); +PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName); +VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void *pHostPointer, VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties); +VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkCooperativeMatrixPropertiesNV *pProperties); +void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, VkExternalBufferProperties *pExternalBufferProperties); +void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, VkExternalBufferProperties *pExternalBufferProperties); +void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties); +void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties); +void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); +void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); +void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures); +void VKAPI_CALL vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 *pFeatures); +void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 *pFeatures); +void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties); +void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2 *pFormatProperties); +void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2 *pFormatProperties); +VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties *pImageFormatProperties); +VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); +VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); +void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties); +void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 *pMemoryProperties); +void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 *pMemoryProperties); +void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT *pMultisampleProperties); +VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects); +void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties); +void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties); +void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties); +void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties); +void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties); +void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties); +void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties); +void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, uint32_t *pPropertyCount, VkSparseImageFormatProperties2 *pProperties); +void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, uint32_t *pPropertyCount, VkSparseImageFormatProperties2 *pProperties); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes); +VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported); +VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); +VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, void *pData); +VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags); +void VKAPI_CALL vkGetQueueCheckpointDataNV(VkQueue queue, uint32_t *pCheckpointDataCount, VkCheckpointDataNV *pCheckpointData); +VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void *pData); +void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity); +VkResult VKAPI_CALL vkGetShaderInfoAMD(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t *pInfoSize, void *pInfo); +VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages); +VkResult VKAPI_CALL vkGetValidationCacheDataEXT(VkDevice device, VkValidationCacheEXT validationCache, size_t *pDataSize, void *pData); +VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges); +VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData); +VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches); +VkResult VKAPI_CALL vkMergeValidationCachesEXT(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT *pSrcCaches); +VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence); +VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo); +VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence); +VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue); +VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); +VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); +VkResult VKAPI_CALL vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); +VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event); +VkResult VKAPI_CALL vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences); +void VKAPI_CALL vkResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event); +void VKAPI_CALL vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); +void VKAPI_CALL vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); +void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory memory); +void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void *pData); +void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void *pData); +void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies); +VkResult VKAPI_CALL vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout); +#endif /* VK_NO_PROTOTYPES */ + +#endif /* __WINE_VULKAN_H */ diff --git a/sdk/include/reactos/wine/vulkan_driver.h b/sdk/include/reactos/wine/vulkan_driver.h new file mode 100644 index 00000000000..02f504e9ae0 --- /dev/null +++ b/sdk/include/reactos/wine/vulkan_driver.h @@ -0,0 +1,135 @@ +/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! + * + * This file is generated from Vulkan vk.xml file covered + * by the following copyright and permission notice: + * + * Copyright (c) 2015-2019 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---- Exceptions to the Apache 2.0 License: ---- + * + * As an exception, if you use this Software to generate code and portions of + * this Software are embedded into the generated code as a result, you may + * redistribute such product without providing attribution as would otherwise + * be required by Sections 4(a), 4(b) and 4(d) of the License. + * + * In addition, if you combine or link code generated by this Software with + * software that is licensed under the GPLv2 or the LGPL v2.0 or 2.1 + * ("`Combined Software`") and if a court of competent jurisdiction determines + * that the patent provision (Section 3), the indemnity provision (Section 9) + * or other Section of the License conflicts with the conditions of the + * applicable GPL or LGPL license, you may retroactively and prospectively + * choose to deem waived or otherwise exclude such Section(s) of the License, + * but only in their entirety and only with respect to the Combined Software. + * + */ + +#ifndef __WINE_VULKAN_DRIVER_H +#define __WINE_VULKAN_DRIVER_H + +/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ +#define WINE_VULKAN_DRIVER_VERSION 7 + +struct vulkan_funcs +{ + /* Vulkan global functions. These are the only calls at this point a graphics driver + * needs to provide. Other function calls will be provided indirectly by dispatch + * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice. + */ + VkResult (*p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); + VkResult (*p_vkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *); + VkResult (*p_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); + void (*p_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); + void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); + void (*p_vkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *); + VkResult (*p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *); + VkResult (*p_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR *); + void * (*p_vkGetDeviceProcAddr)(VkDevice, const char *); + void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *); + VkResult (*p_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkRect2D *); + VkResult (*p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *); + VkResult (*p_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkSurfaceFormatKHR *); + VkResult (*p_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice, VkSurfaceKHR, uint32_t *, VkPresentModeKHR *); + VkResult (*p_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32 *); + VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t); + VkResult (*p_vkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *); + VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); +}; + +extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version); + +static inline void *get_vulkan_driver_device_proc_addr( + const struct vulkan_funcs *vulkan_funcs, const char *name) +{ + if (!name || name[0] != 'v' || name[1] != 'k') return NULL; + + name += 2; + + if (!strcmp(name, "CreateSwapchainKHR")) + return vulkan_funcs->p_vkCreateSwapchainKHR; + if (!strcmp(name, "DestroySwapchainKHR")) + return vulkan_funcs->p_vkDestroySwapchainKHR; + if (!strcmp(name, "GetDeviceGroupSurfacePresentModesKHR")) + return vulkan_funcs->p_vkGetDeviceGroupSurfacePresentModesKHR; + if (!strcmp(name, "GetDeviceProcAddr")) + return vulkan_funcs->p_vkGetDeviceProcAddr; + if (!strcmp(name, "GetSwapchainImagesKHR")) + return vulkan_funcs->p_vkGetSwapchainImagesKHR; + if (!strcmp(name, "QueuePresentKHR")) + return vulkan_funcs->p_vkQueuePresentKHR; + + return NULL; +} + +static inline void *get_vulkan_driver_instance_proc_addr( + const struct vulkan_funcs *vulkan_funcs, VkInstance instance, const char *name) +{ + if (!name || name[0] != 'v' || name[1] != 'k') return NULL; + + name += 2; + + if (!strcmp(name, "CreateInstance")) + return vulkan_funcs->p_vkCreateInstance; + if (!strcmp(name, "EnumerateInstanceExtensionProperties")) + return vulkan_funcs->p_vkEnumerateInstanceExtensionProperties; + + if (!instance) return NULL; + + if (!strcmp(name, "CreateWin32SurfaceKHR")) + return vulkan_funcs->p_vkCreateWin32SurfaceKHR; + if (!strcmp(name, "DestroyInstance")) + return vulkan_funcs->p_vkDestroyInstance; + if (!strcmp(name, "DestroySurfaceKHR")) + return vulkan_funcs->p_vkDestroySurfaceKHR; + if (!strcmp(name, "GetInstanceProcAddr")) + return vulkan_funcs->p_vkGetInstanceProcAddr; + if (!strcmp(name, "GetPhysicalDevicePresentRectanglesKHR")) + return vulkan_funcs->p_vkGetPhysicalDevicePresentRectanglesKHR; + if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilitiesKHR")) + return vulkan_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + if (!strcmp(name, "GetPhysicalDeviceSurfaceFormatsKHR")) + return vulkan_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR; + if (!strcmp(name, "GetPhysicalDeviceSurfacePresentModesKHR")) + return vulkan_funcs->p_vkGetPhysicalDeviceSurfacePresentModesKHR; + if (!strcmp(name, "GetPhysicalDeviceSurfaceSupportKHR")) + return vulkan_funcs->p_vkGetPhysicalDeviceSurfaceSupportKHR; + if (!strcmp(name, "GetPhysicalDeviceWin32PresentationSupportKHR")) + return vulkan_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR; + + name -= 2; + + return get_vulkan_driver_device_proc_addr(vulkan_funcs, name); +} + +#endif /* __WINE_VULKAN_DRIVER_H */ diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h index 1f8171d9c6b..33450aae0dc 100644 --- a/sdk/include/reactos/wine/wined3d.h +++ b/sdk/include/reactos/wine/wined3d.h @@ -26,10 +26,6 @@ #ifndef __WINE_WINED3D_H #define __WINE_WINED3D_H -#ifndef __WINE_CONFIG_H -# error You must include config.h to use this header -#endif - #include "wine/list.h" DEFINE_GUID(IID_IWineD3DDevice, 0xd56e2a4c, 0x5127, 0x8437, 0x65, 0x8a, 0x98, 0xc5, 0xbb, 0x78, 0x94, 0x98); @@ -90,6 +86,22 @@ enum wined3d_device_type WINED3D_DEVICE_TYPE_NULLREF = 4, }; +enum wined3d_feature_level +{ + WINED3D_FEATURE_LEVEL_NONE = 0x0000, + WINED3D_FEATURE_LEVEL_5 = 0x5000, + WINED3D_FEATURE_LEVEL_6 = 0x6000, + WINED3D_FEATURE_LEVEL_7 = 0x7000, + WINED3D_FEATURE_LEVEL_8 = 0x8000, + WINED3D_FEATURE_LEVEL_9_1 = 0x9100, + WINED3D_FEATURE_LEVEL_9_2 = 0x9200, + WINED3D_FEATURE_LEVEL_9_3 = 0x9300, + WINED3D_FEATURE_LEVEL_10 = 0xa000, + WINED3D_FEATURE_LEVEL_10_1 = 0xa100, + WINED3D_FEATURE_LEVEL_11 = 0xb000, + WINED3D_FEATURE_LEVEL_11_1 = 0xb100, +}; + enum wined3d_degree_type { WINED3D_DEGREE_LINEAR = 1, @@ -121,6 +133,7 @@ enum wined3d_format_id WINED3DFMT_R5G5_SNORM_L6_UNORM, WINED3DFMT_R8G8_SNORM_L8X8_UNORM, WINED3DFMT_R10G11B11_SNORM, + WINED3DFMT_R10G10B10X2_TYPELESS, WINED3DFMT_R10G10B10X2_UINT, WINED3DFMT_R10G10B10X2_SNORM, WINED3DFMT_R10G10B10_SNORM_A2_UNORM, @@ -373,7 +386,6 @@ enum wined3d_render_state WINED3D_RS_COLORWRITEENABLE1 = 190, WINED3D_RS_COLORWRITEENABLE2 = 191, WINED3D_RS_COLORWRITEENABLE3 = 192, - WINED3D_RS_BLENDFACTOR = 193, WINED3D_RS_SRGBWRITEENABLE = 194, WINED3D_RS_DEPTHBIAS = 195, WINED3D_RS_WRAP8 = 198, @@ -531,6 +543,16 @@ enum wined3d_swap_effect WINED3D_SWAP_EFFECT_OVERLAY, }; +enum wined3d_swap_interval +{ + WINED3D_SWAP_INTERVAL_IMMEDIATE = 0, + WINED3D_SWAP_INTERVAL_ONE = 1, + WINED3D_SWAP_INTERVAL_TWO = 2, + WINED3D_SWAP_INTERVAL_THREE = 3, + WINED3D_SWAP_INTERVAL_FOUR = 4, + WINED3D_SWAP_INTERVAL_DEFAULT = ~0u, +}; + enum wined3d_sampler_state { WINED3D_SAMP_ADDRESS_U = 1, @@ -590,7 +612,7 @@ enum wined3d_texture_stage_state WINED3D_TSS_ALPHA_ARG0 = 15, WINED3D_TSS_RESULT_ARG = 16, WINED3D_TSS_CONSTANT = 17, - WINED3D_TSS_INVALID = ~0U, + WINED3D_TSS_INVALID = ~0u, }; #define WINED3D_HIGHEST_TEXTURE_STATE WINED3D_TSS_CONSTANT @@ -768,6 +790,7 @@ enum wined3d_stateblock_type WINED3D_SBT_PIXEL_STATE = 2, WINED3D_SBT_VERTEX_STATE = 3, WINED3D_SBT_RECORDED = 4, /* WineD3D private */ + WINED3D_SBT_PRIMARY = 5, /* WineD3D private */ }; enum wined3d_decl_method @@ -843,10 +866,18 @@ enum wined3d_display_rotation WINED3D_DISPLAY_ROTATION_270 = 4, }; -enum wined3d_shader_byte_code_format +enum wined3d_shader_type { - WINED3D_SHADER_BYTE_CODE_FORMAT_SM1 = 0, - WINED3D_SHADER_BYTE_CODE_FORMAT_SM4 = 1, + WINED3D_SHADER_TYPE_PIXEL, + WINED3D_SHADER_TYPE_VERTEX, + WINED3D_SHADER_TYPE_GEOMETRY, + WINED3D_SHADER_TYPE_HULL, + WINED3D_SHADER_TYPE_DOMAIN, + WINED3D_SHADER_TYPE_GRAPHICS_COUNT, + + WINED3D_SHADER_TYPE_COMPUTE = WINED3D_SHADER_TYPE_GRAPHICS_COUNT, + WINED3D_SHADER_TYPE_COUNT, + WINED3D_SHADER_TYPE_INVALID = WINED3D_SHADER_TYPE_COUNT, }; #define WINED3DCOLORWRITEENABLE_RED (1u << 0) @@ -884,6 +915,8 @@ enum wined3d_shader_byte_code_format #define WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE 0x00002000u #define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT 0x00004000u #define WINED3D_SWAPCHAIN_GDI_COMPATIBLE 0x00008000u +#define WINED3D_SWAPCHAIN_IMPLICIT 0x00010000u +#define WINED3D_SWAPCHAIN_HOOK 0x00020000u #define WINED3DDP_MAXTEXCOORD 8 @@ -896,9 +929,6 @@ enum wined3d_shader_byte_code_format #define WINED3D_BIND_DEPTH_STENCIL 0x00000040 #define WINED3D_BIND_UNORDERED_ACCESS 0x00000080 -#define WINED3DUSAGE_RENDERTARGET 0x00000001 -#define WINED3DUSAGE_DEPTHSTENCIL 0x00000002 -#define WINED3DUSAGE_WRITEONLY 0x00000008 #define WINED3DUSAGE_SOFTWAREPROCESSING 0x00000010 #define WINED3DUSAGE_DONOTCLIP 0x00000020 #define WINED3DUSAGE_POINTS 0x00000040 @@ -910,12 +940,11 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE 0x00002000 #define WINED3DUSAGE_DMAP 0x00004000 #define WINED3DUSAGE_TEXTAPI 0x10000000 -#define WINED3DUSAGE_MASK 0x10007bff +#define WINED3DUSAGE_MASK 0x10007bf0 -#define WINED3DUSAGE_SCRATCH 0x00200000 -#define WINED3DUSAGE_PRIVATE 0x00400000 -#define WINED3DUSAGE_LEGACY_CUBEMAP 0x00800000 -#define WINED3DUSAGE_TEXTURE 0x01000000 +#define WINED3DUSAGE_SCRATCH 0x00400000 +#define WINED3DUSAGE_PRIVATE 0x00800000 +#define WINED3DUSAGE_LEGACY_CUBEMAP 0x01000000 #define WINED3DUSAGE_OWNDC 0x02000000 #define WINED3DUSAGE_STATICDECL 0x04000000 #define WINED3DUSAGE_OVERLAY 0x08000000 @@ -940,13 +969,6 @@ enum wined3d_shader_byte_code_format #define WINED3DPRESENT_RATE_DEFAULT 0x00000000 -#define WINED3DPRESENT_INTERVAL_DEFAULT 0x00000000 -#define WINED3DPRESENT_INTERVAL_ONE 0x00000001 -#define WINED3DPRESENT_INTERVAL_TWO 0x00000002 -#define WINED3DPRESENT_INTERVAL_THREE 0x00000004 -#define WINED3DPRESENT_INTERVAL_FOUR 0x00000008 -#define WINED3DPRESENT_INTERVAL_IMMEDIATE 0x80000000 - #define WINED3DCLIPPLANE0 (1u << 0) #define WINED3DCLIPPLANE1 (1u << 1) #define WINED3DCLIPPLANE2 (1u << 2) @@ -997,6 +1019,7 @@ enum wined3d_shader_byte_code_format #define WINED3DCLEAR_TARGET 0x00000001 #define WINED3DCLEAR_ZBUFFER 0x00000002 #define WINED3DCLEAR_STENCIL 0x00000004 +#define WINED3DCLEAR_SYNCHRONOUS 0x80000000 /* Stream source flags */ #define WINED3DSTREAMSOURCE_INDEXEDDATA (1u << 30) @@ -1201,7 +1224,6 @@ enum wined3d_shader_byte_code_format #define WINED3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT 0x00000800 #define WINED3DPRASTERCAPS_ANTIALIASEDGES 0x00001000 #define WINED3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000 -#define WINED3DPRASTERCAPS_ZBIAS 0x00004000 #define WINED3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000 #define WINED3DPRASTERCAPS_FOGRANGE 0x00010000 #define WINED3DPRASTERCAPS_ANISOTROPY 0x00020000 @@ -1555,19 +1577,19 @@ enum wined3d_shader_byte_code_format #define WINED3D_PALETTE_ALLOW_256 0x00000002 #define WINED3D_PALETTE_ALPHA 0x00000004 -#define WINED3D_TEXTURE_CREATE_MAPPABLE 0x00000001 #define WINED3D_TEXTURE_CREATE_DISCARD 0x00000002 #define WINED3D_TEXTURE_CREATE_GET_DC_LENIENT 0x00000004 #define WINED3D_TEXTURE_CREATE_GET_DC 0x00000008 #define WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS 0x00000010 +#define WINED3D_STANDARD_MULTISAMPLE_PATTERN 0xffffffff + #define WINED3D_APPEND_ALIGNED_ELEMENT 0xffffffff #define WINED3D_OUTPUT_SLOT_SEMANTIC 0xffffffff #define WINED3D_OUTPUT_SLOT_UNUSED 0xfffffffe #define WINED3D_MAX_STREAM_OUTPUT_BUFFERS 4 -#define WINED3D_STREAM_OUTPUT_GAP 0xffffffff #define WINED3D_NO_RASTERIZER_STREAM 0xffffffff #define WINED3D_VIEW_BUFFER_RAW 0x00000001 @@ -1576,6 +1598,12 @@ enum wined3d_shader_byte_code_format #define WINED3D_VIEW_TEXTURE_CUBE 0x00000008 #define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010 +#define WINED3D_MAX_VIEWPORTS 16 + +#define WINED3D_REGISTER_WINDOW_NO_WINDOW_CHANGES 0x00000001u +#define WINED3D_REGISTER_WINDOW_NO_ALT_ENTER 0x00000002u +#define WINED3D_REGISTER_WINDOW_NO_PRINT_SCREEN 0x00000004u + struct wined3d_display_mode { UINT width; @@ -1711,29 +1739,32 @@ struct wined3d_tri_patch_info struct wined3d_adapter_identifier { char *driver; - UINT driver_size; + unsigned int driver_size; char *description; - UINT description_size; + unsigned int description_size; char *device_name; - UINT device_name_size; + unsigned int device_name_size; LARGE_INTEGER driver_version; DWORD vendor_id; DWORD device_id; DWORD subsystem_id; DWORD revision; GUID device_identifier; + GUID driver_uuid; + GUID device_uuid; DWORD whql_level; LUID adapter_luid; SIZE_T video_memory; + SIZE_T shared_system_memory; }; struct wined3d_swapchain_desc { - UINT backbuffer_width; - UINT backbuffer_height; + unsigned int backbuffer_width; + unsigned int backbuffer_height; enum wined3d_format_id backbuffer_format; - UINT backbuffer_count; - DWORD backbuffer_usage; + unsigned int backbuffer_count; + unsigned int backbuffer_bind_flags; enum wined3d_multisample_type multisample_type; DWORD multisample_quality; enum wined3d_swap_effect swap_effect; @@ -1742,8 +1773,7 @@ struct wined3d_swapchain_desc BOOL enable_auto_depth_stencil; enum wined3d_format_id auto_depth_stencil_format; DWORD flags; - UINT refresh_rate; - UINT swap_interval; + unsigned int refresh_rate; BOOL auto_restore_display_mode; }; @@ -1754,6 +1784,7 @@ struct wined3d_resource_desc enum wined3d_multisample_type multisample_type; unsigned int multisample_quality; unsigned int usage; + unsigned int bind_flags; unsigned int access; unsigned int width; unsigned int height; @@ -1767,6 +1798,7 @@ struct wined3d_sub_resource_desc enum wined3d_multisample_type multisample_type; unsigned int multisample_quality; unsigned int usage; + unsigned int bind_flags; unsigned int access; unsigned int width; unsigned int height; @@ -1881,7 +1913,7 @@ struct wined3d_ddraw_caps DWORD dds_caps; }; -typedef struct _WINED3DCAPS +struct wined3d_caps { enum wined3d_device_type DeviceType; UINT AdapterOrdinal; @@ -1889,7 +1921,6 @@ typedef struct _WINED3DCAPS DWORD Caps; DWORD Caps2; DWORD Caps3; - DWORD PresentationIntervals; DWORD CursorCaps; DWORD DevCaps; @@ -1952,7 +1983,6 @@ typedef struct _WINED3DCAPS DWORD DevCaps2; float MaxNpatchTessellationLevel; - DWORD Reserved5; /* undocumented */ UINT MasterAdapterOrdinal; UINT AdapterOrdinalInGroup; @@ -1967,13 +1997,14 @@ typedef struct _WINED3DCAPS DWORD MaxPShaderInstructionsExecuted; DWORD MaxVertexShader30InstructionSlots; DWORD MaxPixelShader30InstructionSlots; - DWORD Reserved2; /* Not in the microsoft headers but documented */ - DWORD Reserved3; struct wined3d_ddraw_caps ddraw_caps; BOOL shader_double_precision; -} WINED3DCAPS; + BOOL viewport_array_index_any_shader; + + enum wined3d_feature_level max_feature_level; +}; struct wined3d_color_key { @@ -2008,6 +2039,8 @@ struct wined3d_blend_state_desc struct wined3d_rasterizer_state_desc { BOOL front_ccw; + float depth_bias_clamp; + BOOL depth_clip; }; struct wined3d_sampler_desc @@ -2050,17 +2083,13 @@ struct wined3d_shader_desc { const DWORD *byte_code; size_t byte_code_size; - enum wined3d_shader_byte_code_format format; - struct wined3d_shader_signature input_signature; - struct wined3d_shader_signature output_signature; - struct wined3d_shader_signature patch_constant_signature; - unsigned int max_version; }; struct wined3d_stream_output_element { unsigned int stream_idx; - unsigned int register_idx; + const char *semantic_name; + unsigned int semantic_idx; BYTE component_idx; BYTE component_count; BYTE output_slot; @@ -2068,7 +2097,7 @@ struct wined3d_stream_output_element struct wined3d_stream_output_desc { - struct wined3d_stream_output_element *elements; + const struct wined3d_stream_output_element *elements; unsigned int element_count; unsigned int buffer_strides[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; unsigned int buffer_stride_count; @@ -2124,6 +2153,7 @@ struct wined3d_shader; struct wined3d_shader_resource_view; struct wined3d_stateblock; struct wined3d_swapchain; +struct wined3d_swapchain_state; struct wined3d_texture; struct wined3d_unordered_access_view; struct wined3d_vertex_declaration; @@ -2138,16 +2168,11 @@ struct wined3d_device_parent_ops void (__cdecl *wined3d_device_created)(struct wined3d_device_parent *device_parent, struct wined3d_device *device); void (__cdecl *mode_changed)(struct wined3d_device_parent *device_parent); void (__cdecl *activate)(struct wined3d_device_parent *device_parent, BOOL activate); - HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent, - struct wined3d_texture *texture, unsigned int sub_resource_idx, - void **parent, const struct wined3d_parent_ops **parent_ops); - HRESULT (__cdecl *volume_created)(struct wined3d_device_parent *device_parent, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, + HRESULT (__cdecl *texture_sub_resource_created)(struct wined3d_device_parent *device_parent, + enum wined3d_resource_type type, struct wined3d_texture *texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops); HRESULT (__cdecl *create_swapchain_texture)(struct wined3d_device_parent *device_parent, void *parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture); - HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent, - struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain); }; struct wined3d_private_store @@ -2181,7 +2206,7 @@ HRESULT __cdecl wined3d_check_depth_stencil_match(const struct wined3d *wined3d, enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id); HRESULT __cdecl wined3d_check_device_format(const struct wined3d *wined3d, UINT adaper_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage, - enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id); + unsigned int bind_flags, enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id); HRESULT __cdecl wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id source_format_id, enum wined3d_format_id target_format_id); @@ -2207,14 +2232,17 @@ UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering); HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_raster_status *raster_status); -HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx, - enum wined3d_device_type device_type, WINED3DCAPS *caps); +HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, unsigned int adapter_idx, + enum wined3d_device_type device_type, struct wined3d_caps *caps); HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_output_desc *desc); ULONG __cdecl wined3d_incref(struct wined3d *wined3d); HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function); +BOOL __cdecl wined3d_register_window(struct wined3d *wined3d, HWND window, + struct wined3d_device *device, unsigned int flags); HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d, UINT adapter_idx, const struct wined3d_display_mode *mode); +void __cdecl wined3d_unregister_windows(struct wined3d *wined3d); HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, @@ -2226,7 +2254,7 @@ ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer); HRESULT __cdecl wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window); HRESULT __cdecl wined3d_device_begin_scene(struct wined3d_device *device); -HRESULT __cdecl wined3d_device_begin_stateblock(struct wined3d_device *device); +HRESULT __cdecl wined3d_device_begin_stateblock(struct wined3d_device *device, struct wined3d_stateblock **stateblock); HRESULT __cdecl wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float z, DWORD stencil); HRESULT __cdecl wined3d_device_clear_rendertarget_view(struct wined3d_device *device, @@ -2239,11 +2267,12 @@ void __cdecl wined3d_device_copy_resource(struct wined3d_device *device, HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *device, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource, - unsigned int src_sub_resource_idx, const struct wined3d_box *src_box); + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags); void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device, struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav); -HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, +HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment, + const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count, struct wined3d_device_parent *device_parent, struct wined3d_device **device); ULONG __cdecl wined3d_device_decref(struct wined3d_device *device); void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device, @@ -2261,41 +2290,41 @@ void __cdecl wined3d_device_draw_primitive_instanced(struct wined3d_device *devi void __cdecl wined3d_device_draw_primitive_instanced_indirect(struct wined3d_device *device, struct wined3d_buffer *buffer, unsigned int offset); HRESULT __cdecl wined3d_device_end_scene(struct wined3d_device *device); -HRESULT __cdecl wined3d_device_end_stateblock(struct wined3d_device *device, struct wined3d_stateblock **stateblock); +HRESULT __cdecl wined3d_device_end_stateblock(struct wined3d_device *device); void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device); UINT __cdecl wined3d_device_get_available_texture_mem(const struct wined3d_device *device); INT __cdecl wined3d_device_get_base_vertex_index(const struct wined3d_device *device); -struct wined3d_blend_state * __cdecl wined3d_device_get_blend_state(const struct wined3d_device *device); +struct wined3d_blend_state * __cdecl wined3d_device_get_blend_state(const struct wined3d_device *device, + struct wined3d_color *blend_factor); HRESULT __cdecl wined3d_device_get_clip_plane(const struct wined3d_device *device, UINT plane_idx, struct wined3d_vec4 *plane); HRESULT __cdecl wined3d_device_get_clip_status(const struct wined3d_device *device, struct wined3d_clip_status *clip_status); struct wined3d_shader * __cdecl wined3d_device_get_compute_shader(const struct wined3d_device *device); +struct wined3d_buffer * __cdecl wined3d_device_get_constant_buffer(const struct wined3d_device *device, + enum wined3d_shader_type shader_type, unsigned int idx); void __cdecl wined3d_device_get_creation_parameters(const struct wined3d_device *device, struct wined3d_device_creation_parameters *creation_parameters); -struct wined3d_buffer * __cdecl wined3d_device_get_cs_cb(const struct wined3d_device *device, unsigned int idx); struct wined3d_shader_resource_view * __cdecl wined3d_device_get_cs_resource_view(const struct wined3d_device *device, unsigned int idx); struct wined3d_sampler * __cdecl wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx); struct wined3d_unordered_access_view * __cdecl wined3d_device_get_cs_uav(const struct wined3d_device *device, unsigned int idx); struct wined3d_rendertarget_view * __cdecl wined3d_device_get_depth_stencil_view(const struct wined3d_device *device); -HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps); +HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps); HRESULT __cdecl wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation); struct wined3d_shader * __cdecl wined3d_device_get_domain_shader(const struct wined3d_device *device); -struct wined3d_buffer * __cdecl wined3d_device_get_ds_cb(const struct wined3d_device *device, unsigned int idx); struct wined3d_shader_resource_view * __cdecl wined3d_device_get_ds_resource_view(const struct wined3d_device *device, unsigned int idx); struct wined3d_sampler * __cdecl wined3d_device_get_ds_sampler(const struct wined3d_device *device, unsigned int idx); +enum wined3d_feature_level __cdecl wined3d_device_get_feature_level(const struct wined3d_device *device); void __cdecl wined3d_device_get_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, struct wined3d_gamma_ramp *ramp); struct wined3d_shader * __cdecl wined3d_device_get_geometry_shader(const struct wined3d_device *device); -struct wined3d_buffer * __cdecl wined3d_device_get_gs_cb(const struct wined3d_device *device, UINT idx); struct wined3d_shader_resource_view * __cdecl wined3d_device_get_gs_resource_view(const struct wined3d_device *device, UINT idx); struct wined3d_sampler * __cdecl wined3d_device_get_gs_sampler(const struct wined3d_device *device, UINT idx); -struct wined3d_buffer * __cdecl wined3d_device_get_hs_cb(const struct wined3d_device *device, unsigned int idx); struct wined3d_shader_resource_view * __cdecl wined3d_device_get_hs_resource_view(const struct wined3d_device *device, unsigned int idx); struct wined3d_sampler * __cdecl wined3d_device_get_hs_sampler(const struct wined3d_device *device, unsigned int idx); @@ -2306,12 +2335,12 @@ HRESULT __cdecl wined3d_device_get_light(const struct wined3d_device *device, UINT light_idx, struct wined3d_light *light); HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable); void __cdecl wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material); +unsigned int __cdecl wined3d_device_get_max_frame_latency(const struct wined3d_device *device); float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device); struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device); struct wined3d_query * __cdecl wined3d_device_get_predication(struct wined3d_device *device, BOOL *value); void __cdecl wined3d_device_get_primitive_type(const struct wined3d_device *device, enum wined3d_primitive_type *primitive_topology, unsigned int *patch_vertex_count); -struct wined3d_buffer * __cdecl wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx); HRESULT __cdecl wined3d_device_get_ps_consts_b(const struct wined3d_device *device, unsigned int start_idx, unsigned int count, BOOL *constants); HRESULT __cdecl wined3d_device_get_ps_consts_f(const struct wined3d_device *device, @@ -2329,7 +2358,8 @@ struct wined3d_rendertarget_view * __cdecl wined3d_device_get_rendertarget_view( unsigned int view_idx); DWORD __cdecl wined3d_device_get_sampler_state(const struct wined3d_device *device, UINT sampler_idx, enum wined3d_sampler_state state); -void __cdecl wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect); +void __cdecl wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, + RECT *rect); BOOL __cdecl wined3d_device_get_software_vertex_processing(const struct wined3d_device *device); struct wined3d_buffer * __cdecl wined3d_device_get_stream_output(struct wined3d_device *device, UINT idx, UINT *offset); @@ -2349,8 +2379,8 @@ struct wined3d_unordered_access_view * __cdecl wined3d_device_get_unordered_acce const struct wined3d_device *device, unsigned int idx); struct wined3d_vertex_declaration * __cdecl wined3d_device_get_vertex_declaration(const struct wined3d_device *device); struct wined3d_shader * __cdecl wined3d_device_get_vertex_shader(const struct wined3d_device *device); -void __cdecl wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport); -struct wined3d_buffer * __cdecl wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx); +void __cdecl wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count, + struct wined3d_viewport *viewports); HRESULT __cdecl wined3d_device_get_vs_consts_b(const struct wined3d_device *device, unsigned int start_idx, unsigned int count, BOOL *constants); HRESULT __cdecl wined3d_device_get_vs_consts_f(const struct wined3d_device *device, @@ -2362,8 +2392,6 @@ struct wined3d_shader_resource_view * __cdecl wined3d_device_get_vs_resource_vie struct wined3d_sampler * __cdecl wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx); struct wined3d * __cdecl wined3d_device_get_wined3d(const struct wined3d_device *device); ULONG __cdecl wined3d_device_incref(struct wined3d_device *device); -HRESULT __cdecl wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc); -HRESULT __cdecl wined3d_device_init_gdi(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc); void __cdecl wined3d_device_multiply_transform(struct wined3d_device *device, enum wined3d_transform_state state, const struct wined3d_matrix *matrix); HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device, @@ -2377,16 +2405,16 @@ void __cdecl wined3d_device_resolve_sub_resource(struct wined3d_device *device, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, enum wined3d_format_id format_id); -void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, - const RECT *window_rect); void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index); -void __cdecl wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state); +void __cdecl wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state, + const struct wined3d_color *blend_factor); HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device, UINT plane_idx, const struct wined3d_vec4 *plane); HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device, const struct wined3d_clip_status *clip_status); void __cdecl wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader); -void __cdecl wined3d_device_set_cs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer); +void __cdecl wined3d_device_set_constant_buffer(struct wined3d_device *device, enum wined3d_shader_type type, UINT idx, + struct wined3d_buffer *buffer); void __cdecl wined3d_device_set_cs_resource_view(struct wined3d_device *device, unsigned int idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_cs_sampler(struct wined3d_device *device, @@ -2397,11 +2425,10 @@ void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device, int x_screen_space, int y_screen_space, DWORD flags); HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device, UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx); -void __cdecl wined3d_device_set_depth_stencil_view(struct wined3d_device *device, +HRESULT __cdecl wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view); HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs); void __cdecl wined3d_device_set_domain_shader(struct wined3d_device *device, struct wined3d_shader *shader); -void __cdecl wined3d_device_set_ds_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer); void __cdecl wined3d_device_set_ds_resource_view(struct wined3d_device *device, unsigned int idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_ds_sampler(struct wined3d_device *device, @@ -2409,11 +2436,9 @@ void __cdecl wined3d_device_set_ds_sampler(struct wined3d_device *device, void __cdecl wined3d_device_set_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp); void __cdecl wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader); -void __cdecl wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer); void __cdecl wined3d_device_set_gs_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); -void __cdecl wined3d_device_set_hs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer); void __cdecl wined3d_device_set_hs_resource_view(struct wined3d_device *device, unsigned int idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_hs_sampler(struct wined3d_device *device, @@ -2425,6 +2450,7 @@ HRESULT __cdecl wined3d_device_set_light(struct wined3d_device *device, UINT light_idx, const struct wined3d_light *light); HRESULT __cdecl wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable); void __cdecl wined3d_device_set_material(struct wined3d_device *device, const struct wined3d_material *material); +void __cdecl wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int max_frame_latency); void __cdecl wined3d_device_set_multithreaded(struct wined3d_device *device); HRESULT __cdecl wined3d_device_set_npatch_mode(struct wined3d_device *device, float segments); void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader); @@ -2432,7 +2458,6 @@ void __cdecl wined3d_device_set_predication(struct wined3d_device *device, struct wined3d_query *predicate, BOOL value); void __cdecl wined3d_device_set_primitive_type(struct wined3d_device *device, enum wined3d_primitive_type primitive_topology, unsigned int patch_vertex_count); -void __cdecl wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer); HRESULT __cdecl wined3d_device_set_ps_consts_b(struct wined3d_device *device, unsigned int start_idx, unsigned int count, const BOOL *constants); HRESULT __cdecl wined3d_device_set_ps_consts_f(struct wined3d_device *device, @@ -2450,14 +2475,15 @@ HRESULT __cdecl wined3d_device_set_rendertarget_view(struct wined3d_device *devi unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport); void __cdecl wined3d_device_set_sampler_state(struct wined3d_device *device, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value); -void __cdecl wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect); +void __cdecl wined3d_device_set_scissor_rects(struct wined3d_device *device, + unsigned int rect_count, const RECT *rect); void __cdecl wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software); void __cdecl wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer, UINT offset); HRESULT __cdecl wined3d_device_set_stream_source(struct wined3d_device *device, UINT stream_idx, struct wined3d_buffer *buffer, UINT offset, UINT stride); HRESULT __cdecl wined3d_device_set_stream_source_freq(struct wined3d_device *device, UINT stream_idx, UINT divider); -HRESULT __cdecl wined3d_device_set_texture(struct wined3d_device *device, UINT stage, struct wined3d_texture *texture); +void __cdecl wined3d_device_set_texture(struct wined3d_device *device, UINT stage, struct wined3d_texture *texture); void __cdecl wined3d_device_set_texture_stage_state(struct wined3d_device *device, UINT stage, enum wined3d_texture_stage_state state, DWORD value); void __cdecl wined3d_device_set_transform(struct wined3d_device *device, @@ -2467,8 +2493,8 @@ void __cdecl wined3d_device_set_unordered_access_view(struct wined3d_device *dev void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device, struct wined3d_vertex_declaration *declaration); void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader); -void __cdecl wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport); -void __cdecl wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer); +void __cdecl wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count, + const struct wined3d_viewport *viewports); HRESULT __cdecl wined3d_device_set_vs_consts_b(struct wined3d_device *device, unsigned int start_idx, unsigned int count, const BOOL *constants); HRESULT __cdecl wined3d_device_set_vs_consts_f(struct wined3d_device *device, @@ -2478,13 +2504,10 @@ HRESULT __cdecl wined3d_device_set_vs_consts_i(struct wined3d_device *device, void __cdecl wined3d_device_set_vs_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); -void __cdecl wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, UINT w, UINT h); BOOL __cdecl wined3d_device_show_cursor(struct wined3d_device *device, BOOL show); -HRESULT __cdecl wined3d_device_uninit_3d(struct wined3d_device *device); -HRESULT __cdecl wined3d_device_uninit_gdi(struct wined3d_device *device); void __cdecl wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch); + unsigned int depth_pitch, unsigned int flags); HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture); HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes); @@ -2666,6 +2689,26 @@ HRESULT __cdecl wined3d_stateblock_create(struct wined3d_device *device, enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock); ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock); ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock); +void __cdecl wined3d_stateblock_set_blend_factor(struct wined3d_stateblock *stateblock, + const struct wined3d_color *blend_factor); +void __cdecl wined3d_stateblock_set_pixel_shader(struct wined3d_stateblock *stateblock, struct wined3d_shader *shader); +HRESULT __cdecl wined3d_stateblock_set_ps_consts_b(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const BOOL *constants); +HRESULT __cdecl wined3d_stateblock_set_ps_consts_f(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants); +HRESULT __cdecl wined3d_stateblock_set_ps_consts_i(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants); +void __cdecl wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateblock, + enum wined3d_render_state state, DWORD value); +void __cdecl wined3d_stateblock_set_vertex_declaration(struct wined3d_stateblock *stateblock, + struct wined3d_vertex_declaration *declaration); +void __cdecl wined3d_stateblock_set_vertex_shader(struct wined3d_stateblock *stateblock, struct wined3d_shader *shader); +HRESULT __cdecl wined3d_stateblock_set_vs_consts_b(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const BOOL *constants); +HRESULT __cdecl wined3d_stateblock_set_vs_consts_f(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants); +HRESULT __cdecl wined3d_stateblock_set_vs_consts_i(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants); HRESULT __cdecl wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain); @@ -2684,21 +2727,27 @@ void __cdecl wined3d_swapchain_get_desc(const struct wined3d_swapchain *swapchai struct wined3d_swapchain_desc *desc); HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain, struct wined3d_raster_status *raster_status); +struct wined3d_swapchain_state * __cdecl wined3d_swapchain_get_state(struct wined3d_swapchain *swapchain); ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain); HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags); HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality); -HRESULT __cdecl wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchain, - const struct wined3d_display_mode *mode); -HRESULT __cdecl wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain, - const struct wined3d_swapchain_desc *desc, const struct wined3d_display_mode *mode); HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain, DWORD flags, const struct wined3d_gamma_ramp *ramp); void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette); void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window); +HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc, + HWND window, struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_swapchain_state **state); +void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state); +HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state, + struct wined3d *wined3d, unsigned int adapter_idx, const struct wined3d_display_mode *mode); +HRESULT __cdecl wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state, + const struct wined3d_swapchain_desc *desc, struct wined3d *wined3d, + unsigned int adapter_idx, const struct wined3d_display_mode *mode); + HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture, UINT layer, const struct wined3d_box *dirty_region); HRESULT __cdecl wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_idx, const RECT *dst_rect_in, @@ -2755,10 +2804,13 @@ ULONG __cdecl wined3d_vertex_declaration_decref(struct wined3d_vertex_declaratio void * __cdecl wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration); ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration); +HRESULT __cdecl wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature, + const void *byte_code, SIZE_T byte_code_size); + /* Return the integer base-2 logarithm of x. Undefined for x == 0. */ static inline unsigned int wined3d_log2i(unsigned int x) { -#ifdef HAVE___BUILTIN_CLZ +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))) return __builtin_clz(x) ^ 0x1f; #else static const unsigned int l[] = @@ -2786,6 +2838,19 @@ static inline unsigned int wined3d_log2i(unsigned int x) #endif } +static inline int wined3d_bit_scan(unsigned int *x) +{ + int bit_offset; +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))) + bit_offset = __builtin_ffs(*x) - 1; +#else + for (bit_offset = 0; bit_offset < 32; bit_offset++) + if (*x & (1u << bit_offset)) break; +#endif + *x ^= 1u << bit_offset; + return bit_offset; +} + static inline void wined3d_box_set(struct wined3d_box *box, unsigned int left, unsigned int top, unsigned int right, unsigned int bottom, unsigned int front, unsigned int back) { diff --git a/sdk/include/reactos/wine/winedxgi.idl b/sdk/include/reactos/wine/winedxgi.idl new file mode 100644 index 00000000000..070ac2fddaa --- /dev/null +++ b/sdk/include/reactos/wine/winedxgi.idl @@ -0,0 +1,94 @@ +/* + * Copyright 2008-2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep header + +import "dxgi1_6.idl"; + +[ + object, + local, + uuid(53cb4ff0-c25a-4164-a891-0e83db0a7aac) +] +interface IWineDXGISwapChainFactory : IUnknown +{ + HRESULT create_swapchain( + [in] IDXGIFactory *factory, + [in] HWND window, + [in] const DXGI_SWAP_CHAIN_DESC1 *desc, + [in] const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, + [in] IDXGIOutput *output, + [out] IDXGISwapChain1 **swapchain + ); +} + +[ + object, + local, + uuid(3e1ff30b-c951-48c3-b010-0fb49f3dca71) +] +interface IWineDXGIDevice : IDXGIDevice3 +{ + HRESULT create_surface( + [in] struct wined3d_texture *wined3d_texture, + [in] DXGI_USAGE usage, + [in] const DXGI_SHARED_RESOURCE *shared_resource, + [in] IUnknown *outer, + [out] void **surface + ); +} + +[ + object, + local, + uuid(f2b918f3-603f-430a-9ccd-55872b6e85df) +] +interface IWineDXGIDeviceParent : IUnknown +{ + struct wined3d_device_parent *get_wined3d_device_parent(); +} + +struct wine_dxgi_adapter_info +{ + GUID driver_uuid; + GUID device_uuid; + + DWORD vendor_id; + DWORD device_id; + + LUID luid; +}; + +[ + object, + local, + uuid(17399d75-964e-4c03-99f8-9d4fd196dd62) +] +interface IWineDXGIAdapter : IDXGIAdapter4 +{ + HRESULT get_adapter_info([out] struct wine_dxgi_adapter_info *info); +} + +[ + object, + local, + uuid(ea02a0d1-4c95-488a-a82c-6034621e8c4f) +] +interface IWineDXGIFactory : IDXGIFactory5 +{ +} diff --git a/sdk/lib/crt/stdio/file.c b/sdk/lib/crt/stdio/file.c index 899eeafe03e..0be80b86b28 100644 --- a/sdk/lib/crt/stdio/file.c +++ b/sdk/lib/crt/stdio/file.c @@ -2784,6 +2784,8 @@ int CDECL fclose(FILE* file) { int r, flag; + if (!MSVCRT_CHECK_PMT(file != NULL)) return EOF; + _lock_file(file); flag = file->_flag; free(file->_tmpfname); diff --git a/sdk/lib/dxguid/dx10guid.c b/sdk/lib/dxguid/dx10guid.c index e2938ba08c2..e86c60da0ec 100644 --- a/sdk/lib/dxguid/dx10guid.c +++ b/sdk/lib/dxguid/dx10guid.c @@ -31,10 +31,11 @@ #include "olectl.h" #include "initguid.h" -#if 0 +#include "dxgi1_6.h" #include "d3d10_1.h" -#include "d3d11.h" +#include "d3d11_4.h" +#include "d3d12.h" +#include "d3dx10.h" #include "d3d10_1shader.h" -#endif - #include "d3d11shader.h" + diff --git a/sdk/lib/dxguid/dxguid-mingw.c b/sdk/lib/dxguid/dxguid-mingw.c index 254a8d1c40d..abd51d3c593 100644 --- a/sdk/lib/dxguid/dxguid-mingw.c +++ b/sdk/lib/dxguid/dxguid-mingw.c @@ -15,6 +15,134 @@ #include #include +#if 0 +DEFINE_GUID(IID_IWineDXGIDevice, 0x3e1ff30b, 0xc951, 0x48c3, 0xb0,0x10, 0x0f,0xb4,0x9f,0x3d,0xca,0x71); +DEFINE_GUID(IID_IWineDXGIDeviceParent, 0xf2b918f3, 0x603f, 0x430a, 0x9c,0xcd, 0x55,0x87,0x2b,0x6e,0x85,0xdf); +#endif +#if 0 +DEFINE_GUID(IID_ID3D10BlendState1,0xEDAD8D99,0x8A35,0x4d6d,0x85,0x66,0x2E,0xA2,0x76,0xCD,0xE1,0x61); +DEFINE_GUID(IID_ID3D10ShaderResourceView1,0x9B7E4C87,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Device1,0x9B7E4C8F,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DeviceChild,0x9B7E4C00,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DepthStencilState,0x2B4B1CC8,0xA4AD,0x41f8,0x83,0x22,0xCA,0x86,0xFC,0x3E,0xC6,0x75); +DEFINE_GUID(IID_ID3D10BlendState,0xEDAD8D19,0x8A35,0x4d6d,0x85,0x66,0x2E,0xA2,0x76,0xCD,0xE1,0x61); +DEFINE_GUID(IID_ID3D10RasterizerState,0xA2A07292,0x89AF,0x4345,0xBE,0x2E,0xC5,0x3D,0x9F,0xBB,0x6E,0x9F); +DEFINE_GUID(IID_ID3D10Resource,0x9B7E4C01,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Buffer,0x9B7E4C02,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture1D,0x9B7E4C03,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture2D,0x9B7E4C04,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Texture3D,0x9B7E4C05,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10View,0xC902B03F,0x60A7,0x49BA,0x99,0x36,0x2A,0x3A,0xB3,0x7A,0x7E,0x33); +DEFINE_GUID(IID_ID3D10ShaderResourceView,0x9B7E4C07,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10RenderTargetView,0x9B7E4C08,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10DepthStencilView,0x9B7E4C09,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10VertexShader,0x9B7E4C0A,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10GeometryShader,0x6316BE88,0x54CD,0x4040,0xAB,0x44,0x20,0x46,0x1B,0xC8,0x1F,0x68); +DEFINE_GUID(IID_ID3D10PixelShader,0x4968B601,0x9D00,0x4cde,0x83,0x46,0x8E,0x7F,0x67,0x58,0x19,0xB6); +DEFINE_GUID(IID_ID3D10InputLayout,0x9B7E4C0B,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10SamplerState,0x9B7E4C0C,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Asynchronous,0x9B7E4C0D,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Query,0x9B7E4C0E,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Predicate,0x9B7E4C10,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Counter,0x9B7E4C11,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Device,0x9B7E4C0F,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +DEFINE_GUID(IID_ID3D10Multithread,0x9B7E4E00,0x342C,0x4106,0xA1,0x9F,0x4F,0x27,0x04,0xF6,0x89,0xF0); +#endif +#if 1 +DEFINE_GUID(IID_ID3D10StateBlock, 0x0803425a, 0x57f5, 0x4dd6, 0x94, 0x65, 0xa8, 0x75, 0x70, 0x83, 0x4a, 0x08); + +DEFINE_GUID(IID_IDXGIObject,0xaec22fb8,0x76f3,0x4639,0x9b,0xe0,0x28,0xeb,0x43,0xa6,0x7a,0x2e); +DEFINE_GUID(IID_IDXGIDeviceSubObject,0x3d3e0379,0xf9de,0x4d58,0xbb,0x6c,0x18,0xd6,0x29,0x92,0xf1,0xa6); +DEFINE_GUID(IID_IDXGIResource,0x035f3ab4,0x482e,0x4e50,0xb4,0x1f,0x8a,0x7f,0x8b,0xd8,0x96,0x0b); +DEFINE_GUID(IID_IDXGIKeyedMutex,0x9d8e1289,0xd7b3,0x465f,0x81,0x26,0x25,0x0e,0x34,0x9a,0xf8,0x5d); +DEFINE_GUID(IID_IDXGISurface,0xcafcb56c,0x6ac3,0x4889,0xbf,0x47,0x9e,0x23,0xbb,0xd2,0x60,0xec); +DEFINE_GUID(IID_IDXGISurface1,0x4AE63092,0x6327,0x4c1b,0x80,0xAE,0xBF,0xE1,0x2E,0xA3,0x2B,0x86); +DEFINE_GUID(IID_IDXGIAdapter,0x2411e7e1,0x12ac,0x4ccf,0xbd,0x14,0x97,0x98,0xe8,0x53,0x4d,0xc0); +DEFINE_GUID(IID_IDXGIOutput,0xae02eedb,0xc735,0x4690,0x8d,0x52,0x5a,0x8d,0xc2,0x02,0x13,0xaa); +DEFINE_GUID(IID_IDXGISwapChain,0x310d36a0,0xd2e7,0x4c0a,0xaa,0x04,0x6a,0x9d,0x23,0xb8,0x88,0x6a); +DEFINE_GUID(IID_IDXGIFactory1,0x770aae78,0xf26f,0x4dba,0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87); +DEFINE_GUID(IID_IDXGIAdapter1,0x29038f61,0x3839,0x4626,0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05); +DEFINE_GUID(IID_IDXGIDevice1,0x77db970f,0x6276,0x48ba,0xba,0x28,0x07,0x01,0x43,0xb4,0x39,0x2c); +DEFINE_GUID(IID_ID3D10Effect, 0x51b0ca8b, 0xec0b, 0x4519, 0x87, 0x0d, 0x8e, 0xe1, 0xcb, 0x50, 0x17, 0xc7); +DEFINE_GUID(IID_ID3D10ShaderReflection, 0xd40e20b6, 0xf8f7, 0x42ad, 0xab, 0x20, 0x4b, 0xaf, 0x8f, 0x15, 0xdf, 0xaa); + +DEFINE_GUID(IID_IDXGIDisplayControl,0xea9dbf1a,0xc88e,0x4486,0x85,0x4a,0x98,0xaa,0x01,0x38,0xf3,0x0c); +DEFINE_GUID(IID_IDXGIOutputDuplication,0x191cfac3,0xa341,0x470d,0xb2,0x6e,0xa8,0x64,0xf4,0x28,0x31,0x9c); +DEFINE_GUID(IID_IDXGISurface2,0xaba496dd,0xb617,0x4cb8,0xa8,0x66,0xbc,0x44,0xd7,0xeb,0x1f,0xa2); +DEFINE_GUID(IID_IDXGIResource1,0x30961379,0x4609,0x4a41,0x99,0x8e,0x54,0xfe,0x56,0x7e,0xe0,0xc1); +DEFINE_GUID(IID_IDXGIDevice2,0x05008617,0xfbfd,0x4051,0xa7,0x90,0x14,0x48,0x84,0xb4,0xf6,0xa9); +DEFINE_GUID(IID_IDXGISwapChain1,0x790a45f7,0x0d42,0x4876,0x98,0x3a,0x0a,0x55,0xcf,0xe6,0xf4,0xaa); +DEFINE_GUID(IID_IDXGIFactory2,0x50c83a1c,0xe072,0x4c48,0x87,0xb0,0x36,0x30,0xfa,0x36,0xa6,0xd0); +DEFINE_GUID(IID_IDXGIAdapter2,0x0AA1AE0A,0xFA0E,0x4B84,0x86,0x44,0xE0,0x5F,0xF8,0xE5,0xAC,0xB5); +DEFINE_GUID(IID_IDXGIOutput1,0x00cddea8,0x939b,0x4b83,0xa3,0x40,0xa6,0x85,0x22,0x66,0x66,0xcc); +DEFINE_GUID(IID_IDXGISwapChain3,0x94d99bdb,0xf1f8,0x4ab0,0xb2,0x36,0x7d,0xa0,0x17,0x0e,0xda,0xb1); +DEFINE_GUID(IID_IDXGIOutput4,0xdc7dca35,0x2196,0x414d,0x9F,0x53,0x61,0x78,0x84,0x03,0x2a,0x60); +DEFINE_GUID(IID_IDXGIFactory4,0x1bc6ea02,0xef36,0x464f,0xbf,0x0c,0x21,0xca,0x39,0xe5,0x16,0x8a); +DEFINE_GUID(IID_IDXGIAdapter3,0x645967A4,0x1392,0x4310,0xA7,0x98,0x80,0x53,0xCE,0x3E,0x93,0xFD); +DEFINE_GUID(IID_IDXGIFactory3,0x25483823,0xcd46,0x4c7d,0x86,0xca,0x47,0xaa,0x95,0xb8,0x37,0xbd); +DEFINE_GUID(IID_IDXGIFactory5,0x7632e1f5,0xee65,0x4dca,0x87,0xfd,0x84,0xcd,0x75,0xf8,0x83,0x8d); + +#endif +DEFINE_GUID(IID_ID3D10ShaderResourceView, 0x9b7e4c07, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10DepthStencilView, 0x9b7e4c09, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11UnorderedAccessView, 0x28acf509, 0x7f5c, 0x48f6, 0x86,0x11, 0xf3,0x16,0x01,0x0a,0x63,0x80); +DEFINE_GUID(IID_ID3D11Texture1D, 0xf8fb5c27, 0xc6b3, 0x4f75, 0xa4,0xc8, 0x43,0x9a,0xf2,0xef,0x56,0x4c); +DEFINE_GUID(IID_ID3D11ShaderResourceView, 0xb0e06fe0, 0x8192, 0x4e1a, 0xb1,0xca, 0x36,0xd7,0x41,0x47,0x10,0xb2); +DEFINE_GUID(IID_ID3D11RenderTargetView, 0xdfdba067, 0x0b8d, 0x4865, 0x87,0x5b, 0xd7,0xb4,0x51,0x6c,0xc1,0x64); +DEFINE_GUID(IID_ID3D11DepthStencilView, 0x9fdac92a, 0x1876, 0x48c3, 0xaf,0xad, 0x25,0xb9,0x4f,0x84,0xa9,0xb6); +DEFINE_GUID(IID_ID3D11View, 0x839d1216, 0xbb2e, 0x412b, 0xb7,0xf4, 0xa9,0xdb,0xeb,0xe0,0x8e,0xd1); +DEFINE_GUID(IID_ID3D10Texture2D, 0x9b7e4c04, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Texture3D, 0x037e866e, 0xf56d, 0x4357, 0xa8,0xaf, 0x9d,0xab,0xbe,0x6e,0x25,0x0e); +DEFINE_GUID(IID_ID3D11Texture2D, 0x6f15aaf2, 0xd208, 0x4e89, 0x9a,0xb4, 0x48,0x95,0x35,0xd3,0x4f,0x9c); +DEFINE_GUID(IID_ID3D10BlendState1, 0xedad8d99, 0x8a35, 0x4d6d, 0x85,0x66, 0x2e,0xa2,0x76,0xcd,0xe1,0x61); +DEFINE_GUID(IID_ID3D10SamplerState, 0x9b7e4c0c, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10RasterizerState, 0xa2a07292, 0x89af, 0x4345, 0xbe,0x2e, 0xc5,0x3d,0x9f,0xbb,0x6e,0x9f); +DEFINE_GUID(IID_ID3D10DepthStencilState, 0x2b4b1cc8, 0xa4ad, 0x41f8, 0x83,0x22, 0xca,0x86,0xfc,0x3e,0xc6,0x75); +DEFINE_GUID(IID_ID3D10BlendState, 0xedad8d19, 0x8a35, 0x4d6d, 0x85,0x66, 0x2e,0xa2,0x76,0xcd,0xe1,0x61); +DEFINE_GUID(IID_ID3D11SamplerState, 0xda6fea51, 0x564c, 0x4487, 0x98,0x10, 0xf0,0xd0,0xf9,0xb4,0xe3,0xa5); +DEFINE_GUID(IID_ID3D11RasterizerState, 0x9bb4ab81, 0xab1a, 0x4d8f, 0xb5,0x06, 0xfc,0x04,0x20,0x0b,0x6e,0xe7); +DEFINE_GUID(IID_ID3D11DepthStencilState, 0x03823efb, 0x8d8f, 0x4e1c, 0x9a,0xa2, 0xf6,0x4b,0xb2,0xcb,0xfd,0xf1); +DEFINE_GUID(IID_ID3D11DeviceContext, 0xc0bfa96c, 0xe089, 0x44fb, 0x8e,0xaf, 0x26,0xf8,0x79,0x61,0x90,0xda); +DEFINE_GUID(IID_ID3D11BlendState, 0xcc86fabe, 0xda55, 0x401d, 0x85,0xe7, 0xe3,0xc9,0xde,0x28,0x77,0xe9); +DEFINE_GUID(IID_ID3D10PixelShader, 0x4968b601, 0x9d00, 0x4cde, 0x83,0x46, 0x8e,0x7f,0x67,0x58,0x19,0xb6); +DEFINE_GUID(IID_ID3D10GeometryShader, 0x6316be88, 0x54cd, 0x4040, 0xab,0x44, 0x20,0x46,0x1b,0xc8,0x1f,0x68); +DEFINE_GUID(IID_ID3D11VertexShader, 0x3b301d64, 0xd678, 0x4289, 0x88,0x97, 0x22,0xf8,0x92,0x8b,0x72,0xf3); +DEFINE_GUID(IID_ID3D11PixelShader, 0xea82e40d, 0x51dc, 0x4f33, 0x93,0xd4, 0xdb,0x7c,0x91,0x25,0xae,0x8c); +DEFINE_GUID(IID_ID3D11GeometryShader, 0x38325b96, 0xeffb, 0x4022, 0xba,0x02, 0x2e,0x79,0x5b,0x70,0x27,0x5c); +DEFINE_GUID(IID_ID3D11DomainShader, 0xf582c508, 0x0f36, 0x490c, 0x99,0x77, 0x31,0xee,0xce,0x26,0x8c,0xfa); +DEFINE_GUID(IID_ID3D11ComputeShader, 0x4f5b196e, 0xc2bd, 0x495e, 0xbd,0x01, 0x1f,0xde,0xd3,0x8e,0x49,0x69); +DEFINE_GUID(IID_ID3D10InputLayout, 0x9b7e4c0b, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11InputLayout, 0xe4819ddc, 0x4cf0, 0x4025, 0xbd,0x26, 0x5d,0xe8,0x2a,0x3e,0x07,0xb7); +DEFINE_GUID(IID_ID3D11HullShader, 0x8e5c6061, 0x628a, 0x4c8e, 0x82,0x64, 0xbb,0xe4,0x5c,0xb3,0xd5,0xdd); +DEFINE_GUID(IID_ID3D10Multithread, 0x9b7e4e00, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Device, 0xdb6f6ddb, 0xac77, 0x4e88, 0x82,0x53, 0x81,0x9d,0xf9,0xbb,0xf1,0x40); +DEFINE_GUID(IID_IDXGIDevice, 0x54ec77fa, 0x1377, 0x44e6, 0x8c,0x32, 0x88,0xfd,0x5f,0x44,0xc8,0x4c); +DEFINE_GUID(IID_IDXGIFactory, 0x7b7166ec, 0x21c7, 0x44ae, 0xb2,0x1a, 0xc9,0xae,0x32,0x1a,0xe3,0x69); +DEFINE_GUID(IID_ID3D11ClassLinkage, 0xddf57cba, 0x9543, 0x46e4, 0xa1,0x2b, 0xf2,0x07,0xa0,0xfe,0x7f,0xed); +DEFINE_GUID(IID_ID3D10VertexShader, 0x9b7e4c0a, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Texture2D1, 0x51218251, 0x1e33, 0x4617, 0x9c,0xcb, 0x4d,0x3a,0x43,0x67,0xe7,0xbb); +DEFINE_GUID(IID_ID3D11BlendState1, 0xcc86fabe, 0xda55, 0x401d, 0x85,0xe7, 0xe3,0xc9,0xde,0x28,0x77,0xe9); +DEFINE_GUID(IID_ID3D11UnorderedAccessView1, 0x7b3b6153, 0xa886, 0x4544, 0xab,0x37, 0x65,0x37,0xc8,0x50,0x04,0x03); +DEFINE_GUID(IID_ID3D10View, 0xc902b03f, 0x60a7, 0x49ba, 0x99,0x36, 0x2a,0x3a,0xb3,0x7a,0x7e,0x33); +DEFINE_GUID(IID_ID3D10RenderTargetView, 0x9b7e4c08, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10ShaderResourceView1, 0x9b7e4c87, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Buffer, 0x9b7e4c02, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Resource, 0x9b7e4c01, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Buffer, 0x48570b85, 0xd1ee, 0x4fcd, 0xa2,0x50, 0xeb,0x35,0x07,0x22,0xb0,0x37); +DEFINE_GUID(IID_ID3D11Resource, 0xdc8e63f3, 0xd12b, 0x4952, 0xb4,0x7b, 0x5e,0x45,0x02,0x6a,0x86,0x2d); +DEFINE_GUID(IID_ID3D10Predicate, 0x9b7e4c10, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Query, 0x9b7e4c0e, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Asynchronous, 0x9b7e4c0d, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D11Predicate, 0x9eb576dd, 0x9f77, 0x4d86, 0x81,0xaa, 0x8b,0xab,0x5f,0xe4,0x90,0xe2); +DEFINE_GUID(IID_ID3D11Query, 0xd6c00747, 0x87b7, 0x425e, 0xb8,0x4d, 0x44,0xd1,0x08,0x56,0x0a,0xfd); +DEFINE_GUID(IID_ID3D11Query1, 0x631b4766, 0x36dc, 0x461d, 0x8d,0xb6, 0xc4,0x7e,0x13,0xe6,0x09,0x16); +DEFINE_GUID(IID_ID3D11Asynchronous, 0x4b35d0cd, 0x1e15, 0x4258, 0x9c,0x98, 0x1b,0x13,0x33,0xf6,0xdd,0x3b); +DEFINE_GUID(IID_ID3D11DeviceChild, 0x1841e5c8, 0x16b0, 0x489b, 0xbc,0xc8, 0x44,0xcf,0xb0,0xd5,0xde,0xae); +DEFINE_GUID(IID_ID3D10Device1, 0x9b7e4c8f, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10DeviceChild, 0x9b7e4c00, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); +DEFINE_GUID(IID_ID3D10Device, 0x9b7e4c0f, 0x342c, 0x4106, 0xa1,0x9f, 0x4f,0x27,0x04,0xf6,0x89,0xf0); + + /* FIXME - find a better place for these, needed for dsound */ DEFINE_GUID(CLSID_DirectSoundPrivate, 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); DEFINE_GUID(DSPROPSETID_DirectSoundDevice, 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); diff --git a/sdk/tools/winesync/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff b/sdk/tools/winesync/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff new file mode 100644 index 00000000000..4cc1a420739 --- /dev/null +++ b/sdk/tools/winesync/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff @@ -0,0 +1,28 @@ +diff --git a/sdk/tools/winesync/ddraw_staging/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff b/sdk/tools/winesync/ddraw_staging/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff +new file mode 100644 +index 00000000000..a92d5bd906c +--- /dev/null ++++ b/sdk/tools/winesync/ddraw_staging/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff +@@ -0,0 +1,22 @@ ++diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c ++index 5fc7a4b..ab6bada 100644 ++--- a/dll/directx/wine/ddraw/viewport.c +++++ b/dll/directx/wine/ddraw/viewport.c ++@@ -1220,7 +1220,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *ifa ++ /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ ++ if (!iface) return NULL; ++ assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl); ++- return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); +++ return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); ++ } ++ ++ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface) ++@@ -1228,7 +1228,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface ++ /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ ++ if (!iface) return NULL; ++ assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl); ++- return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); +++ return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); ++ } ++ ++ void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) diff --git a/sdk/tools/winesync/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff b/sdk/tools/winesync/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff new file mode 100644 index 00000000000..3e11e2435e9 --- /dev/null +++ b/sdk/tools/winesync/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff @@ -0,0 +1,169 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index 6da0e20f622..fe507dea81b 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -5171,7 +5171,8 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ + d3d_info->limits.gs_version = shader_caps.gs_version; + d3d_info->limits.ps_version = shader_caps.ps_version; + d3d_info->limits.cs_version = shader_caps.cs_version; +- d3d_info->limits.vs_uniform_count = shader_caps.vs_uniform_count; ++ d3d_info->limits.vs_uniform_count_swvp = shader_caps.vs_uniform_count; ++ d3d_info->limits.vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, shader_caps.vs_uniform_count); + d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count; + d3d_info->limits.varying_count = shader_caps.varying_count; + d3d_info->limits.ffp_textures = fragment_caps.MaxSimultaneousTextures; +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 7793c5440c6..86e959941cc 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4078,17 +4078,26 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d + + HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps) + { ++#if defined(STAGING_CSMT) ++ const struct wined3d_adapter *adapter = device->wined3d->adapters[device->adapter->ordinal]; ++ struct wined3d_vertex_caps vertex_caps; + HRESULT hr; + +- TRACE("device %p, caps %p.\n", device, caps); ++ TRACE("device %p, caps %p.\n", device, caps); + + hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, +- device->create_parms.device_type, caps); +- +- if (SUCCEEDED(hr) && use_software_vertex_processing(device)) +- caps->MaxVertexBlendMatrixIndex = 255; ++ device->create_parms.device_type, caps); ++ if (FAILED(hr)) ++ return hr; + ++ adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); ++ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; + return hr; ++#else ++ return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, ++ device->create_parms.device_type, caps); ++#endif + } + + HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 5f4e381dbc8..e9206ab62ec 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -11233,7 +11233,10 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s + caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0; + caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0; + +- caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants); ++ caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F_SWVP, ++ gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] ++ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) ++ : gl_info->limits.glsl_vs_float_constants); + caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants); + caps->varying_count = gl_info->limits.glsl_varyings; + +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 4f6cf914d25..abafa038c58 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -167,6 +167,7 @@ struct wined3d_d3d_limits + { + unsigned int vs_version, hs_version, ds_version, gs_version, ps_version, cs_version; + DWORD vs_uniform_count; ++ DWORD vs_uniform_count_swvp; + DWORD ps_uniform_count; + unsigned int varying_count; + unsigned int ffp_textures; +@@ -710,6 +711,7 @@ enum wined3d_shader_conditional_op + #define WINED3D_MAX_CONSTS_B 16 + #define WINED3D_MAX_CONSTS_I 16 + #define WINED3D_MAX_VS_CONSTS_F 256 ++#define WINED3D_MAX_VS_CONSTS_F_SWVP 8192 + #define WINED3D_MAX_PS_CONSTS_F 224 + + /* FIXME: This needs to go up to 2048 for +diff --git a/sdk/tools/winesync/wined3d_staging/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff b/sdk/tools/winesync/wined3d_staging/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff +new file mode 100644 +index 00000000000..418db1eb0eb +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff +@@ -0,0 +1,77 @@ ++diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c ++index 6da0e20..fe507de 100644 ++--- a/dll/directx/wine/wined3d/adapter_gl.c +++++ b/dll/directx/wine/wined3d/adapter_gl.c ++@@ -5171,7 +5171,8 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ ++ d3d_info->limits.gs_version = shader_caps.gs_version; ++ d3d_info->limits.ps_version = shader_caps.ps_version; ++ d3d_info->limits.cs_version = shader_caps.cs_version; ++- d3d_info->limits.vs_uniform_count = shader_caps.vs_uniform_count; +++ d3d_info->limits.vs_uniform_count_swvp = shader_caps.vs_uniform_count; +++ d3d_info->limits.vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, shader_caps.vs_uniform_count); ++ d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count; ++ d3d_info->limits.varying_count = shader_caps.varying_count; ++ d3d_info->limits.ffp_textures = fragment_caps.MaxSimultaneousTextures; ++diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c ++index 90d04e6..ac720b9 100644 ++--- a/dll/directx/wine/wined3d/device.c +++++ b/dll/directx/wine/wined3d/device.c ++@@ -4076,10 +4076,21 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d ++ ++ HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps) ++ { +++ const struct wined3d_adapter *adapter = device->wined3d->adapters[device->adapter->ordinal]; +++ struct wined3d_vertex_caps vertex_caps; +++ HRESULT hr; +++ ++ TRACE("device %p, caps %p.\n", device, caps); ++ ++- return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, +++ hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, ++ device->create_parms.device_type, caps); +++ if (FAILED(hr)) +++ return hr; +++ +++ adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); +++ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) +++ caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; +++ return hr; ++ } ++ ++ HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, ++diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c ++index 039bec0..c9612c8 100644 ++--- a/dll/directx/wine/wined3d/glsl_shader.c +++++ b/dll/directx/wine/wined3d/glsl_shader.c ++@@ -11233,7 +11233,10 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s ++ caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0; ++ caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0; ++ ++- caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants); +++ caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F_SWVP, +++ gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] +++ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) +++ : gl_info->limits.glsl_vs_float_constants); ++ caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants); ++ caps->varying_count = gl_info->limits.glsl_varyings; ++ ++diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h ++index 731b44a..6a7dc4f 100644 ++--- a/dll/directx/wine/wined3d/wined3d_private.h +++++ b/dll/directx/wine/wined3d/wined3d_private.h ++@@ -167,6 +167,7 @@ struct wined3d_d3d_limits ++ { ++ unsigned int vs_version, hs_version, ds_version, gs_version, ps_version, cs_version; ++ DWORD vs_uniform_count; +++ DWORD vs_uniform_count_swvp; ++ DWORD ps_uniform_count; ++ unsigned int varying_count; ++ unsigned int ffp_textures; ++@@ -703,6 +704,7 @@ enum wined3d_shader_conditional_op ++ #define WINED3D_MAX_CONSTS_B 16 ++ #define WINED3D_MAX_CONSTS_I 16 ++ #define WINED3D_MAX_VS_CONSTS_F 256 +++#define WINED3D_MAX_VS_CONSTS_F_SWVP 8192 ++ #define WINED3D_MAX_PS_CONSTS_F 224 ++ ++ /* FIXME: This needs to go up to 2048 for diff --git a/sdk/tools/winesync/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff b/sdk/tools/winesync/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff new file mode 100644 index 00000000000..3115f716bf3 --- /dev/null +++ b/sdk/tools/winesync/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff @@ -0,0 +1,814 @@ +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index b5cd303446c..ae105cb5873 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4530,7 +4530,14 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device + void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software) + { + TRACE("device %p, software %#x.\n", device, software); ++ wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); ++ if (!device->softwareVertexProcessing != !software) ++ { ++ unsigned int i; + ++ for (i = 0; i < device->context_count; ++i) ++ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; ++ } + device->softwareVertexProcessing = software; + } + +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index f2a90f6afe4..a67d7090d34 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -140,7 +140,9 @@ struct shader_glsl_priv + + BOOL consts_ubo; + GLuint ubo_vs_c; +- struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F]; ++ BOOL prev_device_swvp; ++ struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F_SWVP]; ++ unsigned int max_vs_consts_f; + + const struct wined3d_vertex_pipe_ops *vertex_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; +@@ -155,7 +157,7 @@ struct glsl_vs_program + struct list shader_entry; + GLuint id; + GLenum vertex_color_clamp; +- GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F]; ++ GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F_SWVP]; + GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; + GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; + GLint pos_fixup_location; +@@ -1193,7 +1195,7 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st + { + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); + checkGLcall("glBindBuffer"); +- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); + } +@@ -1201,14 +1203,16 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st + /* Context activation is done by the caller. */ + static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, + const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, +- unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv) ++ unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv, BOOL device_swvp) + { + const struct wined3d_shader_lconst *lconst; + BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX; + + if (is_vertex_shader && priv->consts_ubo) + { ++ BOOL zero_sw_constants = !device_swvp && priv->prev_device_swvp; + const struct wined3d_vec4 *data; ++ unsigned int const_count; + unsigned max_const_used; + + if (priv->ubo_vs_c == -1) +@@ -1218,22 +1222,32 @@ static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, co + } + + bind_and_orphan_consts_ubo(gl_info, priv); +- max_const_used = shader->reg_maps.usesrelconstF +- ? WINED3D_MAX_VS_CONSTS_F : shader->reg_maps.constant_float_count; +- if (shader->load_local_constsF) ++ const_count = device_swvp ? priv->max_vs_consts_f : WINED3D_MAX_VS_CONSTS_F; ++ max_const_used = shader->reg_maps.usesrelconstF ? const_count : shader->reg_maps.constant_float_count; ++ if (shader->load_local_constsF || (zero_sw_constants && shader->reg_maps.usesrelconstF)) + { + data = priv->vs_c_buffer; + memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants)); +- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) ++ if (zero_sw_constants) + { +- priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; ++ memset(&priv->vs_c_buffer[const_count], 0, (priv->max_vs_consts_f - WINED3D_MAX_VS_CONSTS_F) ++ * sizeof(*constants)); ++ priv->prev_device_swvp = FALSE; ++ } ++ if (shader->load_local_constsF) ++ { ++ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) ++ { ++ priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; ++ } + } + } + else + { + data = constants; + } +- GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) * max_const_used, data)); ++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) ++ * (zero_sw_constants ? priv->max_vs_consts_f : max_const_used), data)); + checkGLcall("glBufferSubData"); + return; + } +@@ -1601,7 +1615,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); + checkGLcall("glBindBuffer (UBO)"); +- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); + } +@@ -1613,7 +1627,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + + if (update_mask & WINED3D_SHADER_CONST_VS_F) + shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f, +- prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version, priv); ++ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, ++ constant_version, priv, device_is_swvp(context->device)); + + if (update_mask & WINED3D_SHADER_CONST_VS_I) + shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i, +@@ -1766,7 +1781,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + + if (update_mask & WINED3D_SHADER_CONST_PS_F) + shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f, +- prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, priv); ++ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, ++ priv, FALSE); + + if (update_mask & WINED3D_SHADER_CONST_PS_I) + shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i, +@@ -1911,7 +1927,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev + if (priv->consts_ubo) + return; + +- for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i) ++ for (i = start; i < count + start; ++i) + { + update_heap_entry(heap, i, priv->next_constant_version); + } +@@ -2265,7 +2281,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c + shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n" + "{ \n" + " vec4 %s_c[%u];\n" +- "};\n", prefix, min(shader->limits->constant_float, WINED3D_MAX_VS_CONSTS_F)); ++ "};\n", prefix, min(shader->limits->constant_float, priv->max_vs_consts_f)); + } + else if (shader->limits->constant_float > 0) + { +@@ -9975,12 +9991,13 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * + } + else if (!priv->consts_ubo) + { +- for (i = 0; i < vs_c_count; ++i) ++ for (i = 0; i < min(vs_c_count, priv->max_vs_consts_f); ++i) + { + string_buffer_sprintf(name, "vs_c[%u]", i); + vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } +- memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); ++ if (vs_c_count < priv->max_vs_consts_f) ++ memset(&vs->uniform_f_locations[vs_c_count], 0xff, (priv->max_vs_consts_f - vs_c_count) * sizeof(GLuint)); + } + + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) +@@ -10298,6 +10315,10 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, + vs_list = &ffp_shader->linked_programs; + } + ++ if (vshader && vshader->reg_maps.constant_float_count > WINED3D_MAX_VS_CONSTS_F ++ && !device_is_swvp(context_gl->c.device)) ++ FIXME("Applying context with SW shader in HW mode.\n"); ++ + hshader = state->shader[WINED3D_SHADER_TYPE_HULL]; + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program) + hs_id = ctx_data->glsl_program->hs.id; +@@ -11055,7 +11076,7 @@ static void constant_heap_free(struct constant_heap *heap) + static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, + const struct wined3d_fragment_pipe_ops *fragment_pipe) + { +- SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1; ++ SIZE_T stack_size; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct fragment_caps fragment_caps; + void *vertex_priv, *fragment_priv; +@@ -11066,6 +11087,18 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + + priv->consts_ubo = (device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS) + && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]; ++ priv->max_vs_consts_f = min(WINED3D_MAX_VS_CONSTS_F_SWVP, priv->consts_ubo ++ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) ++ : gl_info->limits.glsl_vs_float_constants); ++ ++ if (!(device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING))) ++ priv->max_vs_consts_f = min(priv->max_vs_consts_f, WINED3D_MAX_VS_CONSTS_F); ++ ++ stack_size = priv->consts_ubo ++ ? wined3d_log2i(WINED3D_MAX_PS_CONSTS_F) + 1 ++ : wined3d_log2i(max(priv->max_vs_consts_f, WINED3D_MAX_PS_CONSTS_F)) + 1; ++ TRACE("consts_ubo %#x, max_vs_consts_f %u.\n", priv->consts_ubo, priv->max_vs_consts_f); ++ + string_buffer_list_init(&priv->string_buffers); + + if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv))) +@@ -11095,7 +11128,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + goto fail; + } + +- if (!constant_heap_init(&priv->vconst_heap, WINED3D_MAX_VS_CONSTS_F)) ++ if (!priv->consts_ubo && !constant_heap_init(&priv->vconst_heap, priv->max_vs_consts_f)) + { + ERR("Failed to initialize vertex shader constant heap\n"); + goto fail; +diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c +index e572751be83..de4776b30c1 100644 +--- a/dll/directx/wine/wined3d/shader.c ++++ b/dll/directx/wine/wined3d/shader.c +@@ -592,7 +592,7 @@ static void shader_delete_constant_list(struct list *clist) + list_init(clist); + } + +-static void shader_set_limits(struct wined3d_shader *shader) ++static void shader_set_limits(struct wined3d_shader *shader, BOOL swvp) + { + static const struct limits_entry + { +@@ -615,6 +615,19 @@ static void shader_set_limits(struct wined3d_shader *shader) + {WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}}, + {0} + }, ++ vs_limits_swvp[] = ++ { ++ /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */ ++ {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0, 0, 8192, 0, 12, 0}}, ++ {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 255), { 0, 16, 8192, 16, 12, 0}}, ++ /* DX10 cards on Windows advertise a D3D9 constant limit of 256 ++ * even though they are capable of supporting much more (GL ++ * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the ++ * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 ++ * shaders to 256. */ ++ {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 255), { 4, 16, 8192, 16, 12, 0}}, ++ {0} ++ }, + hs_limits[] = + { + /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */ +@@ -659,7 +672,7 @@ static void shader_set_limits(struct wined3d_shader *shader) + FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type); + /* Fall-through. */ + case WINED3D_SHADER_TYPE_VERTEX: +- limits_array = vs_limits; ++ limits_array = swvp ? vs_limits_swvp : vs_limits; + break; + case WINED3D_SHADER_TYPE_HULL: + limits_array = hs_limits; +@@ -1027,7 +1040,7 @@ static HRESULT shader_scan_output_signature(struct wined3d_shader *shader) + } + + /* Note that this does not count the loop register as an address register. */ +-static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size) ++static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size, BOOL swvp) + { + struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)]; + struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT]; +@@ -1053,7 +1066,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co + prev_ins = current_ins = ptr; + reg_maps->shader_version = shader_version; + +- shader_set_limits(shader); ++ shader_set_limits(shader, swvp); + + if (!(reg_maps->constf = heap_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32), + sizeof(*reg_maps->constf)))) +@@ -3325,7 +3338,7 @@ static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_l + } + + static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, +- enum wined3d_shader_type type, unsigned int float_const_count) ++ enum wined3d_shader_type type, unsigned int float_const_count, BOOL swvp) + { + const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; + struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; +@@ -3350,7 +3363,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d + shader_trace_init(fe, shader->frontend_data); + + /* Second pass: figure out which registers are used, what the semantics are, etc. */ +- if (FAILED(hr = shader_get_registers_used(shader, float_const_count))) ++ if (FAILED(hr = shader_get_registers_used(shader, float_const_count, swvp))) + return hr; + + if (version->type != type) +@@ -3689,14 +3702,19 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ + const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) + { + struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; ++ unsigned int vs_uniform_count; + unsigned int i; + HRESULT hr; ++ BOOL swvp = device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING ++ | WINED3DCREATE_MIXED_VERTEXPROCESSING); + + if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) + return hr; + ++ vs_uniform_count = swvp ? device->adapter->d3d_info.limits.vs_uniform_count_swvp ++ : device->adapter->d3d_info.limits.vs_uniform_count; + if (FAILED(hr = shader_set_function(shader, device, +- WINED3D_SHADER_TYPE_VERTEX, device->adapter->d3d_info.limits.vs_uniform_count))) ++ WINED3D_SHADER_TYPE_VERTEX, vs_uniform_count, swvp))) + { + shader_cleanup(shader); + return hr; +@@ -3800,7 +3818,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, + { + shader->reg_maps.shader_version = shader_version; + shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; +- shader_set_limits(shader); ++ shader_set_limits(shader, 0); + if (FAILED(hr = shader_scan_output_signature(shader))) + return hr; + } +@@ -3853,7 +3871,7 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 + goto fail; + + if (shader->function +- && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0))) ++ && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0, 0))) + goto fail; + + return WINED3D_OK; +@@ -4185,7 +4203,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d + return hr; + + if (FAILED(hr = shader_set_function(shader, device, +- WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count))) ++ WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count, 0))) + { + shader_cleanup(shader); + return hr; +@@ -4277,7 +4295,7 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru + return hr; + } + +- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0))) ++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0, 0))) + { + shader_cleanup(object); + heap_free(object); +@@ -4311,7 +4329,7 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru + return hr; + } + +- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0))) ++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0, 0))) + { + shader_cleanup(object); + heap_free(object); +@@ -4373,7 +4391,7 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru + return hr; + } + +- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0))) ++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0, 0))) + { + shader_cleanup(object); + heap_free(object); +diff --git a/dll/directx/wine/wined3d/shader_sm1.c b/dll/directx/wine/wined3d/shader_sm1.c +index 0c6bb933174..1051307e88c 100644 +--- a/dll/directx/wine/wined3d/shader_sm1.c ++++ b/dll/directx/wine/wined3d/shader_sm1.c +@@ -543,7 +543,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size, + + major = WINED3D_SM1_VERSION_MAJOR(*byte_code); + minor = WINED3D_SM1_VERSION_MINOR(*byte_code); +- if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0)) ++ if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 255)) + { + WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code); + return NULL; +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 9a9846a6015..4089921c771 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -4916,6 +4916,13 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, + return FALSE; + } + ++static inline BOOL device_is_swvp(const struct wined3d_device *device) ++{ ++ return (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ && device->softwareVertexProcessing); ++} ++ + void get_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN; + void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, + unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN; +diff --git a/sdk/tools/winesync/wined3d_staging/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff b/sdk/tools/winesync/wined3d_staging/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff +new file mode 100644 +index 00000000000..305aa1fbaa4 +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff +@@ -0,0 +1,404 @@ ++diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c ++index 33e2951..d56ae07 100644 ++--- a/dll/directx/wine/wined3d/device.c +++++ b/dll/directx/wine/wined3d/device.c ++@@ -4532,6 +4532,14 @@ void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device * ++ warned = TRUE; ++ } ++ +++ wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); +++ if (!device->softwareVertexProcessing != !software) +++ { +++ unsigned int i; +++ +++ for (i = 0; i < device->context_count; ++i) +++ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; +++ } ++ device->softwareVertexProcessing = software; ++ } ++ ++diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c ++index 050d94c..0c3955f 100644 ++--- a/dll/directx/wine/wined3d/glsl_shader.c +++++ b/dll/directx/wine/wined3d/glsl_shader.c ++@@ -140,7 +140,9 @@ struct shader_glsl_priv ++ ++ BOOL consts_ubo; ++ GLuint ubo_vs_c; ++- struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F]; +++ BOOL prev_device_swvp; +++ struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F_SWVP]; +++ unsigned int max_vs_consts_f; ++ ++ const struct wined3d_vertex_pipe_ops *vertex_pipe; ++ const struct wined3d_fragment_pipe_ops *fragment_pipe; ++@@ -155,7 +157,7 @@ struct glsl_vs_program ++ struct list shader_entry; ++ GLuint id; ++ GLenum vertex_color_clamp; ++- GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F]; +++ GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F_SWVP]; ++ GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; ++ GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; ++ GLint pos_fixup_location; ++@@ -1193,7 +1195,7 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st ++ { ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); ++ checkGLcall("glBindBuffer"); ++- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), +++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); ++ } ++@@ -1201,14 +1203,16 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st ++ /* Context activation is done by the caller. */ ++ static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, ++ const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, ++- unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv) +++ unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv, BOOL device_swvp) ++ { ++ const struct wined3d_shader_lconst *lconst; ++ BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX; ++ ++ if (is_vertex_shader && priv->consts_ubo) ++ { +++ BOOL zero_sw_constants = !device_swvp && priv->prev_device_swvp; ++ const struct wined3d_vec4 *data; +++ unsigned int const_count; ++ unsigned max_const_used; ++ ++ if (priv->ubo_vs_c == -1) ++@@ -1218,22 +1222,32 @@ static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, co ++ } ++ ++ bind_and_orphan_consts_ubo(gl_info, priv); ++- max_const_used = shader->reg_maps.usesrelconstF ++- ? WINED3D_MAX_VS_CONSTS_F : shader->reg_maps.constant_float_count; ++- if (shader->load_local_constsF) +++ const_count = device_swvp ? priv->max_vs_consts_f : WINED3D_MAX_VS_CONSTS_F; +++ max_const_used = shader->reg_maps.usesrelconstF ? const_count : shader->reg_maps.constant_float_count; +++ if (shader->load_local_constsF || (zero_sw_constants && shader->reg_maps.usesrelconstF)) ++ { ++ data = priv->vs_c_buffer; ++ memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants)); ++- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) +++ if (zero_sw_constants) ++ { ++- priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; +++ memset(&priv->vs_c_buffer[const_count], 0, (priv->max_vs_consts_f - WINED3D_MAX_VS_CONSTS_F) +++ * sizeof(*constants)); +++ priv->prev_device_swvp = FALSE; +++ } +++ if (shader->load_local_constsF) +++ { +++ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) +++ { +++ priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; +++ } ++ } ++ } ++ else ++ { ++ data = constants; ++ } ++- GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) * max_const_used, data)); +++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) +++ * (zero_sw_constants ? priv->max_vs_consts_f : max_const_used), data)); ++ checkGLcall("glBufferSubData"); ++ return; ++ } ++@@ -1601,7 +1615,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++ GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); ++ checkGLcall("glBindBuffer (UBO)"); ++- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), +++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); ++ } ++@@ -1613,7 +1627,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++ ++ if (update_mask & WINED3D_SHADER_CONST_VS_F) ++ shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f, ++- prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version, priv); +++ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, +++ constant_version, priv, device_is_swvp(context->device)); ++ ++ if (update_mask & WINED3D_SHADER_CONST_VS_I) ++ shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i, ++@@ -1766,7 +1781,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++ ++ if (update_mask & WINED3D_SHADER_CONST_PS_F) ++ shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f, ++- prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, priv); +++ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, +++ priv, FALSE); ++ ++ if (update_mask & WINED3D_SHADER_CONST_PS_I) ++ shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i, ++@@ -1911,7 +1927,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev ++ if (priv->consts_ubo) ++ return; ++ ++- for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i) +++ for (i = start; i < count + start; ++i) ++ { ++ update_heap_entry(heap, i, priv->next_constant_version); ++ } ++@@ -2265,7 +2281,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c ++ shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n" ++ "{ \n" ++ " vec4 %s_c[%u];\n" ++- "};\n", prefix, min(shader->limits->constant_float, WINED3D_MAX_VS_CONSTS_F)); +++ "};\n", prefix, min(shader->limits->constant_float, priv->max_vs_consts_f)); ++ } ++ else if (shader->limits->constant_float > 0) ++ { ++@@ -9975,12 +9991,13 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * ++ } ++ else if (!priv->consts_ubo) ++ { ++- for (i = 0; i < vs_c_count; ++i) +++ for (i = 0; i < min(vs_c_count, priv->max_vs_consts_f); ++i) ++ { ++ string_buffer_sprintf(name, "vs_c[%u]", i); ++ vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); ++ } ++- memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); +++ if (vs_c_count < priv->max_vs_consts_f) +++ memset(&vs->uniform_f_locations[vs_c_count], 0xff, (priv->max_vs_consts_f - vs_c_count) * sizeof(GLuint)); ++ } ++ ++ for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) ++@@ -10298,6 +10315,10 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, ++ vs_list = &ffp_shader->linked_programs; ++ } ++ +++ if (vshader && vshader->reg_maps.constant_float_count > WINED3D_MAX_VS_CONSTS_F +++ && !device_is_swvp(context_gl->c.device)) +++ FIXME("Applying context with SW shader in HW mode.\n"); +++ ++ hshader = state->shader[WINED3D_SHADER_TYPE_HULL]; ++ if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program) ++ hs_id = ctx_data->glsl_program->hs.id; ++@@ -11055,7 +11076,7 @@ static void constant_heap_free(struct constant_heap *heap) ++ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, ++ const struct wined3d_fragment_pipe_ops *fragment_pipe) ++ { ++- SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1; +++ SIZE_T stack_size; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ struct fragment_caps fragment_caps; ++ void *vertex_priv, *fragment_priv; ++@@ -11066,6 +11087,18 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win ++ ++ priv->consts_ubo = (device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS) ++ && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]; +++ priv->max_vs_consts_f = min(WINED3D_MAX_VS_CONSTS_F_SWVP, priv->consts_ubo +++ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) +++ : gl_info->limits.glsl_vs_float_constants); +++ +++ if (!(device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING))) +++ priv->max_vs_consts_f = min(priv->max_vs_consts_f, WINED3D_MAX_VS_CONSTS_F); +++ +++ stack_size = priv->consts_ubo +++ ? wined3d_log2i(WINED3D_MAX_PS_CONSTS_F) + 1 +++ : wined3d_log2i(max(priv->max_vs_consts_f, WINED3D_MAX_PS_CONSTS_F)) + 1; +++ TRACE("consts_ubo %#x, max_vs_consts_f %u.\n", priv->consts_ubo, priv->max_vs_consts_f); +++ ++ string_buffer_list_init(&priv->string_buffers); ++ ++ if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv))) ++@@ -11095,7 +11128,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win ++ goto fail; ++ } ++ ++- if (!constant_heap_init(&priv->vconst_heap, WINED3D_MAX_VS_CONSTS_F)) +++ if (!priv->consts_ubo && !constant_heap_init(&priv->vconst_heap, priv->max_vs_consts_f)) ++ { ++ ERR("Failed to initialize vertex shader constant heap\n"); ++ goto fail; ++diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c ++index e572751..de4776b 100644 ++--- a/dll/directx/wine/wined3d/shader.c +++++ b/dll/directx/wine/wined3d/shader.c ++@@ -592,7 +592,7 @@ static void shader_delete_constant_list(struct list *clist) ++ list_init(clist); ++ } ++ ++-static void shader_set_limits(struct wined3d_shader *shader) +++static void shader_set_limits(struct wined3d_shader *shader, BOOL swvp) ++ { ++ static const struct limits_entry ++ { ++@@ -615,6 +615,19 @@ static void shader_set_limits(struct wined3d_shader *shader) ++ {WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}}, ++ {0} ++ }, +++ vs_limits_swvp[] = +++ { +++ /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */ +++ {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0, 0, 8192, 0, 12, 0}}, +++ {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 255), { 0, 16, 8192, 16, 12, 0}}, +++ /* DX10 cards on Windows advertise a D3D9 constant limit of 256 +++ * even though they are capable of supporting much more (GL +++ * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the +++ * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 +++ * shaders to 256. */ +++ {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 255), { 4, 16, 8192, 16, 12, 0}}, +++ {0} +++ }, ++ hs_limits[] = ++ { ++ /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */ ++@@ -659,7 +672,7 @@ static void shader_set_limits(struct wined3d_shader *shader) ++ FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type); ++ /* Fall-through. */ ++ case WINED3D_SHADER_TYPE_VERTEX: ++- limits_array = vs_limits; +++ limits_array = swvp ? vs_limits_swvp : vs_limits; ++ break; ++ case WINED3D_SHADER_TYPE_HULL: ++ limits_array = hs_limits; ++@@ -1027,7 +1040,7 @@ static HRESULT shader_scan_output_signature(struct wined3d_shader *shader) ++ } ++ ++ /* Note that this does not count the loop register as an address register. */ ++-static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size) +++static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size, BOOL swvp) ++ { ++ struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)]; ++ struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT]; ++@@ -1053,7 +1066,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co ++ prev_ins = current_ins = ptr; ++ reg_maps->shader_version = shader_version; ++ ++- shader_set_limits(shader); +++ shader_set_limits(shader, swvp); ++ ++ if (!(reg_maps->constf = heap_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32), ++ sizeof(*reg_maps->constf)))) ++@@ -3325,7 +3338,7 @@ static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_l ++ } ++ ++ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, ++- enum wined3d_shader_type type, unsigned int float_const_count) +++ enum wined3d_shader_type type, unsigned int float_const_count, BOOL swvp) ++ { ++ const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; ++ struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; ++@@ -3350,7 +3363,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d ++ shader_trace_init(fe, shader->frontend_data); ++ ++ /* Second pass: figure out which registers are used, what the semantics are, etc. */ ++- if (FAILED(hr = shader_get_registers_used(shader, float_const_count))) +++ if (FAILED(hr = shader_get_registers_used(shader, float_const_count, swvp))) ++ return hr; ++ ++ if (version->type != type) ++@@ -3689,14 +3702,19 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ ++ const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) ++ { ++ struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; +++ unsigned int vs_uniform_count; ++ unsigned int i; ++ HRESULT hr; +++ BOOL swvp = device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING +++ | WINED3DCREATE_MIXED_VERTEXPROCESSING); ++ ++ if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) ++ return hr; ++ +++ vs_uniform_count = swvp ? device->adapter->d3d_info.limits.vs_uniform_count_swvp +++ : device->adapter->d3d_info.limits.vs_uniform_count; ++ if (FAILED(hr = shader_set_function(shader, device, ++- WINED3D_SHADER_TYPE_VERTEX, device->adapter->d3d_info.limits.vs_uniform_count))) +++ WINED3D_SHADER_TYPE_VERTEX, vs_uniform_count, swvp))) ++ { ++ shader_cleanup(shader); ++ return hr; ++@@ -3800,7 +3818,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, ++ { ++ shader->reg_maps.shader_version = shader_version; ++ shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; ++- shader_set_limits(shader); +++ shader_set_limits(shader, 0); ++ if (FAILED(hr = shader_scan_output_signature(shader))) ++ return hr; ++ } ++@@ -3853,7 +3871,7 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 ++ goto fail; ++ ++ if (shader->function ++- && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0))) +++ && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0, 0))) ++ goto fail; ++ ++ return WINED3D_OK; ++@@ -4185,7 +4203,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d ++ return hr; ++ ++ if (FAILED(hr = shader_set_function(shader, device, ++- WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count))) +++ WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count, 0))) ++ { ++ shader_cleanup(shader); ++ return hr; ++@@ -4277,7 +4295,7 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru ++ return hr; ++ } ++ ++- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0))) +++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0, 0))) ++ { ++ shader_cleanup(object); ++ heap_free(object); ++@@ -4311,7 +4329,7 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru ++ return hr; ++ } ++ ++- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0))) +++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0, 0))) ++ { ++ shader_cleanup(object); ++ heap_free(object); ++@@ -4373,7 +4391,7 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru ++ return hr; ++ } ++ ++- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0))) +++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0, 0))) ++ { ++ shader_cleanup(object); ++ heap_free(object); ++diff --git a/dll/directx/wine/wined3d/shader_sm1.c b/dll/directx/wine/wined3d/shader_sm1.c ++index 0c6bb93..1051307 100644 ++--- a/dll/directx/wine/wined3d/shader_sm1.c +++++ b/dll/directx/wine/wined3d/shader_sm1.c ++@@ -543,7 +543,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size, ++ ++ major = WINED3D_SM1_VERSION_MAJOR(*byte_code); ++ minor = WINED3D_SM1_VERSION_MINOR(*byte_code); ++- if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0)) +++ if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 255)) ++ { ++ WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code); ++ return NULL; ++diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h ++index efe41f8..daccc13 100644 ++--- a/dll/directx/wine/wined3d/wined3d_private.h +++++ b/dll/directx/wine/wined3d/wined3d_private.h ++@@ -4884,6 +4884,13 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, ++ return FALSE; ++ } ++ +++static inline BOOL device_is_swvp(const struct wined3d_device *device) +++{ +++ return (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) +++ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) +++ && device->softwareVertexProcessing); +++} +++ ++ void get_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN; ++ void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, ++ unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN; diff --git a/sdk/tools/winesync/0011-wined3d__Allow_higher_world_matrix_states.diff b/sdk/tools/winesync/0011-wined3d__Allow_higher_world_matrix_states.diff new file mode 100644 index 00000000000..7c86ab546a7 --- /dev/null +++ b/sdk/tools/winesync/0011-wined3d__Allow_higher_world_matrix_states.diff @@ -0,0 +1,762 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index fe507dea81b..06fbc518d97 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -5180,6 +5180,7 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ + TRACE("Max texture stages: %u.\n", d3d_info->limits.ffp_blend_stages); + d3d_info->limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; + d3d_info->limits.active_light_count = vertex_caps.max_active_lights; ++ d3d_info->limits.ffp_max_vertex_blend_matrix_index = vertex_caps.max_vertex_blend_matrix_index; + + d3d_info->valid_dual_rt_mask = 0; + for (i = 0; i < gl_info->limits.dual_buffers; ++i) +diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c +index f94c570620b..867b66b1270 100644 +--- a/dll/directx/wine/wined3d/cs.c ++++ b/dll/directx/wine/wined3d/cs.c +@@ -1674,7 +1674,8 @@ static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *dat + const struct wined3d_cs_set_transform *op = data; + + cs->state.transforms[op->state] = op->matrix; +- if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) ++ if (op->state < WINED3D_TS_WORLD_MATRIX(max(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices, ++ cs->device->adapter->d3d_info.limits.ffp_max_vertex_blend_matrix_index + 1))) + device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); + } + +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index b5cd303446c..77f2f709485 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4101,6 +4101,11 @@ HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device + adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); + if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; ++ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; ++ if (!((device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ && device->softwareVertexProcessing))) ++ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); + return hr; + #else + return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, +@@ -4530,7 +4535,14 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device + void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software) + { + TRACE("device %p, software %#x.\n", device, software); ++ wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); ++ if (!device->softwareVertexProcessing != !software) ++ { ++ unsigned int i; + ++ for (i = 0; i < device->context_count; ++i) ++ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; ++ } + device->softwareVertexProcessing = software; + } + +diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c +index 726b1e37754..f366b8c5fa3 100644 +--- a/dll/directx/wine/wined3d/directx.c ++++ b/dll/directx/wine/wined3d/directx.c +@@ -2032,6 +2032,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, unsigned in + caps->MaxActiveLights = vertex_caps.max_active_lights; + caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices; + caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; ++ if (caps->DeviceType == WINED3D_DEVICE_TYPE_HAL) ++ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); + caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps; + caps->FVFCaps = vertex_caps.fvf_caps; + caps->RasterCaps |= vertex_caps.raster_caps; +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index a67d7090d34..c274f711580 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -11998,6 +11998,258 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, +diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c +index e9243308de4..26b90ba7a1b 100644 +--- a/dll/directx/wine/wined3d/state.c ++++ b/dll/directx/wine/wined3d/state.c +@@ -5416,7 +5416,8 @@ static void prune_invalid_states(struct wined3d_state_entry *state_table, const + state_table[i].apply = state_undefined; + } + +- start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(d3d_info->limits.ffp_vertex_blend_matrices)); ++ start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(max(d3d_info->limits.ffp_vertex_blend_matrices, ++ d3d_info->limits.ffp_max_vertex_blend_matrix_index + 1))); + last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)); + for (i = start; i <= last; ++i) + { +diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c +index 44f356c9546..3ff7441760e 100644 +--- a/dll/directx/wine/wined3d/utils.c ++++ b/dll/directx/wine/wined3d/utils.c +@@ -5150,11 +5150,9 @@ const char *debug_d3dtstype(enum wined3d_transform_state tstype) + TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(3)); + #undef TSTYPE_TO_STR + default: +- if (tstype > 256 && tstype < 512) +- { +- FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype); +- return ("WINED3D_TS_WORLD_MATRIX > 0"); +- } ++ if (tstype > WINED3D_TS_WORLD_MATRIX(3) && tstype < WINED3D_TS_WORLD_MATRIX(256)) ++ return ("WINED3D_TS_WORLD_MATRIX > 3"); ++ + FIXME("Unrecognized transform state %#x.\n", tstype); + return "unrecognized"; + } +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 4089921c771..d19af9f0b17 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -174,6 +174,7 @@ struct wined3d_d3d_limits + unsigned int ffp_blend_stages; + unsigned int ffp_vertex_blend_matrices; + unsigned int active_light_count; ++ unsigned int ffp_max_vertex_blend_matrix_index; + + unsigned int max_rt_count; + unsigned int max_clip_distances; +diff --git a/sdk/include/reactos/wine/wined3d.h.rej b/sdk/include/reactos/wine/wined3d.h.rej +new file mode 100644 +index 00000000000..fdb42123ceb +--- /dev/null ++++ b/sdk/include/reactos/wine/wined3d.h.rej +@@ -0,0 +1,9 @@ ++diff a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h (rejected hunks) ++@@ -1334,6 +1334,7 @@ enum wined3d_shader_type ++ #define WINED3D_NO_PRIMITIVE_RESTART 0x00000800 ++ #define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 ++ #define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 +++#define WINED3D_LEGACY_SHADER_CONSTANTS 0x00004000 ++ ++ #define WINED3D_RESZ_CODE 0x7fa05000 ++ +diff --git a/sdk/tools/winesync/wined3d_staging/0011-wined3d__Allow_higher_world_matrix_states.diff b/sdk/tools/winesync/wined3d_staging/0011-wined3d__Allow_higher_world_matrix_states.diff +new file mode 100644 +index 00000000000..4baa7797afa +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0011-wined3d__Allow_higher_world_matrix_states.diff +@@ -0,0 +1,363 @@ ++diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c ++index fe507de..06fbc51 100644 ++--- a/dll/directx/wine/wined3d/adapter_gl.c +++++ b/dll/directx/wine/wined3d/adapter_gl.c ++@@ -5180,6 +5180,7 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ ++ TRACE("Max texture stages: %u.\n", d3d_info->limits.ffp_blend_stages); ++ d3d_info->limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; ++ d3d_info->limits.active_light_count = vertex_caps.max_active_lights; +++ d3d_info->limits.ffp_max_vertex_blend_matrix_index = vertex_caps.max_vertex_blend_matrix_index; ++ ++ d3d_info->valid_dual_rt_mask = 0; ++ for (i = 0; i < gl_info->limits.dual_buffers; ++i) ++diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c ++index fc5d722..9f90d3c 100644 ++--- a/dll/directx/wine/wined3d/cs.c +++++ b/dll/directx/wine/wined3d/cs.c ++@@ -1671,7 +1671,8 @@ static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *dat ++ const struct wined3d_cs_set_transform *op = data; ++ ++ cs->state.transforms[op->state] = op->matrix; ++- if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) +++ if (op->state < WINED3D_TS_WORLD_MATRIX(max(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices, +++ cs->device->adapter->d3d_info.limits.ffp_max_vertex_blend_matrix_index + 1))) ++ device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); ++ } ++ ++diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c ++index d56ae07..986ea7a 100644 ++--- a/dll/directx/wine/wined3d/device.c +++++ b/dll/directx/wine/wined3d/device.c ++@@ -4098,6 +4098,11 @@ HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device ++ adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); ++ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; +++ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; +++ if (!((device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) +++ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) +++ && device->softwareVertexProcessing))) +++ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); ++ return hr; ++ } ++ ++diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c ++index 726b1e3..f366b8c 100644 ++--- a/dll/directx/wine/wined3d/directx.c +++++ b/dll/directx/wine/wined3d/directx.c ++@@ -2032,6 +2032,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, unsigned in ++ caps->MaxActiveLights = vertex_caps.max_active_lights; ++ caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices; ++ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; +++ if (caps->DeviceType == WINED3D_DEVICE_TYPE_HAL) +++ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); ++ caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps; ++ caps->FVFCaps = vertex_caps.fvf_caps; ++ caps->RasterCaps |= vertex_caps.raster_caps; ++diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c ++index 0c3955f..055749f 100644 ++--- a/dll/directx/wine/wined3d/glsl_shader.c +++++ b/dll/directx/wine/wined3d/glsl_shader.c ++@@ -11998,6 +11998,258 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, +++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, ++ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, ++ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, ++diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c ++index 817166e..ab14864 100644 ++--- a/dll/directx/wine/wined3d/state.c +++++ b/dll/directx/wine/wined3d/state.c ++@@ -5416,7 +5416,8 @@ static void prune_invalid_states(struct wined3d_state_entry *state_table, const ++ state_table[i].apply = state_undefined; ++ } ++ ++- start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(d3d_info->limits.ffp_vertex_blend_matrices)); +++ start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(max(d3d_info->limits.ffp_vertex_blend_matrices, +++ d3d_info->limits.ffp_max_vertex_blend_matrix_index + 1))); ++ last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)); ++ for (i = start; i <= last; ++i) ++ { ++diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c ++index cc217c7..d58c503 100644 ++--- a/dll/directx/wine/wined3d/utils.c +++++ b/dll/directx/wine/wined3d/utils.c ++@@ -5127,11 +5127,9 @@ const char *debug_d3dtstype(enum wined3d_transform_state tstype) ++ TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(3)); ++ #undef TSTYPE_TO_STR ++ default: ++- if (tstype > 256 && tstype < 512) ++- { ++- FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype); ++- return ("WINED3D_TS_WORLD_MATRIX > 0"); ++- } +++ if (tstype > WINED3D_TS_WORLD_MATRIX(3) && tstype < WINED3D_TS_WORLD_MATRIX(256)) +++ return ("WINED3D_TS_WORLD_MATRIX > 3"); +++ ++ FIXME("Unrecognized transform state %#x.\n", tstype); ++ return "unrecognized"; ++ } ++diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h ++index daccc13..c4c6bab 100644 ++--- a/dll/directx/wine/wined3d/wined3d_private.h +++++ b/dll/directx/wine/wined3d/wined3d_private.h ++@@ -174,6 +174,7 @@ struct wined3d_d3d_limits ++ unsigned int ffp_blend_stages; ++ unsigned int ffp_vertex_blend_matrices; ++ unsigned int active_light_count; +++ unsigned int ffp_max_vertex_blend_matrix_index; ++ ++ unsigned int max_rt_count; ++ unsigned int max_clip_distances; diff --git a/sdk/tools/winesync/0012-wined3d__Support_indexed_vertex_blending.diff b/sdk/tools/winesync/0012-wined3d__Support_indexed_vertex_blending.diff new file mode 100644 index 00000000000..f5f1dfcf1cb --- /dev/null +++ b/sdk/tools/winesync/0012-wined3d__Support_indexed_vertex_blending.diff @@ -0,0 +1,756 @@ +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index c274f711580..1fa732743ad 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -150,6 +150,9 @@ struct shader_glsl_priv + struct wine_rb_tree ffp_fragment_shaders; + BOOL ffp_proj_control; + BOOL legacy_lighting; ++ ++ GLuint ubo_modelview; ++ struct wined3d_matrix *modelview_buffer; + }; + + struct glsl_vs_program +@@ -164,6 +167,7 @@ struct glsl_vs_program + GLint base_vertex_id_location; + + GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; ++ GLint modelview_block_index; + GLint projection_matrix_location; + GLint normal_matrix_location; + GLint texture_matrix_location[WINED3D_MAX_TEXTURES]; +@@ -1606,10 +1610,10 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + { + unsigned int base, count; + ++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++ &base, &count); + if (priv->consts_ubo) + { +- wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, +- &base, &count); + if (priv->ubo_vs_c == -1) + { + GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); +@@ -1622,6 +1626,21 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base, priv->ubo_vs_c)); + checkGLcall("glBindBufferBase"); + } ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] ++ && (context->device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS)) ++ { ++ if (priv->ubo_modelview == -1) ++ { ++ GL_EXTCALL(glGenBuffers(1, &priv->ubo_modelview)); ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); ++ checkGLcall("glBindBuffer (UBO)"); ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, ++ sizeof(struct wined3d_matrix) * MAX_VERTEX_BLEND_UBO, NULL, GL_DYNAMIC_DRAW)); ++ checkGLcall("glBufferData (UBO)"); ++ } ++ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + 1, priv->ubo_modelview)); ++ checkGLcall("glBindBufferBase"); ++ } + ctx_data->ubo_bound = TRUE; + } + +@@ -1668,28 +1687,41 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + } + + if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW) +- { +- struct wined3d_matrix mat; +- +- get_modelview_matrix(context, state, 0, &mat); +- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); +- checkGLcall("glUniformMatrix4fv"); +- + shader_glsl_ffp_vertex_normalmatrix_uniform(context_gl, state, prog); +- } + + if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) + { + struct wined3d_matrix mat; + +- for (i = 1; i < MAX_VERTEX_BLENDS; ++i) ++ if (prog->vs.modelview_block_index != -1) + { +- if (prog->vs.modelview_matrix_location[i] == -1) +- break; ++ if (priv->ubo_modelview == -1) ++ FIXME("UBO buffer with vertex blend matrices is not initialized.\n"); ++ ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); ++ checkGLcall("glBindBuffer (UBO)"); ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); + +- get_modelview_matrix(context, state, i, &mat); +- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); +- checkGLcall("glUniformMatrix4fv"); ++ for (i = 0; i < MAX_VERTEX_BLEND_UBO; ++i) ++ get_modelview_matrix(context, state, i, &priv->modelview_buffer[i]); ++ ++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, ++ sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, priv->modelview_buffer)); ++ checkGLcall("glBufferSubData"); ++ } ++ else ++ { ++ for (i = 0; i < MAX_VERTEX_BLENDS; ++i) ++ { ++ if (prog->vs.modelview_matrix_location[i] == -1) ++ break; ++ ++ get_modelview_matrix(context, state, i, &mat); ++ GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); ++ checkGLcall("glUniformMatrix4fv"); ++ } + } + } + +@@ -9008,8 +9040,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + { + {"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */ + {"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */ +- /* TODO: Indexed vertex blending */ +- {"float", ""}, /* WINED3D_FFP_BLENDINDICES */ ++ {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */ + {"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */ + {"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */ + {"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */ +@@ -9025,6 +9056,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + string_buffer_clear(buffer); + + shader_glsl_add_version_declaration(buffer, gl_info); ++ TRACE("settings->vb_indices %#x.\n", settings->vb_indices); ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ shader_addline(buffer,"#extension GL_ARB_uniform_buffer_object : enable\n"); + + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); +@@ -9039,7 +9073,18 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + } + shader_addline(buffer, "\n"); + +- shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS); ++ if (settings->vb_indices && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ { ++ shader_addline(buffer,"layout(std140) uniform ffp_modelview_ubo\n\ ++ { \n\ ++ mat4 ffp_modelview_matrix[%u];\n\ ++ };\n", MAX_VERTEX_BLEND_UBO); ++ } ++ else ++ { ++ shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", settings->vertexblends + 1); ++ } ++ + shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); + shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); + shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", WINED3D_MAX_TEXTURES); +@@ -9101,6 +9146,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + shader_addline(buffer, "\nvoid main()\n{\n"); + shader_addline(buffer, "float m;\n"); + shader_addline(buffer, "vec3 r;\n"); ++ if (settings->vb_indices) ++ shader_addline(buffer, "int ind;\n"); + + for (i = 0; i < ARRAY_SIZE(attrib_info); ++i) + { +@@ -9130,8 +9177,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); + + shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); +- for (i = 0; i < settings->vertexblends + 1; ++i) +- shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); ++ if (settings->vb_indices) ++ { ++ for (i = 0; i < settings->vertexblends + 1; ++i) ++ { ++ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); ++ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " ++ "(ffp_modelview_matrix[ind] * ffp_attrib_position);\n", i); ++ } ++ } ++ else ++ { ++ for (i = 0; i < settings->vertexblends + 1; ++i) ++ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " ++ "(ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); ++ } + + shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n"); + if (settings->clipping) +@@ -9155,7 +9215,19 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + else + { + for (i = 0; i < settings->vertexblends + 1; ++i) +- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); ++ { ++ if (settings->vb_indices) ++ { ++ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); ++ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " ++ "(mat3(ffp_modelview_matrix[ind]) * ffp_attrib_normal);\n", i); ++ } ++ else ++ { ++ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " ++ "(mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); ++ } ++ } + } + + if (settings->normalize) +@@ -10020,6 +10092,28 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * + string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i); + vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } ++ ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ { ++ vs->modelview_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "ffp_modelview_ubo")); ++ checkGLcall("glGetUniformBlockIndex"); ++ if (vs->modelview_block_index != -1) ++ { ++ unsigned int base, count; ++ ++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++ &base, &count); ++ assert(count >= 2); ++ ++ GL_EXTCALL(glUniformBlockBinding(program_id, vs->modelview_block_index, base + 1)); ++ checkGLcall("glUniformBlockBinding"); ++ } ++ } ++ else ++ { ++ vs->modelview_block_index = -1; ++ } ++ + vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); + vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) +@@ -10599,7 +10693,7 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, + entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW + | WINED3D_SHADER_CONST_FFP_PROJ; + +- for (i = 1; i < MAX_VERTEX_BLENDS; ++i) ++ for (i = 0; i < MAX_VERTEX_BLENDS; ++i) + { + if (entry->vs.modelview_matrix_location[i] != -1) + { +@@ -10608,6 +10702,9 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, + } + } + ++ if (entry->vs.modelview_block_index != -1) ++ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; ++ + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + { + if (entry->vs.texture_matrix_location[i] != -1) +@@ -11148,7 +11245,17 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + fragment_pipe->get_caps(device->adapter, &fragment_caps); + priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; + priv->legacy_lighting = device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING; +- ++ priv->ubo_modelview = -1; /* To be initialized on first usage. */ ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ { ++ priv->modelview_buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv->modelview_buffer) ++ * MAX_VERTEX_BLEND_UBO); ++ if (!priv->modelview_buffer) ++ { ++ ERR("Failed to alloacte modelview buffer.\n"); ++ goto fail; ++ } ++ } + device->vertex_priv = vertex_priv; + device->fragment_priv = fragment_priv; + device->shader_priv = priv; +@@ -11181,6 +11288,14 @@ static void shader_glsl_free(struct wined3d_device *device, struct wined3d_conte + string_buffer_free(&priv->shader_buffer); + priv->fragment_pipe->free_private(device, context); + priv->vertex_pipe->vp_free(device, context); ++ if (priv->ubo_modelview != -1) ++ { ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_modelview)); ++ checkGLcall("glDeleteBuffers"); ++ priv->ubo_modelview = -1; ++ } ++ HeapFree(GetProcessHeap(), 0, priv->modelview_buffer); + + if (priv->ubo_vs_c != -1) + { +@@ -11605,7 +11720,11 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter, + caps->ffp_generic_attributes = TRUE; + caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS; + caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; +- caps->max_vertex_blend_matrix_index = 0; ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLEND_UBO - 1; ++ else ++ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLENDS - 1; ++ + caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN + | WINED3DVTXPCAPS_MATERIALSOURCE7 + | WINED3DVTXPCAPS_VERTEXFOG +@@ -11807,7 +11926,8 @@ static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, + static void glsl_vertex_pipe_world(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) + { +- context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW; ++ context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW ++ | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; + } + + static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, +diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c +index 3ff7441760e..88b0fff5af7 100644 +--- a/dll/directx/wine/wined3d/utils.c ++++ b/dll/directx/wine/wined3d/utils.c +@@ -6893,6 +6893,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, + settings->flatshading = FALSE; + + settings->swizzle_map = si->swizzle_map; ++ settings->vb_indices = is_indexed_vertex_blending(context, state); + } + + int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) +diff --git a/dll/directx/wine/wined3d/vertexdeclaration.c b/dll/directx/wine/wined3d/vertexdeclaration.c +index e91409f4522..c86f5b4b125 100644 +--- a/dll/directx/wine/wined3d/vertexdeclaration.c ++++ b/dll/directx/wine/wined3d/vertexdeclaration.c +@@ -128,6 +128,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e + return FALSE; + } + ++ case WINED3D_DECL_USAGE_BLEND_INDICES: ++ switch(element->format) ++ { ++ case WINED3DFMT_R8G8B8A8_UINT: ++ return TRUE; ++ default: ++ return FALSE; ++ } ++ + case WINED3D_DECL_USAGE_NORMAL: + switch(element->format) + { +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index d19af9f0b17..1da43bb706d 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -275,6 +275,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup + } + + /* Device caps */ ++#define MAX_VERTEX_BLEND_UBO 256 + #define WINED3D_MAX_STREAMS 16 + #define WINED3D_MAX_TEXTURES 8 + #define WINED3D_MAX_FRAGMENT_SAMPLERS 16 +@@ -5275,6 +5276,13 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) + BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN; + void wined3d_dxtn_free(void) DECLSPEC_HIDDEN; + ++static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, ++ const struct wined3d_state *state) ++{ ++ return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] ++ && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); ++} ++ + static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, + enum wined3d_material_color_source source) + { +diff --git a/sdk/tools/winesync/wined3d_staging/0012-wined3d__Support_indexed_vertex_blending.diff b/sdk/tools/winesync/wined3d_staging/0012-wined3d__Support_indexed_vertex_blending.diff +new file mode 100644 +index 00000000000..c528926c79d +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0012-wined3d__Support_indexed_vertex_blending.diff +@@ -0,0 +1,380 @@ ++diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c ++index 055749f..05de1d7 100644 ++--- a/dll/directx/wine/wined3d/glsl_shader.c +++++ b/dll/directx/wine/wined3d/glsl_shader.c ++@@ -150,6 +150,9 @@ struct shader_glsl_priv ++ struct wine_rb_tree ffp_fragment_shaders; ++ BOOL ffp_proj_control; ++ BOOL legacy_lighting; +++ +++ GLuint ubo_modelview; +++ struct wined3d_matrix *modelview_buffer; ++ }; ++ ++ struct glsl_vs_program ++@@ -164,6 +167,7 @@ struct glsl_vs_program ++ GLint base_vertex_id_location; ++ ++ GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; +++ GLint modelview_block_index; ++ GLint projection_matrix_location; ++ GLint normal_matrix_location; ++ GLint texture_matrix_location[WINED3D_MAX_TEXTURES]; ++@@ -1606,10 +1610,10 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++ { ++ unsigned int base, count; ++ +++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, +++ &base, &count); ++ if (priv->consts_ubo) ++ { ++- wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++- &base, &count); ++ if (priv->ubo_vs_c == -1) ++ { ++ GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); ++@@ -1622,6 +1626,21 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base, priv->ubo_vs_c)); ++ checkGLcall("glBindBufferBase"); ++ } +++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] +++ && (context->device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS)) +++ { +++ if (priv->ubo_modelview == -1) +++ { +++ GL_EXTCALL(glGenBuffers(1, &priv->ubo_modelview)); +++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); +++ checkGLcall("glBindBuffer (UBO)"); +++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, +++ sizeof(struct wined3d_matrix) * MAX_VERTEX_BLEND_UBO, NULL, GL_DYNAMIC_DRAW)); +++ checkGLcall("glBufferData (UBO)"); +++ } +++ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + 1, priv->ubo_modelview)); +++ checkGLcall("glBindBufferBase"); +++ } ++ ctx_data->ubo_bound = TRUE; ++ } ++ ++@@ -1668,28 +1687,41 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++ } ++ ++ if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW) ++- { ++- struct wined3d_matrix mat; ++- ++- get_modelview_matrix(context, state, 0, &mat); ++- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); ++- checkGLcall("glUniformMatrix4fv"); ++- ++ shader_glsl_ffp_vertex_normalmatrix_uniform(context_gl, state, prog); ++- } ++ ++ if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) ++ { ++ struct wined3d_matrix mat; ++ ++- for (i = 1; i < MAX_VERTEX_BLENDS; ++i) +++ if (prog->vs.modelview_block_index != -1) ++ { ++- if (prog->vs.modelview_matrix_location[i] == -1) ++- break; +++ if (priv->ubo_modelview == -1) +++ FIXME("UBO buffer with vertex blend matrices is not initialized.\n"); +++ +++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); +++ checkGLcall("glBindBuffer (UBO)"); +++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, +++ NULL, GL_STREAM_DRAW)); +++ checkGLcall("glBufferData"); ++ ++- get_modelview_matrix(context, state, i, &mat); ++- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); ++- checkGLcall("glUniformMatrix4fv"); +++ for (i = 0; i < MAX_VERTEX_BLEND_UBO; ++i) +++ get_modelview_matrix(context, state, i, &priv->modelview_buffer[i]); +++ +++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, +++ sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, priv->modelview_buffer)); +++ checkGLcall("glBufferSubData"); +++ } +++ else +++ { +++ for (i = 0; i < MAX_VERTEX_BLENDS; ++i) +++ { +++ if (prog->vs.modelview_matrix_location[i] == -1) +++ break; +++ +++ get_modelview_matrix(context, state, i, &mat); +++ GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); +++ checkGLcall("glUniformMatrix4fv"); +++ } ++ } ++ } ++ ++@@ -9008,8 +9040,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr ++ { ++ {"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */ ++ {"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */ ++- /* TODO: Indexed vertex blending */ ++- {"float", ""}, /* WINED3D_FFP_BLENDINDICES */ +++ {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */ ++ {"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */ ++ {"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */ ++ {"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */ ++@@ -9025,6 +9056,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr ++ string_buffer_clear(buffer); ++ ++ shader_glsl_add_version_declaration(buffer, gl_info); +++ TRACE("settings->vb_indices %#x.\n", settings->vb_indices); +++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) +++ shader_addline(buffer,"#extension GL_ARB_uniform_buffer_object : enable\n"); ++ ++ if (shader_glsl_use_explicit_attrib_location(gl_info)) ++ shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); ++@@ -9039,7 +9073,18 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr ++ } ++ shader_addline(buffer, "\n"); ++ ++- shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS); +++ if (settings->vb_indices && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) +++ { +++ shader_addline(buffer,"layout(std140) uniform ffp_modelview_ubo\n\ +++ { \n\ +++ mat4 ffp_modelview_matrix[%u];\n\ +++ };\n", MAX_VERTEX_BLEND_UBO); +++ } +++ else +++ { +++ shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", settings->vertexblends + 1); +++ } +++ ++ shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); ++ shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); ++ shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", WINED3D_MAX_TEXTURES); ++@@ -9101,6 +9146,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr ++ shader_addline(buffer, "\nvoid main()\n{\n"); ++ shader_addline(buffer, "float m;\n"); ++ shader_addline(buffer, "vec3 r;\n"); +++ if (settings->vb_indices) +++ shader_addline(buffer, "int ind;\n"); ++ ++ for (i = 0; i < ARRAY_SIZE(attrib_info); ++i) ++ { ++@@ -9130,8 +9177,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr ++ shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); ++ ++ shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); ++- for (i = 0; i < settings->vertexblends + 1; ++i) ++- shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); +++ if (settings->vb_indices) +++ { +++ for (i = 0; i < settings->vertexblends + 1; ++i) +++ { +++ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); +++ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " +++ "(ffp_modelview_matrix[ind] * ffp_attrib_position);\n", i); +++ } +++ } +++ else +++ { +++ for (i = 0; i < settings->vertexblends + 1; ++i) +++ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " +++ "(ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); +++ } ++ ++ shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n"); ++ if (settings->clipping) ++@@ -9155,7 +9215,19 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr ++ else ++ { ++ for (i = 0; i < settings->vertexblends + 1; ++i) ++- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); +++ { +++ if (settings->vb_indices) +++ { +++ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); +++ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " +++ "(mat3(ffp_modelview_matrix[ind]) * ffp_attrib_normal);\n", i); +++ } +++ else +++ { +++ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " +++ "(mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); +++ } +++ } ++ } ++ ++ if (settings->normalize) ++@@ -10020,6 +10092,28 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * ++ string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i); ++ vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); ++ } +++ +++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) +++ { +++ vs->modelview_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "ffp_modelview_ubo")); +++ checkGLcall("glGetUniformBlockIndex"); +++ if (vs->modelview_block_index != -1) +++ { +++ unsigned int base, count; +++ +++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, +++ &base, &count); +++ assert(count >= 2); +++ +++ GL_EXTCALL(glUniformBlockBinding(program_id, vs->modelview_block_index, base + 1)); +++ checkGLcall("glUniformBlockBinding"); +++ } +++ } +++ else +++ { +++ vs->modelview_block_index = -1; +++ } +++ ++ vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); ++ vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); ++ for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) ++@@ -10599,7 +10693,7 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, ++ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW ++ | WINED3D_SHADER_CONST_FFP_PROJ; ++ ++- for (i = 1; i < MAX_VERTEX_BLENDS; ++i) +++ for (i = 0; i < MAX_VERTEX_BLENDS; ++i) ++ { ++ if (entry->vs.modelview_matrix_location[i] != -1) ++ { ++@@ -10608,6 +10702,9 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, ++ } ++ } ++ +++ if (entry->vs.modelview_block_index != -1) +++ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; +++ ++ for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) ++ { ++ if (entry->vs.texture_matrix_location[i] != -1) ++@@ -11148,7 +11245,17 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win ++ fragment_pipe->get_caps(device->adapter, &fragment_caps); ++ priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; ++ priv->legacy_lighting = device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING; ++- +++ priv->ubo_modelview = -1; /* To be initialized on first usage. */ +++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) +++ { +++ priv->modelview_buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv->modelview_buffer) +++ * MAX_VERTEX_BLEND_UBO); +++ if (!priv->modelview_buffer) +++ { +++ ERR("Failed to alloacte modelview buffer.\n"); +++ goto fail; +++ } +++ } ++ device->vertex_priv = vertex_priv; ++ device->fragment_priv = fragment_priv; ++ device->shader_priv = priv; ++@@ -11181,6 +11288,14 @@ static void shader_glsl_free(struct wined3d_device *device, struct wined3d_conte ++ string_buffer_free(&priv->shader_buffer); ++ priv->fragment_pipe->free_private(device, context); ++ priv->vertex_pipe->vp_free(device, context); +++ if (priv->ubo_modelview != -1) +++ { +++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +++ GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_modelview)); +++ checkGLcall("glDeleteBuffers"); +++ priv->ubo_modelview = -1; +++ } +++ HeapFree(GetProcessHeap(), 0, priv->modelview_buffer); ++ ++ if (priv->ubo_vs_c != -1) ++ { ++@@ -11605,7 +11720,11 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter, ++ caps->ffp_generic_attributes = TRUE; ++ caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS; ++ caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; ++- caps->max_vertex_blend_matrix_index = 0; +++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) +++ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLEND_UBO - 1; +++ else +++ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLENDS - 1; +++ ++ caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN ++ | WINED3DVTXPCAPS_MATERIALSOURCE7 ++ | WINED3DVTXPCAPS_VERTEXFOG ++@@ -11807,7 +11926,8 @@ static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, ++ static void glsl_vertex_pipe_world(struct wined3d_context *context, ++ const struct wined3d_state *state, DWORD state_id) ++ { ++- context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW; +++ context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW +++ | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; ++ } ++ ++ static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, ++diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c ++index d58c503..0466863 100644 ++--- a/dll/directx/wine/wined3d/utils.c +++++ b/dll/directx/wine/wined3d/utils.c ++@@ -6547,6 +6547,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, ++ settings->flatshading = FALSE; ++ ++ settings->swizzle_map = si->swizzle_map; +++ settings->vb_indices = is_indexed_vertex_blending(context, state); ++ } ++ ++ int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) ++diff --git a/dll/directx/wine/wined3d/vertexdeclaration.c b/dll/directx/wine/wined3d/vertexdeclaration.c ++index 8103274..e91409f 100644 ++--- a/dll/directx/wine/wined3d/vertexdeclaration.c +++++ b/dll/directx/wine/wined3d/vertexdeclaration.c ++@@ -119,6 +119,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e ++ return FALSE; ++ } ++ +++ case WINED3D_DECL_USAGE_BLEND_INDICES: +++ switch(element->format) +++ { +++ case WINED3DFMT_R8G8B8A8_UINT: +++ return TRUE; +++ default: +++ return FALSE; +++ } +++ ++ case WINED3D_DECL_USAGE_NORMAL: ++ switch(element->format) ++ { ++diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h ++index c4c6bab..5a6d300 100644 ++--- a/dll/directx/wine/wined3d/wined3d_private.h +++++ b/dll/directx/wine/wined3d/wined3d_private.h ++@@ -275,6 +275,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup ++ } ++ ++ /* Device caps */ +++#define MAX_VERTEX_BLEND_UBO 256 ++ #define WINED3D_MAX_STREAMS 16 ++ #define WINED3D_MAX_TEXTURES 8 ++ #define WINED3D_MAX_FRAGMENT_SAMPLERS 16 ++@@ -3062,7 +3063,8 @@ struct wined3d_ffp_vs_settings ++ DWORD ortho_fog : 1; ++ DWORD flatshading : 1; ++ DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */ ++- DWORD padding : 2; +++ DWORD vb_indices : 1; +++ DWORD padding : 1; ++ ++ DWORD texgen[WINED3D_MAX_TEXTURES]; ++ }; ++@@ -5212,6 +5214,13 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) ++ assert(cs->thread_id != GetCurrentThreadId()); ++ } ++ +++static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, +++ const struct wined3d_state *state) +++{ +++ return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] +++ && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); +++} +++ ++ static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, ++ enum wined3d_material_color_source source) ++ { diff --git a/sdk/tools/winesync/0015-wined3d__Remaining_UAV_counter_changes.diff b/sdk/tools/winesync/0015-wined3d__Remaining_UAV_counter_changes.diff new file mode 100644 index 00000000000..0ec77367845 --- /dev/null +++ b/sdk/tools/winesync/0015-wined3d__Remaining_UAV_counter_changes.diff @@ -0,0 +1,61 @@ +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 5083f09f440..1da43bb706d 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -5276,6 +5276,13 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) + BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN; + void wined3d_dxtn_free(void) DECLSPEC_HIDDEN; + ++static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, ++ const struct wined3d_state *state) ++{ ++ return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] ++ && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); ++} ++ + static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, + enum wined3d_material_color_source source) + { +diff --git a/sdk/tools/winesync/wined3d_staging/0015-wined3d__Remaining_UAV_counter_changes.diff b/sdk/tools/winesync/wined3d_staging/0015-wined3d__Remaining_UAV_counter_changes.diff +new file mode 100644 +index 00000000000..ac72304bf01 +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0015-wined3d__Remaining_UAV_counter_changes.diff +@@ -0,0 +1,37 @@ ++diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c ++index 9f90d3c..54be547 100644 ++--- a/dll/directx/wine/wined3d/cs.c +++++ b/dll/directx/wine/wined3d/cs.c ++@@ -2504,6 +2504,7 @@ static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void * ++ context_release(context); ++ ++ wined3d_resource_release(&op->buffer->resource); +++ wined3d_resource_release(view->resource); ++ } ++ ++ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, ++@@ -2518,6 +2519,7 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff ++ op->view = uav; ++ ++ wined3d_resource_acquire(&dst_buffer->resource); +++ wined3d_resource_acquire(uav->resource); ++ ++ wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); ++ } ++diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c ++index 986ea7a..655b6d9 100644 ++--- a/dll/directx/wine/wined3d/device.c +++++ b/dll/directx/wine/wined3d/device.c ++@@ -4616,6 +4616,12 @@ void CDECL wined3d_device_copy_uav_counter(struct wined3d_device *device, ++ TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n", ++ device, dst_buffer, offset, uav); ++ +++ if (offset + sizeof(GLuint) > dst_buffer->resource.size) +++ { +++ WARN("Offset %u too large.\n", offset); +++ return; +++ } +++ ++ wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav); ++ } ++ diff --git a/sdk/tools/winesync/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff b/sdk/tools/winesync/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff new file mode 100644 index 00000000000..2cab9bc8d51 --- /dev/null +++ b/sdk/tools/winesync/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff @@ -0,0 +1,92 @@ +diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c +index 6988d9d6961..52dfb95b38e 100644 +--- a/dll/directx/wine/wined3d/surface.c ++++ b/dll/directx/wine/wined3d/surface.c +@@ -682,6 +682,25 @@ static void convert_x8r8g8b8_dxt5(const BYTE *src, BYTE *dst, + wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); + } + ++static void convert_x8r8g8b8_l8(const BYTE *src, BYTE *dst, ++ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) ++{ ++ unsigned int x, y; ++ ++ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); ++ ++ for (y = 0; y < h; ++y) ++ { ++ const DWORD *src_line = (const DWORD *)(src + y * pitch_in); ++ BYTE *dst_line = (BYTE *)(dst + y * pitch_out); ++ ++ for (x = 0; x < w; ++x) ++ { ++ dst_line[x] = src_line[x] & 0x000000ff; ++ } ++ } ++} ++ + struct d3dfmt_converter_desc + { + enum wined3d_format_id from, to; +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 5083f09f440..1da43bb706d 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -5276,6 +5276,13 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) + BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN; + void wined3d_dxtn_free(void) DECLSPEC_HIDDEN; + ++static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, ++ const struct wined3d_state *state) ++{ ++ return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] ++ && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); ++} ++ + static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, + enum wined3d_material_color_source source) + { +diff --git a/sdk/tools/winesync/wined3d_staging/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff b/sdk/tools/winesync/wined3d_staging/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff +new file mode 100644 +index 00000000000..1246998041c +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff +@@ -0,0 +1,38 @@ ++diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c ++index 1beb98e..981d6bf 100644 ++--- a/dll/directx/wine/wined3d/surface.c +++++ b/dll/directx/wine/wined3d/surface.c ++@@ -563,6 +563,25 @@ static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst, ++ } ++ } ++ +++static void convert_x8r8g8b8_l8(const BYTE *src, BYTE *dst, +++ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +++{ +++ unsigned int x, y; +++ +++ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); +++ +++ for (y = 0; y < h; ++y) +++ { +++ const DWORD *src_line = (const DWORD *)(src + y * pitch_in); +++ BYTE *dst_line = (BYTE *)(dst + y * pitch_out); +++ +++ for (x = 0; x < w; ++x) +++ { +++ dst_line[x] = src_line[x] & 0x000000ff; +++ } +++ } +++} +++ ++ struct d3dfmt_converter_desc ++ { ++ enum wined3d_format_id from, to; ++@@ -577,6 +596,7 @@ static const struct d3dfmt_converter_desc converters[] = ++ {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8A8_UNORM, convert_a8r8g8b8_x8r8g8b8}, ++ {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8}, ++ {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5}, +++ {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_L8_UNORM, convert_x8r8g8b8_l8}, ++ }; ++ ++ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from, diff --git a/sdk/tools/winesync/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff b/sdk/tools/winesync/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff new file mode 100644 index 00000000000..599fdbf4cba --- /dev/null +++ b/sdk/tools/winesync/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff @@ -0,0 +1,518 @@ +diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c +index 0b99d33650c..525711e353b 100644 +--- a/dll/directx/wine/wined3d/context.c ++++ b/dll/directx/wine/wined3d/context.c +@@ -2754,7 +2754,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, + const struct wined3d_gl_info *gl_info; + uint32_t rt_mask, *cur_mask; + struct wined3d_texture *rt; +- unsigned int sampler; ++ unsigned int i, sampler; + SIZE rt_size; + + TRACE("Setting up context %p for blitting.\n", context); +@@ -2861,10 +2861,8 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + } + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); ++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) ++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); + + context->last_was_rhw = TRUE; + context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ +@@ -4862,7 +4860,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s + if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) + continue; + +- if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) ++ if (state->render_states[WINED3D_RS_COLORWRITE(i)]) + { + wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding); + wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); +diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c +index 26b90ba7a1b..7cd2e48aae3 100644 +--- a/dll/directx/wine/wined3d/state.c ++++ b/dll/directx/wine/wined3d/state.c +@@ -1553,9 +1553,6 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined + { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE]; +- DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1]; +- DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2]; +- DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3]; + + TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", + mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, +@@ -1568,13 +1565,7 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); + checkGLcall("glColorMask(...)"); + +- if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) +- || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) +- { +- FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", +- mask0, mask1, mask2, mask3); +- FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); +- } ++ /* FIXME: WINED3D_RS_COLORWRITEENABLE1 .. WINED3D_RS_COLORWRITEENABLE7 not implemented. */ + } + + static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) +@@ -1587,9 +1578,20 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW + checkGLcall("glColorMaski"); + } + +-static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) ++static void state_colorwrite_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- set_color_mask(wined3d_context_gl(context)->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]); ++ const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; ++ int index; ++ ++ if (state_id == WINED3D_RS_COLORWRITEENABLE) index = 0; ++ else if (state_id <= WINED3D_RS_COLORWRITEENABLE3) index = state_id - WINED3D_RS_COLORWRITEENABLE1 + 1; ++ else if (state_id <= WINED3D_RS_COLORWRITEENABLE7) index = state_id - WINED3D_RS_COLORWRITEENABLE4 + 4; ++ else return; ++ ++ if (index >= gl_info->limits.buffers) ++ WARN("Ignoring color write value for index %d, because gpu only supports %d render targets\n", index, gl_info->limits.buffers); ++ ++ set_color_mask(gl_info, index, state->render_states[state_id]); + } + + static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +@@ -4666,18 +4668,26 @@ const struct wined3d_state_entry_template misc_state_template[] = + { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, WINED3D_GL_BLEND_EQUATION }, + { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, + /* Samplers */ +diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c +index ee698ec67cb..e6383550e21 100644 +--- a/dll/directx/wine/wined3d/stateblock.c ++++ b/dll/directx/wine/wined3d/stateblock.c +@@ -44,6 +44,10 @@ static const DWORD pixel_states_render[] = + WINED3D_RS_COLORWRITEENABLE1, + WINED3D_RS_COLORWRITEENABLE2, + WINED3D_RS_COLORWRITEENABLE3, ++ WINED3D_RS_COLORWRITEENABLE4, ++ WINED3D_RS_COLORWRITEENABLE5, ++ WINED3D_RS_COLORWRITEENABLE6, ++ WINED3D_RS_COLORWRITEENABLE7, + WINED3D_RS_DEPTHBIAS, + WINED3D_RS_DESTBLEND, + WINED3D_RS_DESTBLENDALPHA, +@@ -1452,6 +1456,7 @@ void CDECL wined3d_stateblock_set_blend_factor(struct wined3d_stateblock *stateb + + static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], const struct wined3d_d3d_info *d3d_info) + { ++ unsigned int i; + union + { + struct wined3d_line_pattern lp; +@@ -1545,7 +1550,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c + tmpfloat.f = d3d_info->limits.pointsize_max; + rs[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d; + rs[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE; +- rs[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f; + tmpfloat.f = 0.0f; + rs[WINED3D_RS_TWEENFACTOR] = tmpfloat.d; + rs[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD; +@@ -1571,9 +1575,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c + rs[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS; +- rs[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f; +- rs[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f; +- rs[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f; + rs[WINED3D_RS_SRGBWRITEENABLE] = 0; + rs[WINED3D_RS_DEPTHBIAS] = 0; + rs[WINED3D_RS_WRAP8] = 0; +@@ -1588,6 +1589,8 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c + rs[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE; + rs[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO; + rs[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD; ++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) ++ rs[WINED3D_RS_COLORWRITE(i)] = 0x0000000f; + } + + static void init_default_texture_state(unsigned int i, DWORD stage[WINED3D_HIGHEST_TEXTURE_STATE + 1]) +diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c +index 6988d9d6961..52dfb95b38e 100644 +--- a/dll/directx/wine/wined3d/surface.c ++++ b/dll/directx/wine/wined3d/surface.c +@@ -682,6 +682,25 @@ static void convert_x8r8g8b8_dxt5(const BYTE *src, BYTE *dst, + wined3d_dxt5_encode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h); + } + ++static void convert_x8r8g8b8_l8(const BYTE *src, BYTE *dst, ++ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) ++{ ++ unsigned int x, y; ++ ++ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); ++ ++ for (y = 0; y < h; ++y) ++ { ++ const DWORD *src_line = (const DWORD *)(src + y * pitch_in); ++ BYTE *dst_line = (BYTE *)(dst + y * pitch_out); ++ ++ for (x = 0; x < w; ++x) ++ { ++ dst_line[x] = src_line[x] & 0x000000ff; ++ } ++ } ++} ++ + struct d3dfmt_converter_desc + { + enum wined3d_format_id from, to; +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 5083f09f440..1da43bb706d 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -5276,6 +5276,13 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) + BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN; + void wined3d_dxtn_free(void) DECLSPEC_HIDDEN; + ++static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, ++ const struct wined3d_state *state) ++{ ++ return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] ++ && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); ++} ++ + static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, + enum wined3d_material_color_source source) + { +diff --git a/sdk/include/reactos/wine/wined3d.h.rej b/sdk/include/reactos/wine/wined3d.h.rej +deleted file mode 100644 +index fdb42123ceb..00000000000 +--- a/sdk/include/reactos/wine/wined3d.h.rej ++++ /dev/null +@@ -1,9 +0,0 @@ +-diff a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h (rejected hunks) +-@@ -1334,6 +1334,7 @@ enum wined3d_shader_type +- #define WINED3D_NO_PRIMITIVE_RESTART 0x00000800 +- #define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 +- #define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 +-+#define WINED3D_LEGACY_SHADER_CONSTANTS 0x00004000 +- +- #define WINED3D_RESZ_CODE 0x7fa05000 +- +diff --git a/sdk/tools/winesync/wined3d_staging/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff b/sdk/tools/winesync/wined3d_staging/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff +new file mode 100644 +index 00000000000..52aa98f83bf +--- /dev/null ++++ b/sdk/tools/winesync/wined3d_staging/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff +@@ -0,0 +1,278 @@ ++diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c ++index 9001d60..dc57667 100644 ++--- a/dll/directx/wine/wined3d/context.c +++++ b/dll/directx/wine/wined3d/context.c ++@@ -2754,7 +2754,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, ++ const struct wined3d_gl_info *gl_info; ++ uint32_t rt_mask, *cur_mask; ++ struct wined3d_texture *rt; ++- unsigned int sampler; +++ unsigned int i, sampler; ++ SIZE rt_size; ++ ++ TRACE("Setting up context %p for blitting.\n", context); ++@@ -2861,10 +2861,8 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, ++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); ++ } ++ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); +++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) +++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); ++ ++ context->last_was_rhw = TRUE; ++ context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ ++@@ -4862,7 +4860,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s ++ if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) ++ continue; ++ ++- if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) +++ if (state->render_states[WINED3D_RS_COLORWRITE(i)]) ++ { ++ wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding); ++ wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); ++diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c ++index 655b6d9..d4bd20a 100644 ++--- a/dll/directx/wine/wined3d/device.c +++++ b/dll/directx/wine/wined3d/device.c ++@@ -438,10 +438,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c ++ } ++ ++ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); +++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) +++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); ++ gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a); ++ checkGLcall("glClearColor"); ++ clear_mask = clear_mask | GL_COLOR_BUFFER_BIT; ++diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c ++index ab14864..41df2e9 100644 ++--- a/dll/directx/wine/wined3d/state.c +++++ b/dll/directx/wine/wined3d/state.c ++@@ -1553,9 +1553,6 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined ++ { ++ const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; ++ DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE]; ++- DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1]; ++- DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2]; ++- DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3]; ++ ++ TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", ++ mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, ++@@ -1568,13 +1565,7 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined ++ mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); ++ checkGLcall("glColorMask(...)"); ++ ++- if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) ++- || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) ++- { ++- FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", ++- mask0, mask1, mask2, mask3); ++- FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); ++- } +++ /* FIXME: WINED3D_RS_COLORWRITEENABLE1 .. WINED3D_RS_COLORWRITEENABLE7 not implemented. */ ++ } ++ ++ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) ++@@ -1587,9 +1578,20 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW ++ checkGLcall("glColorMaski"); ++ } ++ ++-static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +++static void state_colorwrite_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) ++ { ++- set_color_mask(wined3d_context_gl(context)->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]); +++ const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; +++ int index; +++ +++ if (state_id == WINED3D_RS_COLORWRITEENABLE) index = 0; +++ else if (state_id <= WINED3D_RS_COLORWRITEENABLE3) index = state_id - WINED3D_RS_COLORWRITEENABLE1 + 1; +++ else if (state_id <= WINED3D_RS_COLORWRITEENABLE7) index = state_id - WINED3D_RS_COLORWRITEENABLE4 + 4; +++ else return; +++ +++ if (index >= gl_info->limits.buffers) +++ WARN("Ignoring color write value for index %d, because gpu only supports %d render targets\n", index, gl_info->limits.buffers); +++ +++ set_color_mask(gl_info, index, state->render_states[state_id]); ++ } ++ ++ static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) ++@@ -4666,18 +4668,26 @@ const struct wined3d_state_entry_template misc_state_template[] = ++ { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, +++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, WINED3D_GL_BLEND_EQUATION }, ++ { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, ++- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, ++ /* Samplers */ ++diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c ++index 172b46b..08ccff6 100644 ++--- a/dll/directx/wine/wined3d/stateblock.c +++++ b/dll/directx/wine/wined3d/stateblock.c ++@@ -44,6 +44,10 @@ static const DWORD pixel_states_render[] = ++ WINED3D_RS_COLORWRITEENABLE1, ++ WINED3D_RS_COLORWRITEENABLE2, ++ WINED3D_RS_COLORWRITEENABLE3, +++ WINED3D_RS_COLORWRITEENABLE4, +++ WINED3D_RS_COLORWRITEENABLE5, +++ WINED3D_RS_COLORWRITEENABLE6, +++ WINED3D_RS_COLORWRITEENABLE7, ++ WINED3D_RS_DEPTHBIAS, ++ WINED3D_RS_DESTBLEND, ++ WINED3D_RS_DESTBLENDALPHA, ++@@ -1452,6 +1456,7 @@ void CDECL wined3d_stateblock_set_blend_factor(struct wined3d_stateblock *stateb ++ ++ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], const struct wined3d_d3d_info *d3d_info) ++ { +++ unsigned int i; ++ union ++ { ++ struct wined3d_line_pattern lp; ++@@ -1545,7 +1550,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c ++ tmpfloat.f = d3d_info->limits.pointsize_max; ++ rs[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d; ++ rs[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE; ++- rs[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f; ++ tmpfloat.f = 0.0f; ++ rs[WINED3D_RS_TWEENFACTOR] = tmpfloat.d; ++ rs[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD; ++@@ -1571,9 +1575,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c ++ rs[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; ++ rs[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; ++ rs[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS; ++- rs[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f; ++- rs[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f; ++- rs[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f; ++ rs[WINED3D_RS_SRGBWRITEENABLE] = 0; ++ rs[WINED3D_RS_DEPTHBIAS] = 0; ++ rs[WINED3D_RS_WRAP8] = 0; ++@@ -1588,6 +1589,8 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c ++ rs[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE; ++ rs[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO; ++ rs[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD; +++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) +++ rs[WINED3D_RS_COLORWRITE(i)] = 0x0000000f; ++ } ++ ++ static void init_default_texture_state(unsigned int i, DWORD stage[WINED3D_HIGHEST_TEXTURE_STATE + 1]) ++diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c ++index 981d6bf..7ebb765 100644 ++--- a/dll/directx/wine/wined3d/surface.c +++++ b/dll/directx/wine/wined3d/surface.c ++@@ -153,6 +153,7 @@ void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *co ++ GLenum gl_filter; ++ GLenum buffer; ++ RECT s, d; +++ int i; ++ ++ TRACE("device %p, context %p, filter %s, src_texture %p, src_sub_resource_idx %u, src_location %s, " ++ "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", ++@@ -261,10 +262,8 @@ void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *co ++ context_invalidate_state(context, STATE_FRAMEBUFFER); ++ ++ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); ++- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); +++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) +++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); ++ ++ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); ++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); ++diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c ++index 0466863..e549e1a 100644 ++--- a/dll/directx/wine/wined3d/utils.c +++++ b/dll/directx/wine/wined3d/utils.c ++@@ -4949,7 +4949,6 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) ++ D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN); ++ D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX); ++ D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE); ++- D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); ++ D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR); ++ D3DSTATE_TO_STR(WINED3D_RS_BLENDOP); ++ D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE); ++@@ -4969,9 +4968,14 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) ++ D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL); ++ D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS); ++ D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC); +++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3); +++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE4); +++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE5); +++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE6); +++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE7); ++ D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE); ++ D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS); ++ D3DSTATE_TO_STR(WINED3D_RS_WRAP8); ++diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h ++index 5a6d300..5ec24e3 100644 ++--- a/dll/directx/wine/wined3d/wined3d_private.h +++++ b/dll/directx/wine/wined3d/wined3d_private.h ++@@ -291,6 +291,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup ++ #define MAX_UNORDERED_ACCESS_VIEWS 8 ++ #define MAX_TGSM_REGISTERS 8192 ++ #define MAX_VERTEX_BLENDS 4 +++#define MAX_RENDER_TARGETS 8 ++ ++ struct min_lookup ++ { ++diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h ++index e0df4c7..bbc9acf 100644 ++--- a/sdk/include/reactos/wine/wined3d.h +++++ b/sdk/include/reactos/wine/wined3d.h ++@@ -400,8 +400,20 @@ enum wined3d_render_state ++ WINED3D_RS_SRCBLENDALPHA = 207, ++ WINED3D_RS_DESTBLENDALPHA = 208, ++ WINED3D_RS_BLENDOPALPHA = 209, +++ WINED3D_RS_COLORWRITEENABLE4 = 210, +++ WINED3D_RS_COLORWRITEENABLE5 = 211, +++ WINED3D_RS_COLORWRITEENABLE6 = 212, +++ WINED3D_RS_COLORWRITEENABLE7 = 213, ++ }; ++-#define WINEHIGHEST_RENDER_STATE WINED3D_RS_BLENDOPALPHA +++#define WINEHIGHEST_RENDER_STATE WINED3D_RS_COLORWRITEENABLE7 +++ +++static inline enum wined3d_render_state WINED3D_RS_COLORWRITE(int index) +++{ +++ if (index == 0) return WINED3D_RS_COLORWRITEENABLE; +++ if (index <= 3) return WINED3D_RS_COLORWRITEENABLE1 + index - 1; +++ if (index <= 7) return WINED3D_RS_COLORWRITEENABLE4 + index - 4; +++ return WINED3D_RS_COLORWRITEENABLE; +++} ++ ++ enum wined3d_blend ++ { diff --git a/sdk/tools/winesync/d3dlegacy.cfg b/sdk/tools/winesync/d3dlegacy.cfg new file mode 100644 index 00000000000..3bd9247568b --- /dev/null +++ b/sdk/tools/winesync/d3dlegacy.cfg @@ -0,0 +1,8 @@ +directories: + dlls/d3d8: dll/directx/wine/d3d8 + dlls/d3d9: dll/directx/wine/d3d9 +files: + include/d3d8.h: sdk/include/psdk/d3d8.h + include/d3d9.h: sdk/include/psdk/d3d9.h +tags: + wine: wine-3.3 diff --git a/sdk/tools/winesync/d3dlegacy_staging/0001-d3d8__Avoid_implicit_cast_of_interface_pointer.diff b/sdk/tools/winesync/d3dlegacy_staging/0001-d3d8__Avoid_implicit_cast_of_interface_pointer.diff new file mode 100644 index 00000000000..50c9b0d1cd3 --- /dev/null +++ b/sdk/tools/winesync/d3dlegacy_staging/0001-d3d8__Avoid_implicit_cast_of_interface_pointer.diff @@ -0,0 +1,25 @@ +diff --git a/dll/directx/wine/d3d8/texture.c b/dll/directx/wine/d3d8/texture.c +index e34ae8a..2bc6f96 100644 +--- a/dll/directx/wine/d3d8/texture.c ++++ b/dll/directx/wine/d3d8/texture.c +@@ -22,17 +22,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d8); + + static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); ++ return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + } + + static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); ++ return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + } + + static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); ++ return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + } + + static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out) diff --git a/sdk/tools/winesync/d3dlegacy_staging/0002-d3d9__Avoid_implicit_cast_of_interface_pointer.diff b/sdk/tools/winesync/d3dlegacy_staging/0002-d3d9__Avoid_implicit_cast_of_interface_pointer.diff new file mode 100644 index 00000000000..025d47ce604 --- /dev/null +++ b/sdk/tools/winesync/d3dlegacy_staging/0002-d3d9__Avoid_implicit_cast_of_interface_pointer.diff @@ -0,0 +1,25 @@ +diff --git a/dll/directx/wine/d3d9/texture.c b/dll/directx/wine/d3d9/texture.c +index ae754b5..5c30e4c 100644 +--- a/dll/directx/wine/d3d9/texture.c ++++ b/dll/directx/wine/d3d9/texture.c +@@ -24,17 +24,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d9); + + static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); ++ return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); + } + + static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); ++ return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); + } + + static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); ++ return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); + } + + static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent) diff --git a/sdk/tools/winesync/d3dlegacy_staging/0003-wined3d__Use_UBO_for_vertex_shader_float_constants_if_supported.diff b/sdk/tools/winesync/d3dlegacy_staging/0003-wined3d__Use_UBO_for_vertex_shader_float_constants_if_supported.diff new file mode 100644 index 00000000000..301dd3327aa --- /dev/null +++ b/sdk/tools/winesync/d3dlegacy_staging/0003-wined3d__Use_UBO_for_vertex_shader_float_constants_if_supported.diff @@ -0,0 +1,26 @@ +diff --git a/dll/directx/wine/d3d8/directx.c b/dll/directx/wine/d3d8/directx.c +index c523984..274d5e1 100644 +--- a/dll/directx/wine/d3d8/directx.c ++++ b/dll/directx/wine/d3d8/directx.c +@@ -416,7 +416,7 @@ BOOL d3d8_init(struct d3d8 *d3d8) + DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING + | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER + | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART +- | WINED3D_LEGACY_CUBEMAP_FILTERING; ++ | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LEGACY_SHADER_CONSTANTS; + + d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl; + d3d8->refcount = 1; +diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c +index 1d3754a..f42c5ea 100644 +--- a/dll/directx/wine/d3d9/directx.c ++++ b/dll/directx/wine/d3d9/directx.c +@@ -583,7 +583,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) + DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER + | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR + | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING +- | WINED3D_NORMALIZED_DEPTH_BIAS; ++ | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LEGACY_SHADER_CONSTANTS; + + if (!extended) + flags |= WINED3D_VIDMEM_ACCOUNTING; diff --git a/sdk/tools/winesync/d3dlegacy_staging/0004-d3d9__Support_SWVP_vertex_shader_float_constants_limits.diff b/sdk/tools/winesync/d3dlegacy_staging/0004-d3d9__Support_SWVP_vertex_shader_float_constants_limits.diff new file mode 100644 index 00000000000..3cd6fc8246f --- /dev/null +++ b/sdk/tools/winesync/d3dlegacy_staging/0004-d3d9__Support_SWVP_vertex_shader_float_constants_limits.diff @@ -0,0 +1,130 @@ +diff --git a/dll/directx/wine/d3d9/d3d9_private.h b/dll/directx/wine/d3d9/d3d9_private.h +index 03e2aa7..03d804a 100644 +--- a/dll/directx/wine/d3d9/d3d9_private.h ++++ b/dll/directx/wine/d3d9/d3d9_private.h +@@ -40,6 +40,7 @@ + #include "wine/wined3d.h" + + #define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 ++#define D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP 8192 + #define D3D9_MAX_TEXTURE_UNITS 20 + #define D3D9_MAX_STREAMS 16 + +@@ -56,7 +57,7 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_H + unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags, unsigned int usage) DECLSPEC_HIDDEN; + void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, + const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) DECLSPEC_HIDDEN; +-void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps) DECLSPEC_HIDDEN; ++void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps, DWORD flags) DECLSPEC_HIDDEN; + + struct d3d9 + { +diff --git a/dll/directx/wine/d3d9/device.c b/dll/directx/wine/d3d9/device.c +index 3d16812..c7bbb9e 100644 +--- a/dll/directx/wine/d3d9/device.c ++++ b/dll/directx/wine/d3d9/device.c +@@ -360,7 +360,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch + return TRUE; + } + +-void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps) ++void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps, DWORD creation_flags) + { + static const DWORD ps_minor_version[] = {0, 4, 0, 0}; + static const DWORD vs_minor_version[] = {0, 1, 0, 0}; +@@ -498,7 +498,10 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d + D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | + D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; + +- caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); ++ if (creation_flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP, caps->MaxVertexShaderConst); ++ else ++ caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); + caps->NumSimultaneousRTs = min(D3D_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs); + + if (caps->PixelShaderVersion > 3) +@@ -684,6 +687,7 @@ static HRESULT WINAPI d3d9_device_GetDirect3D(IDirect3DDevice9Ex *iface, IDirect + static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *caps) + { + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); ++ struct wined3d_device_creation_parameters creation_parameters; + struct wined3d_caps wined3d_caps; + HRESULT hr; + +@@ -692,13 +696,15 @@ static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCA + if (!caps) + return D3DERR_INVALIDCALL; + ++ wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters); ++ + memset(caps, 0, sizeof(*caps)); + + wined3d_mutex_lock(); + hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); + wined3d_mutex_unlock(); + +- d3dcaps_from_wined3dcaps(caps, &wined3d_caps); ++ d3dcaps_from_wined3dcaps(caps, &wined3d_caps, creation_parameters.flags); + + return hr; + } +@@ -3471,14 +3477,20 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantF(IDirect3DDevice9Ex *i + UINT reg_idx, const float *data, UINT count) + { + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); ++ struct wined3d_device_creation_parameters creation_parameters; ++ unsigned int max_constants; + HRESULT hr; + + TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); + +- if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF) ++ wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters); ++ max_constants = creation_parameters.flags ++ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ ? D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP : D3D9_MAX_VERTEX_SHADER_CONSTANTF; ++ if (reg_idx + count > max_constants) + { + WARN("Trying to access %u constants, but d3d9 only supports %u\n", +- reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF); ++ reg_idx + count, max_constants); + return D3DERR_INVALIDCALL; + } + +@@ -3499,14 +3511,20 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *i + UINT reg_idx, float *data, UINT count) + { + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); ++ struct wined3d_device_creation_parameters creation_parameters; ++ unsigned int max_constants; + HRESULT hr; + + TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); + +- if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF) ++ wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters); ++ max_constants = creation_parameters.flags ++ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ ? D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP : D3D9_MAX_VERTEX_SHADER_CONSTANTF; ++ if (reg_idx + count > max_constants) + { + WARN("Trying to access %u constants, but d3d9 only supports %u\n", +- reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF); ++ reg_idx + count, max_constants); + return D3DERR_INVALIDCALL; + } + +diff --git a/dll/directx/wine/d3d9/directx.c b/dll/directx/wine/d3d9/directx.c +index f42c5ea..da80033 100644 +--- a/dll/directx/wine/d3d9/directx.c ++++ b/dll/directx/wine/d3d9/directx.c +@@ -370,7 +370,7 @@ static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DD + hr = wined3d_get_device_caps(d3d9->wined3d, adapter, device_type, &wined3d_caps); + wined3d_mutex_unlock(); + +- d3dcaps_from_wined3dcaps(caps, &wined3d_caps); ++ d3dcaps_from_wined3dcaps(caps, &wined3d_caps, 0); + + return hr; + } diff --git a/sdk/tools/winesync/ddraw.cfg b/sdk/tools/winesync/ddraw.cfg new file mode 100644 index 00000000000..59e2e7f8a1a --- /dev/null +++ b/sdk/tools/winesync/ddraw.cfg @@ -0,0 +1,5 @@ +directories: + dlls/ddraw: dll/directx/wine/ddraw +files: null +tags: + wine: wine-4.18 diff --git a/sdk/tools/winesync/ddraw_staging/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff b/sdk/tools/winesync/ddraw_staging/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff new file mode 100644 index 00000000000..a92d5bd906c --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0001-ddraw__Avoid_implicit_cast_of_interface_pointer.diff @@ -0,0 +1,22 @@ +diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c +index 5fc7a4b..ab6bada 100644 +--- a/dll/directx/wine/ddraw/viewport.c ++++ b/dll/directx/wine/ddraw/viewport.c +@@ -1220,7 +1220,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *ifa + /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ + if (!iface) return NULL; + assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl); +- return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); ++ return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); + } + + struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface) +@@ -1228,7 +1228,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface + /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ + if (!iface) return NULL; + assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl); +- return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); ++ return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); + } + + void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) diff --git a/sdk/tools/winesync/ddraw_staging/0002-ddraw__Don_t_set_HWTRANSFORMANDLIGHT_flag_on_d3d7_RGB_device.diff b/sdk/tools/winesync/ddraw_staging/0002-ddraw__Don_t_set_HWTRANSFORMANDLIGHT_flag_on_d3d7_RGB_device.diff new file mode 100644 index 00000000000..cb6cf39723e --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0002-ddraw__Don_t_set_HWTRANSFORMANDLIGHT_flag_on_d3d7_RGB_device.diff @@ -0,0 +1,60 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 2c76190..9429ca5 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -49,6 +49,7 @@ static struct enum_device_entry + char interface_name[100]; + char device_name[100]; + const GUID *device_guid; ++ DWORD remove_caps; + } device_list7[] = + { + /* T&L HAL device */ +@@ -56,6 +57,7 @@ static struct enum_device_entry + "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", + "Wine D3D7 T&L HAL", + &IID_IDirect3DTnLHalDevice, ++ 0, + }, + + /* HAL device */ +@@ -63,6 +65,7 @@ static struct enum_device_entry + "WINE Direct3D7 Hardware acceleration using WineD3D", + "Direct3D HAL", + &IID_IDirect3DHALDevice, ++ 0, + }, + + /* RGB device */ +@@ -70,6 +73,7 @@ static struct enum_device_entry + "WINE Direct3D7 RGB Software Emulation using WineD3D", + "Wine D3D7 RGB", + &IID_IDirect3DRGBDevice, ++ D3DDEVCAPS_HWTRANSFORMANDLIGHT, + }, + }; + +@@ -3631,6 +3635,7 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + { + struct ddraw *ddraw = impl_from_IDirect3D7(iface); + D3DDEVICEDESC7 device_desc7; ++ DWORD dev_caps; + HRESULT hr; + size_t i; + +@@ -3647,11 +3652,15 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + return hr; + } + ++ dev_caps = device_desc7.dwDevCaps; ++ + for (i = 0; i < ARRAY_SIZE(device_list7); i++) + { + HRESULT ret; + + device_desc7.deviceGUID = *device_list7[i].device_guid; ++ device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; ++ + ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); + if (ret != DDENUMRET_OK) + { diff --git a/sdk/tools/winesync/ddraw_staging/0003-ddraw__Set_dwZBufferBitDepth_in_ddraw7_GetCaps.diff b/sdk/tools/winesync/ddraw_staging/0003-ddraw__Set_dwZBufferBitDepth_in_ddraw7_GetCaps.diff new file mode 100644 index 00000000000..9b9b514db94 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0003-ddraw__Set_dwZBufferBitDepth_in_ddraw7_GetCaps.diff @@ -0,0 +1,42 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 9429ca5..46bfbd2 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -1416,6 +1416,28 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) + return DD_OK; + } + ++HRESULT CALLBACK enum_zbuffer(DDPIXELFORMAT *format, void *ctx) ++{ ++ DDCAPS *caps = ctx; ++ ++ switch (format->u1.dwZBufferBitDepth) ++ { ++ case 8: ++ caps->dwZBufferBitDepths |= DDBD_8; ++ break; ++ case 16: ++ caps->dwZBufferBitDepths |= DDBD_16; ++ break; ++ case 24: ++ caps->dwZBufferBitDepths |= DDBD_24; ++ break; ++ case 32: ++ caps->dwZBufferBitDepths |= DDBD_32; ++ break; ++ } ++ return D3DENUMRET_OK; ++} ++ + /***************************************************************************** + * IDirectDraw7::GetCaps + * +@@ -1496,6 +1518,8 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD + caps.dwCaps |= DDCAPS_ALIGNSTRIDE; + caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT; + ++ IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps); ++ + caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps; + + if(DriverCaps) diff --git a/sdk/tools/winesync/ddraw_staging/0004-ddraw_tests__Add_more_tests_for_IDirectDraw7__EnumSurfaces.diff b/sdk/tools/winesync/ddraw_staging/0004-ddraw_tests__Add_more_tests_for_IDirectDraw7__EnumSurfaces.diff new file mode 100644 index 00000000000..eba52bbf111 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0004-ddraw_tests__Add_more_tests_for_IDirectDraw7__EnumSurfaces.diff @@ -0,0 +1,14 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 46bfbd2..165200e 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -3237,6 +3237,9 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, + if (!Callback) + return DDERR_INVALIDPARAMS; + ++ if (!all && !DDSD) ++ return DDERR_INVALIDPARAMS; ++ + wined3d_mutex_lock(); + + /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ diff --git a/sdk/tools/winesync/ddraw_staging/0005-ddraw__Implement_DDENUMSURFACES_CANBECREATED_flag_in_ddraw7_EnumSurfaces.diff b/sdk/tools/winesync/ddraw_staging/0005-ddraw__Implement_DDENUMSURFACES_CANBECREATED_flag_in_ddraw7_EnumSurfaces.diff new file mode 100644 index 00000000000..7df312fb608 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0005-ddraw__Implement_DDENUMSURFACES_CANBECREATED_flag_in_ddraw7_EnumSurfaces.diff @@ -0,0 +1,127 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 165200e..68e9286 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -3224,49 +3224,97 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, + { + struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + struct ddraw_surface *surf; +- BOOL all, nomatch; +- DDSURFACEDESC2 desc; +- struct list *entry, *entry2; ++ DWORD match_flags = Flags & (DDENUMSURFACES_ALL | DDENUMSURFACES_NOMATCH | DDENUMSURFACES_MATCH); + + TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n", + iface, Flags, DDSD, Context, Callback); + +- all = Flags & DDENUMSURFACES_ALL; +- nomatch = Flags & DDENUMSURFACES_NOMATCH; +- + if (!Callback) + return DDERR_INVALIDPARAMS; + +- if (!all && !DDSD) +- return DDERR_INVALIDPARAMS; ++ if (Flags & DDENUMSURFACES_CANBECREATED) ++ { ++ IDirectDrawSurface7 *surface; ++ DDSURFACEDESC2 testdesc; ++ HRESULT hr; + +- wined3d_mutex_lock(); ++ if (match_flags != DDENUMSURFACES_MATCH) ++ return DDERR_INVALIDPARAMS; + +- /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ +- LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) +- { +- surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); ++ if (!DDSD) ++ return DDERR_INVALIDPARAMS; + +- if (!surf->iface_count) ++ memcpy(&testdesc, DDSD, sizeof(testdesc)); ++ if (!(testdesc.dwFlags & DDSD_WIDTH)) + { +- WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); +- continue; ++ testdesc.dwFlags |= DDSD_WIDTH; ++ testdesc.dwWidth = 512; ++ } ++ if (!(testdesc.dwFlags & DDSD_HEIGHT)) ++ { ++ testdesc.dwFlags |= DDSD_HEIGHT; ++ testdesc.dwHeight = 512; + } + +- if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) ++ hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL); ++ if (SUCCEEDED(hr)) ++ { ++ surf = unsafe_impl_from_IDirectDrawSurface7(surface); ++ Callback(NULL, &surf->surface_desc, Context); ++ IDirectDrawSurface7_Release(surface); ++ } ++ else ++ ERR("Failed to create surface, hr %#x.\n", hr); ++ } ++ else if (Flags & DDENUMSURFACES_DOESEXIST) ++ { ++ BOOL all, nomatch; ++ DDSURFACEDESC2 desc; ++ struct list *entry, *entry2; ++ ++ /* a combination of match flags is not allowed */ ++ if (match_flags != 0 && ++ match_flags != DDENUMSURFACES_ALL && ++ match_flags != DDENUMSURFACES_MATCH && ++ match_flags != DDENUMSURFACES_NOMATCH) ++ return DDERR_INVALIDPARAMS; ++ ++ all = (Flags & DDENUMSURFACES_ALL) != 0; ++ nomatch = (Flags & DDENUMSURFACES_NOMATCH) != 0; ++ ++ if (!all && !DDSD) ++ return DDERR_INVALIDPARAMS; ++ ++ wined3d_mutex_lock(); ++ ++ /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ ++ LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) + { +- TRACE("Enumerating surface %p.\n", surf); +- desc = surf->surface_desc; +- IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); +- if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK) ++ surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); ++ ++ if (!surf->iface_count) + { +- wined3d_mutex_unlock(); +- return DD_OK; ++ WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); ++ continue; ++ } ++ ++ if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) ++ { ++ TRACE("Enumerating surface %p.\n", surf); ++ desc = surf->surface_desc; ++ IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); ++ if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK) ++ { ++ wined3d_mutex_unlock(); ++ return DD_OK; ++ } + } + } +- } + +- wined3d_mutex_unlock(); ++ wined3d_mutex_unlock(); ++ } ++ else ++ return DDERR_INVALIDPARAMS; + + return DD_OK; + } diff --git a/sdk/tools/winesync/ddraw_staging/0006-ddraw__Allow_size_and_format_conversions_in_IDirect3DTexture2__Load.diff b/sdk/tools/winesync/ddraw_staging/0006-ddraw__Allow_size_and_format_conversions_in_IDirect3DTexture2__Load.diff new file mode 100644 index 00000000000..3731a0f4ec8 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0006-ddraw__Allow_size_and_format_conversions_in_IDirect3DTexture2__Load.diff @@ -0,0 +1,203 @@ +diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c +index 6c27d8c..66e5a9e 100644 +--- a/dll/directx/wine/ddraw/surface.c ++++ b/dll/directx/wine/ddraw/surface.c +@@ -5247,6 +5247,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) + return impl_from_IDirectDrawSurface7(next_level); + } + ++static BOOL compare_format(DDPIXELFORMAT *format1, DDPIXELFORMAT *format2) ++{ ++ if ((format1->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)) != ++ (format2->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC))) ++ return FALSE; ++ ++ if (format1->dwFlags & (DDPF_RGB|DDPF_YUV)) ++ { ++ if (!(format1->dwFlags & DDPF_ALPHA)) ++ { ++ /* The RGB and YUV bits are stored in the same fields */ ++ if (format1->u1.dwRGBBitCount != format2->u1.dwRGBBitCount) ++ return FALSE; ++ ++ if (format1->u2.dwRBitMask != format2->u2.dwRBitMask) ++ return FALSE; ++ ++ if (format1->u3.dwGBitMask != format2->u3.dwGBitMask) ++ return FALSE; ++ ++ if (format1->u4.dwBBitMask != format2->u4.dwBBitMask) ++ return FALSE; ++ } ++ ++ if (format1->dwFlags & (DDPF_ALPHAPIXELS | DDPF_ALPHA)) ++ { ++ if (format1->u5.dwRGBAlphaBitMask != format2->u5.dwRGBAlphaBitMask) ++ return FALSE; ++ } ++ } ++ ++ if (format1->dwFlags & DDPF_FOURCC) ++ { ++ if (format1->dwFourCC != format2->dwFourCC) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + /***************************************************************************** + * IDirect3DTexture2::Load + * +@@ -5268,7 +5308,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + { + struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface); + struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture); +- struct wined3d_resource *dst_resource, *src_resource; ++ RECT src_rect, dst_rect; + HRESULT hr; + + TRACE("iface %p, src_texture %p.\n", iface, src_texture); +@@ -5281,90 +5321,60 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + + wined3d_mutex_lock(); + +- dst_resource = wined3d_texture_get_resource(dst_surface->wined3d_texture); +- src_resource = wined3d_texture_get_resource(src_surface->wined3d_texture); +- +- if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) +- != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) +- || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) +- { +- ERR("Trying to load surfaces with different mip-map counts.\n"); +- } +- + for (;;) + { +- struct ddraw_palette *dst_pal, *src_pal; +- DDSURFACEDESC *src_desc, *dst_desc; ++ DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc; + + TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface); + +- /* Suppress the ALLOCONLOAD flag */ +- dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; +- +- /* Get the palettes */ +- dst_pal = dst_surface->palette; +- src_pal = src_surface->palette; +- +- if (src_pal) ++ if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat, ++ &dst_surface->surface_desc.u4.ddpfPixelFormat)) + { +- PALETTEENTRY palent[256]; ++ struct ddraw_palette *dst_pal, *src_pal; + +- if (!dst_pal) +- { +- wined3d_mutex_unlock(); +- return DDERR_NOPALETTEATTACHED; +- } +- IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); +- IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); +- } ++ /* Get the palettes */ ++ dst_pal = dst_surface->palette; ++ src_pal = src_surface->palette; + +- /* Copy one surface on the other */ +- dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); +- src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); ++ if (src_pal) ++ { ++ PALETTEENTRY palent[256]; + +- if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight)) +- { +- /* Should also check for same pixel format, u1.lPitch, ... */ +- ERR("Error in surface sizes.\n"); +- wined3d_mutex_unlock(); +- return D3DERR_TEXTURE_LOAD_FAILED; +- } +- else +- { +- struct wined3d_map_desc src_map_desc, dst_map_desc; ++ if (!dst_pal) ++ { ++ wined3d_mutex_unlock(); ++ return DDERR_NOPALETTEATTACHED; ++ } ++ IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); ++ IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); ++ } + +- /* Copy the src blit color key if the source has one, don't erase +- * the destination's ckey if the source has none */ + if (src_desc->dwFlags & DDSD_CKSRCBLT) + { + IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface, + DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt); + } ++ } ++ else ++ { ++ if (src_desc->dwFlags & DDSD_CKSRCBLT) ++ return E_FAIL; ++ } + +- if (FAILED(hr = wined3d_resource_map(src_resource, +- src_surface->sub_resource_idx, &src_map_desc, NULL, WINED3D_MAP_READ))) +- { +- ERR("Failed to lock source surface, hr %#x.\n", hr); +- wined3d_mutex_unlock(); +- return D3DERR_TEXTURE_LOAD_FAILED; +- } +- +- if (FAILED(hr = wined3d_resource_map(dst_resource, +- dst_surface->sub_resource_idx, &dst_map_desc, NULL, WINED3D_MAP_WRITE))) +- { +- ERR("Failed to lock destination surface, hr %#x.\n", hr); +- wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); +- wined3d_mutex_unlock(); +- return D3DERR_TEXTURE_LOAD_FAILED; +- } ++ /* Suppress the ALLOCONLOAD flag */ ++ dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + +- if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) +- memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize); +- else +- memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); ++ SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, src_surface->surface_desc.dwHeight); ++ SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, dst_surface->surface_desc.dwHeight); + +- wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx); +- wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); ++ hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, &dst_rect, ++ src_surface->wined3d_texture, src_surface->sub_resource_idx, &src_rect, ++ 0, NULL, WINED3D_TEXF_LINEAR); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to blit surface, hr %#x.\n", hr); ++ wined3d_mutex_unlock(); ++ return hr; + } + + if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) +@@ -5377,12 +5387,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + else + dst_surface = NULL; + ++ if (src_surface && !dst_surface) ++ return DDERR_NOTFOUND; ++ + if (!src_surface || !dst_surface) +- { +- if (src_surface != dst_surface) +- ERR("Loading surface with different mipmap structure.\n"); + break; +- } + } + + wined3d_mutex_unlock(); diff --git a/sdk/tools/winesync/ddraw_staging/0007-ddraw__Create_rendering_targets_in_video_memory_if_possible.diff b/sdk/tools/winesync/ddraw_staging/0007-ddraw__Create_rendering_targets_in_video_memory_if_possible.diff new file mode 100644 index 00000000000..8607abbed6b --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0007-ddraw__Create_rendering_targets_in_video_memory_if_possible.diff @@ -0,0 +1,197 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 68e9286..1141739 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -4296,7 +4296,7 @@ static HRESULT WINAPI d3d7_CreateDevice(IDirect3D7 *iface, REFCLSID riid, + TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device); + + wined3d_mutex_lock(); +- if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL))) ++ if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, target, (IUnknown *)surface, 7, &object, NULL))) + { + *device = &object->IDirect3DDevice7_iface; + } +@@ -4325,7 +4325,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, + return CLASS_E_NOAGGREGATION; + + wined3d_mutex_lock(); +- if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) ++ if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) + { + *device = &device_impl->IDirect3DDevice3_iface; + } +@@ -4351,7 +4351,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, + iface, debugstr_guid(riid), surface, device); + + wined3d_mutex_lock(); +- if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) ++ if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) + { + *device = &device_impl->IDirect3DDevice2_iface; + } +diff --git a/dll/directx/wine/ddraw/ddraw_private.h b/dll/directx/wine/ddraw/ddraw_private.h +index 771b2a4..4bf0e46 100644 +--- a/dll/directx/wine/ddraw/ddraw_private.h ++++ b/dll/directx/wine/ddraw/ddraw_private.h +@@ -307,6 +307,7 @@ struct d3d_device + IUnknown IUnknown_inner; + LONG ref; + UINT version; ++ BOOL hw; + + IUnknown *outer_unknown; + struct wined3d_device *wined3d_device; +@@ -354,7 +355,7 @@ struct d3d_device + struct wined3d_stateblock *recording; + }; + +-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, ++HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, + UINT version, struct d3d_device **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN; + enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) DECLSPEC_HIDDEN; + +diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c +index 43e5d0a..5d18a12 100644 +--- a/dll/directx/wine/ddraw/device.c ++++ b/dll/directx/wine/ddraw/device.c +@@ -1854,7 +1854,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, + return DDERR_INVALIDCAPS; + } + +- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) ++ if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target_impl); + wined3d_mutex_unlock(); +@@ -1930,7 +1930,7 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, + return DDERR_INVALIDPIXELFORMAT; + } + +- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) ++ if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target_impl); + IDirectDrawSurface4_AddRef(target); +@@ -1979,7 +1979,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, + return DDERR_INVALIDPIXELFORMAT; + } + +- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) ++ if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target_impl); + IDirectDrawSurface_AddRef(target); +@@ -6933,7 +6933,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device + return WINED3D_ZB_TRUE; + } + +-static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, ++static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, BOOL hw, + struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown) + { + static const D3DMATRIX ident = +@@ -6956,6 +6956,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, + device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl; + device->ref = 1; + device->version = version; ++ device->hw = hw; + + if (outer_unknown) + device->outer_unknown = outer_unknown; +@@ -7009,14 +7010,18 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, + return D3D_OK; + } + +-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, ++HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, + UINT version, struct d3d_device **device, IUnknown *outer_unknown) + { + struct d3d_device *object; ++ BOOL hw = TRUE; + HRESULT hr; + +- TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n", +- ddraw, target, version, device, outer_unknown); ++ TRACE("ddraw %p, guid %s, target %p, version %u, device %p, outer_unknown %p.\n", ++ ddraw, debugstr_guid(guid), target, version, device, outer_unknown); ++ ++ if (IsEqualGUID(guid, &IID_IDirect3DRGBDevice)) ++ hw = FALSE; + + if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) +@@ -7039,7 +7044,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn + return DDERR_OUTOFMEMORY; + } + +- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) ++ if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target); + return D3DERR_SURFACENOTINVIDMEM; +@@ -7057,7 +7062,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn + return DDERR_OUTOFMEMORY; + } + +- if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown))) ++ if (FAILED(hr = d3d_device_init(object, ddraw, hw, target, rt_iface, version, outer_unknown))) + { + WARN("Failed to initialize device, hr %#x.\n", hr); + heap_free(object); +diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c +index 66e5a9e..31ccce2 100644 +--- a/dll/directx/wine/ddraw/surface.c ++++ b/dll/directx/wine/ddraw/surface.c +@@ -223,7 +223,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, + { + HRESULT hr; + +- if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface, ++ if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface, + 1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface))) + { + This->device1 = NULL; +@@ -6197,7 +6197,42 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ + + if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + { +- wined3d_desc.access = WINED3D_RESOURCE_ACCESS_CPU ++ unsigned int bind_flags = 0; ++ ++ if (!(desc->dwFlags & DDSD_LPSURFACE)) ++ { ++ if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) ++ { ++ bind_flags |= WINED3D_BIND_SHADER_RESOURCE; ++ } ++ else if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) ++ { ++ bind_flags |= WINED3D_BIND_SHADER_RESOURCE; ++ } ++ ++ if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) ++ bind_flags |= WINED3D_BIND_DEPTH_STENCIL; ++ else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) ++ bind_flags |= WINED3D_BIND_RENDER_TARGET; ++ } ++ /* ++ * The ddraw RGB device allows to use system memory surfaces as rendering target. ++ * This does not cause problems because the RGB device does software rasterization ++ * though it will fail with hardware accelerated ddraw. In order to be partially ++ * compatible with games requesting explicitly the RGB device, we ignore the ++ * specified location and try to create rendering targets in video memory if ++ * possible. ++ */ ++ if (bind_flags ++ && SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, ++ WINED3D_DEVICE_TYPE_HAL, mode.format_id, 0, ++ bind_flags, WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) ++ { ++ FIXME("Application wants to create rendering target in system memory, using video memory instead\n"); ++ wined3d_desc.bind_flags = bind_flags; ++ } ++ else ++ wined3d_desc.access = WINED3D_RESOURCE_ACCESS_CPU + | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; + } + else diff --git a/sdk/tools/winesync/ddraw_staging/0008-ddraw__Silence_noisy_FIXME_about_unimplemented_D3DPROCESSVERTICES_UPDATEEXTENTS.diff b/sdk/tools/winesync/ddraw_staging/0008-ddraw__Silence_noisy_FIXME_about_unimplemented_D3DPROCESSVERTICES_UPDATEEXTENTS.diff new file mode 100644 index 00000000000..41926180cf6 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0008-ddraw__Silence_noisy_FIXME_about_unimplemented_D3DPROCESSVERTICES_UPDATEEXTENTS.diff @@ -0,0 +1,16 @@ +diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c +index 80dbdfd..ee80327 100644 +--- a/dll/directx/wine/ddraw/executebuffer.c ++++ b/dll/directx/wine/ddraw/executebuffer.c +@@ -293,7 +293,10 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d + ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); + + if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS) +- FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); ++ { ++ static int once; ++ if (!once++) FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); ++ } + if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR) + FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n"); + diff --git a/sdk/tools/winesync/ddraw_staging/0009-ddraw__Allow_setting_texture_without_DDSCAPS_TEXTURE_for_software_device.diff b/sdk/tools/winesync/ddraw_staging/0009-ddraw__Allow_setting_texture_without_DDSCAPS_TEXTURE_for_software_device.diff new file mode 100644 index 00000000000..33f20bac036 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0009-ddraw__Allow_setting_texture_without_DDSCAPS_TEXTURE_for_software_device.diff @@ -0,0 +1,59 @@ +diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c +index 5d18a12..3d38ba6 100644 +--- a/dll/directx/wine/ddraw/device.c ++++ b/dll/directx/wine/ddraw/device.c +@@ -2910,10 +2910,8 @@ static HRESULT WINAPI d3d_device3_SetLightState(IDirect3DDevice3 *iface, + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } +- + material_activate(m); + } +- + device->material = value; + } + else if (state == D3DLIGHTSTATE_COLORMODEL) +@@ -4794,7 +4792,8 @@ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface, + struct ddraw_surface *surf = unsafe_impl_from_IDirectDrawSurface7(texture); + struct wined3d_texture *wined3d_texture = NULL; + +- TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); ++ TRACE("iface %p, stage %u, texture %p, surf %p, surf->surface_desc.ddsCaps.dwCaps %#x.\n", ++ iface, stage, texture, surf, surf ? surf->surface_desc.ddsCaps.dwCaps : 0); + + if (surf && (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + wined3d_texture = surf->wined3d_texture; +@@ -4830,19 +4829,30 @@ static HRESULT WINAPI d3d_device3_SetTexture(IDirect3DDevice3 *iface, + { + struct d3d_device *device = impl_from_IDirect3DDevice3(iface); + struct ddraw_surface *tex = unsafe_impl_from_IDirect3DTexture2(texture); +- HRESULT hr; ++ struct wined3d_texture *wined3d_texture; + + TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); + + wined3d_mutex_lock(); + +- hr = IDirect3DDevice7_SetTexture(&device->IDirect3DDevice7_iface, stage, &tex->IDirectDrawSurface7_iface); ++ if (tex && ((tex->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) || !device->hw)) ++ { ++ if (!(tex->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) ++ WARN("Setting texture without DDSCAPS_TEXTURE.\n"); ++ wined3d_texture = tex->wined3d_texture; ++ } ++ else ++ { ++ wined3d_texture = NULL; ++ } ++ ++ wined3d_device_set_texture(device->wined3d_device, stage, wined3d_texture); + + fixup_texture_alpha_op(device); + + wined3d_mutex_unlock(); + +- return hr; ++ return D3D_OK; + } + + static const struct tss_lookup diff --git a/sdk/tools/winesync/ddraw_staging/0010-ddraw__Remove_const_from_ddraw1_vtbl_and_ddraw_surface1_vtbl.diff b/sdk/tools/winesync/ddraw_staging/0010-ddraw__Remove_const_from_ddraw1_vtbl_and_ddraw_surface1_vtbl.diff new file mode 100644 index 00000000000..ab4dc06608f --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0010-ddraw__Remove_const_from_ddraw1_vtbl_and_ddraw_surface1_vtbl.diff @@ -0,0 +1,26 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 1141739..83c7ae3 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -4723,7 +4723,7 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl = + ddraw2_GetAvailableVidMem, + }; + +-static const struct IDirectDrawVtbl ddraw1_vtbl = ++static struct IDirectDrawVtbl ddraw1_vtbl = + { + /* IUnknown */ + ddraw1_QueryInterface, +diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c +index 31ccce2..0a477d5 100644 +--- a/dll/directx/wine/ddraw/surface.c ++++ b/dll/directx/wine/ddraw/surface.c +@@ -5621,7 +5621,7 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = + ddraw_surface2_PageUnlock, + }; + +-static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = ++static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = + { + /* IUnknown */ + ddraw_surface1_QueryInterface, diff --git a/sdk/tools/winesync/ddraw_staging/0011-ddraw__Allow_writing_to_vtable_for_surface_and_palette.diff b/sdk/tools/winesync/ddraw_staging/0011-ddraw__Allow_writing_to_vtable_for_surface_and_palette.diff new file mode 100644 index 00000000000..d0c05288d87 --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0011-ddraw__Allow_writing_to_vtable_for_surface_and_palette.diff @@ -0,0 +1,53 @@ +diff --git a/dll/directx/wine/ddraw/palette.c b/dll/directx/wine/ddraw/palette.c +index 980c62b..89e4fa6 100644 +--- a/dll/directx/wine/ddraw/palette.c ++++ b/dll/directx/wine/ddraw/palette.c +@@ -215,7 +215,7 @@ static HRESULT WINAPI ddraw_palette_GetEntries(IDirectDrawPalette *iface, + return hr; + } + +-static const struct IDirectDrawPaletteVtbl ddraw_palette_vtbl = ++static struct IDirectDrawPaletteVtbl ddraw_palette_vtbl = + { + /*** IUnknown ***/ + ddraw_palette_QueryInterface, +diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c +index 0a477d5..e4ae2d6 100644 +--- a/dll/directx/wine/ddraw/surface.c ++++ b/dll/directx/wine/ddraw/surface.c +@@ -5414,7 +5414,7 @@ static HRESULT WINAPI d3d_texture1_Load(IDirect3DTexture *iface, IDirect3DTextur + * The VTable + *****************************************************************************/ + +-static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = ++static struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = + { + /* IUnknown */ + ddraw_surface7_QueryInterface, +@@ -5473,7 +5473,7 @@ static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = + ddraw_surface7_GetLOD, + }; + +-static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = ++static struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = + { + /* IUnknown */ + ddraw_surface4_QueryInterface, +@@ -5527,7 +5527,7 @@ static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = + ddraw_surface4_ChangeUniquenessValue, + }; + +-static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = ++static struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = + { + /* IUnknown */ + ddraw_surface3_QueryInterface, +@@ -5575,7 +5575,7 @@ static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = + ddraw_surface3_SetSurfaceDesc, + }; + +-static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = ++static struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = + { + /* IUnknown */ + ddraw_surface2_QueryInterface, diff --git a/sdk/tools/winesync/ddraw_staging/0012-ddraw__Return_correct_devices_based_off_requested_DirectX_version.diff b/sdk/tools/winesync/ddraw_staging/0012-ddraw__Return_correct_devices_based_off_requested_DirectX_version.diff new file mode 100644 index 00000000000..edb7ebcddaf --- /dev/null +++ b/sdk/tools/winesync/ddraw_staging/0012-ddraw__Return_correct_devices_based_off_requested_DirectX_version.diff @@ -0,0 +1,326 @@ +diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c +index 83c7ae3..aaeff43 100644 +--- a/dll/directx/wine/ddraw/ddraw.c ++++ b/dll/directx/wine/ddraw/ddraw.c +@@ -44,37 +44,80 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier = + 0 + }; + ++#define D3D_VERSION(x) (1 << (x)) ++ + static struct enum_device_entry + { +- char interface_name[100]; ++ unsigned int version_mask; ++ /* Some games (Motoracer 2 demo) have the bad idea to modify the device ++ * name/description strings. Let's put the strings in sufficiently sized ++ * arrays in static-lifetime writable memory. */ ++ char device_desc[100]; + char device_name[100]; + const GUID *device_guid; + DWORD remove_caps; +-} device_list7[] = ++} device_list[] = + { +- /* T&L HAL device */ ++ /* Ramp Emulation (D3D 1&2 only) */ + { +- "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", +- "Wine D3D7 T&L HAL", +- &IID_IDirect3DTnLHalDevice, ++ D3D_VERSION(1)|D3D_VERSION(2), ++ "WineD3D Ramp Software Emulation", ++ "Ramp Emulation", ++ &IID_IDirect3DRampDevice, + 0, + }, + +- /* HAL device */ ++ /* RGB Emulation (D3D 1-7) */ + { +- "WINE Direct3D7 Hardware acceleration using WineD3D", ++ D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7), ++ "WineD3D RGB Software Emulation", ++ "RGB Emulation", ++ &IID_IDirect3DRGBDevice, ++ D3DDEVCAPS_HWTRANSFORMANDLIGHT, ++ }, ++ ++ /* Direct3D HAL (D3D 1-7) */ ++ { ++ D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7), ++ "WineD3D Hardware Acceleration", + "Direct3D HAL", + &IID_IDirect3DHALDevice, + 0, + }, + +- /* RGB device */ ++ /* MMX Emulation (D3D2 only) */ + { +- "WINE Direct3D7 RGB Software Emulation using WineD3D", +- "Wine D3D7 RGB", +- &IID_IDirect3DRGBDevice, +- D3DDEVCAPS_HWTRANSFORMANDLIGHT, ++ D3D_VERSION(2), ++ "WineD3D MMX Software Emulation", ++ "MMX Emulation", ++ &IID_IDirect3DMMXDevice, ++ 0, ++ }, ++ ++ /* Direct3D T&L HAL (D3D7 only) */ ++ { ++ D3D_VERSION(7), ++ "WineD3D Hardware Transform and Lighting Acceleration", ++ "Direct3D T&L HAL", ++ &IID_IDirect3DTnLHalDevice, ++ 0, + }, ++ ++ /* In the future, we may wish to add the "Reference Rasterizer" and ++ * "Null device", which are only available in DX6-8 and must be explicitly ++ * enabled by the registry values: ++ * * EnumReference ++ * * EnumNullDevice, ++ * which are DWORD values which must be created under ++ * HKLM\Software\Microsoft\Direct3D\Drivers and set to any nonzero value. ++ * (Refer to enablerefrast.reg/disablerefrast.reg in the DX6/7 SDKs and ++ * KB249579 for more information.) ++ * ++ * DirectX 9.0 and higher appear to no longer recognize these settings, ++ * so apparently these devices were removed starting with DX9. ++ * ++ * Some games (AvP, Motoracer 2) break if these devices are enumerated. ++ */ + }; + + static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {} +@@ -1371,15 +1414,6 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) + D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | + D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV); + +- if (!(caps->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2)) +- { +- /* DirectX7 always has the np2 flag set, no matter what the card +- * supports. Some old games (Rollcage) check the caps incorrectly. +- * If wined3d supports nonpow2 textures it also has np2 conditional +- * support. */ +- caps->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL; +- } +- + /* Fill the missing members, and do some fixup */ + caps->dpcLineCaps.dwSize = sizeof(caps->dpcLineCaps); + caps->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD +@@ -3695,8 +3729,7 @@ static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface, IDirectDrawSur + /***************************************************************************** + * IDirect3D7::EnumDevices + * +- * The EnumDevices method for IDirect3D7. It enumerates all supported +- * D3D7 devices. Currently the T&L, HAL and RGB devices are enumerated. ++ * The EnumDevices method for IDirect3D7. It enumerates all D3D7 devices. + * + * Params: + * callback: Function to call for each enumerated device +@@ -3729,14 +3762,17 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + + dev_caps = device_desc7.dwDevCaps; + +- for (i = 0; i < ARRAY_SIZE(device_list7); i++) ++ for (i = 0; i < ARRAY_SIZE(device_list); i++) + { + HRESULT ret; + +- device_desc7.deviceGUID = *device_list7[i].device_guid; +- device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; ++ if (!(device_list[i].version_mask & D3D_VERSION(ddraw->d3dversion))) ++ continue; ++ ++ device_desc7.deviceGUID = *device_list[i].device_guid; ++ device_desc7.dwDevCaps = dev_caps & ~device_list[i].remove_caps; + +- ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); ++ ret = callback(device_list[i].device_name, device_list[i].device_name, &device_desc7, context); + if (ret != DDENUMRET_OK) + { + TRACE("Application cancelled the enumeration.\n"); +@@ -3752,11 +3788,21 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + return D3D_OK; + } + ++static void clear_device_desc(D3DDEVICEDESC *device_desc) ++{ ++ memset(device_desc, 0, sizeof(*device_desc)); ++ device_desc->dwSize = sizeof(*device_desc); ++ device_desc->dtcTransformCaps.dwSize = sizeof(device_desc->dtcTransformCaps); ++ device_desc->dlcLightingCaps.dwSize = sizeof(device_desc->dlcLightingCaps); ++ device_desc->dpcLineCaps.dwSize = sizeof(device_desc->dpcLineCaps); ++ device_desc->dpcTriCaps.dwSize = sizeof(device_desc->dpcTriCaps); ++} ++ + /***************************************************************************** + * IDirect3D3::EnumDevices + * +- * Enumerates all supported Direct3DDevice interfaces. This is the +- * implementation for Direct3D 1 to Direc3D 3, Version 7 has its own. ++ * Enumerates all Direct3DDevice interfaces. This is the implementation for ++ * Direct3D 1 to Direct3D 3; Version 7 has its own. + * + * Versions 1, 2 and 3 + * +@@ -3771,18 +3817,18 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + *****************************************************************************/ + static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBACK callback, void *context) + { +- static CHAR wined3d_description[] = "Wine D3DDevice using WineD3D and OpenGL"; +- ++/* Size of D3DDEVICEDESC in Direct3D 1-3 */ ++enum { ++ D3D1_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth), /* 172 */ ++ D3D2_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat), /* 204 */ ++ D3D3_DESC_SIZE = sizeof(D3DDEVICEDESC) /* 252 */ ++}; + struct ddraw *ddraw = impl_from_IDirect3D3(iface); +- D3DDEVICEDESC device_desc1, hal_desc, hel_desc; ++ DWORD desc_size; ++ D3DDEVICEDESC device_desc1, empty_desc1, hal_desc, hel_desc; + D3DDEVICEDESC7 device_desc7; + HRESULT hr; +- +- /* Some games (Motoracer 2 demo) have the bad idea to modify the device +- * name string. Let's put the string in a sufficiently sized array in +- * writable memory. */ +- char device_name[50]; +- strcpy(device_name,"Direct3D HEL"); ++ size_t i; + + TRACE("iface %p, callback %p, context %p.\n", iface, callback, context); + +@@ -3791,52 +3837,58 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA + + wined3d_mutex_lock(); + ++ switch (ddraw->d3dversion) ++ { ++ case 1: desc_size = D3D1_DESC_SIZE; break; ++ case 2: desc_size = D3D2_DESC_SIZE; break; ++ default: desc_size = D3D3_DESC_SIZE; break; ++ } ++ + if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &device_desc7))) + { + wined3d_mutex_unlock(); + return hr; + } ++ + ddraw_d3dcaps1_from_7(&device_desc1, &device_desc7); ++ device_desc1.dwSize = desc_size; + +- /* Do I have to enumerate the reference id? Note from old d3d7: +- * "It seems that enumerating the reference IID on Direct3D 1 games +- * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1 +- * +- * There's a registry key HKLM\Software\Microsoft\Direct3D\Drivers, +- * EnumReference which enables / disables enumerating the reference +- * rasterizer. It's a DWORD, 0 means disabled, 2 means enabled. The +- * enablerefrast.reg and disablerefrast.reg files in the DirectX 7.0 sdk +- * demo directory suggest this. +- * +- * Some games(GTA 2) seem to use the second enumerated device, so I have +- * to enumerate at least 2 devices. So enumerate the reference device to +- * have 2 devices. +- * +- * Other games (Rollcage) tell emulation and hal device apart by certain +- * flags. Rollcage expects D3DPTEXTURECAPS_POW2 to be set (yeah, it is a +- * limitation flag), and it refuses all devices that have the perspective +- * flag set. This way it refuses the emulation device, and HAL devices +- * never have POW2 unset in d3d7 on windows. */ +- if (ddraw->d3dversion != 1) +- { +- static CHAR reference_description[] = "RGB Direct3D emulation"; +- +- TRACE("Enumerating WineD3D D3DDevice interface.\n"); +- hal_desc = device_desc1; +- hel_desc = device_desc1; +- /* The rgb device has the pow2 flag set in the hel caps, but not in the hal caps. */ +- hal_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- hal_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- /* RGB, RAMP and MMX devices have a HAL dcmColorModel of 0 */ +- hal_desc.dcmColorModel = 0; +- /* RGB, RAMP and MMX devices cannot report HAL hardware flags */ +- hal_desc.dwFlags = 0; +- +- hr = callback((GUID *)&IID_IDirect3DRGBDevice, reference_description, +- device_name, &hal_desc, &hel_desc, context); +- if (hr != D3DENUMRET_OK) ++ clear_device_desc(&empty_desc1); ++ empty_desc1.dwSize = desc_size; ++ ++ for (i = 0; i < ARRAY_SIZE(device_list); i++) ++ { ++ if (!(device_list[i].version_mask & D3D_VERSION(ddraw->d3dversion))) ++ continue; ++ ++ if (IsEqualGUID(&IID_IDirect3DHALDevice, device_list[i].device_guid)) ++ { ++ hal_desc = device_desc1; ++ ++ /* The HAL device's hel_desc is almost empty -- but not completely */ ++ hel_desc = empty_desc1; ++ hel_desc.dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS ++ | D3DDD_LIGHTINGCAPS | D3DDD_BCLIPPING; ++ hel_desc.dcmColorModel = 0; ++ hel_desc.dwDevCaps = D3DDEVCAPS_FLOATTLVERTEX; ++ hel_desc.dtcTransformCaps.dwCaps = hal_desc.dtcTransformCaps.dwCaps; ++ hel_desc.dlcLightingCaps = hal_desc.dlcLightingCaps; ++ hel_desc.bClipping = hal_desc.bClipping; ++ hel_desc.dwMaxVertexCount = hal_desc.dwMaxVertexCount; ++ } ++ else ++ { ++ hal_desc = empty_desc1; ++ ++ hel_desc = device_desc1; ++ /* Ramp device supports grayscale only */ ++ if (IsEqualGUID(&IID_IDirect3DRampDevice, device_list[i].device_guid)) ++ hel_desc.dcmColorModel = D3DCOLOR_MONO; ++ } ++ ++ hr = callback((GUID *)device_list[i].device_guid, device_list[i].device_desc, ++ device_list[i].device_name, &hal_desc, &hel_desc, context); ++ if (hr != DDENUMRET_OK) + { + TRACE("Application cancelled the enumeration.\n"); + wined3d_mutex_unlock(); +@@ -3844,29 +3896,6 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA + } + } + +- strcpy(device_name,"Direct3D HAL"); +- +- TRACE("Enumerating HAL Direct3D device.\n"); +- hal_desc = device_desc1; +- hel_desc = device_desc1; +- +- /* The hal device does not have the pow2 flag set in hel, but in hal. */ +- hel_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- hel_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- /* HAL devices have a HEL dcmColorModel of 0 */ +- hel_desc.dcmColorModel = 0; +- +- hr = callback((GUID *)&IID_IDirect3DHALDevice, wined3d_description, +- device_name, &hal_desc, &hel_desc, context); +- if (hr != D3DENUMRET_OK) +- { +- TRACE("Application cancelled the enumeration.\n"); +- wined3d_mutex_unlock(); +- return D3D_OK; +- } +- + TRACE("End of enumeration.\n"); + + wined3d_mutex_unlock(); diff --git a/sdk/tools/winesync/wined3d.cfg b/sdk/tools/winesync/wined3d.cfg new file mode 100644 index 00000000000..079439cb886 --- /dev/null +++ b/sdk/tools/winesync/wined3d.cfg @@ -0,0 +1,6 @@ +directories: + dlls/wined3d: dll/directx/wine/wined3d +files: + include/wine/wined3d.h: sdk/include/reactos/wine/wined3d.h +tags: + wine: wine-4.18 diff --git a/sdk/tools/winesync/wined3d_staging/0001-nvapi__Implement_NvAPI_D3D11_SetDepthBoundsTest._(v2).diff b/sdk/tools/winesync/wined3d_staging/0001-nvapi__Implement_NvAPI_D3D11_SetDepthBoundsTest._(v2).diff new file mode 100644 index 00000000000..b8afead5113 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0001-nvapi__Implement_NvAPI_D3D11_SetDepthBoundsTest._(v2).diff @@ -0,0 +1,13 @@ +diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h +index 445ecd2..98f83dc 100644 +--- a/sdk/include/reactos/wine/wined3d.h ++++ b/sdk/include/reactos/wine/wined3d.h +@@ -28,6 +28,8 @@ + + #include "wine/list.h" + ++DEFINE_GUID(IID_IWineD3DDevice, 0xd56e2a4c, 0x5127, 0x8437, 0x65, 0x8a, 0x98, 0xc5, 0xbb, 0x78, 0x94, 0x98); ++ + #define WINED3D_OK S_OK + + #define _FACWINED3D 0x876 diff --git a/sdk/tools/winesync/wined3d_staging/0002-wined3d__Add_wined3d_resource_map_info_function.diff b/sdk/tools/winesync/wined3d_staging/0002-wined3d__Add_wined3d_resource_map_info_function.diff new file mode 100644 index 00000000000..0b57078e4d4 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0002-wined3d__Add_wined3d_resource_map_info_function.diff @@ -0,0 +1,157 @@ +diff --git a/dll/directx/wine/wined3d/buffer.c b/dll/directx/wine/wined3d/buffer.c +index 95fcdff..c52b627 100644 +--- a/dll/directx/wine/wined3d/buffer.c ++++ b/dll/directx/wine/wined3d/buffer.c +@@ -1108,6 +1108,24 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc + return WINED3D_OK; + } + ++static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ struct wined3d_map_info *info, DWORD flags) ++{ ++ struct wined3d_buffer *buffer = buffer_from_resource(resource); ++ ++ if (sub_resource_idx) ++ { ++ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); ++ return E_INVALIDARG; ++ } ++ ++ info->row_pitch = resource->size; ++ info->slice_pitch = resource->size; ++ info->size = buffer->resource.size; ++ ++ return WINED3D_OK; ++} ++ + static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) + { + struct wined3d_buffer *buffer = buffer_from_resource(resource); +@@ -1266,6 +1284,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = + buffer_resource_preload, + buffer_unload, + buffer_resource_sub_resource_map, ++ buffer_resource_sub_resource_map_info, + buffer_resource_sub_resource_unmap, + }; + +diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c +index bba940f..ff31c00 100644 +--- a/dll/directx/wine/wined3d/resource.c ++++ b/dll/directx/wine/wined3d/resource.c +@@ -383,6 +383,14 @@ HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned i + return wined3d_cs_map(resource->device->cs, resource, sub_resource_idx, map_desc, box, flags); + } + ++HRESULT CDECL wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ struct wined3d_map_info *info, DWORD flags) ++{ ++ TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); ++ ++ return resource->resource_ops->resource_map_info(resource, sub_resource_idx, info, flags); ++} ++ + HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) + { + TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); +diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c +index 17b71c5..a74f692 100644 +--- a/dll/directx/wine/wined3d/texture.c ++++ b/dll/directx/wine/wined3d/texture.c +@@ -3052,6 +3052,36 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour + return WINED3D_OK; + } + ++static HRESULT texture_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ struct wined3d_map_info *info, DWORD flags) ++{ ++ const struct wined3d_format *format = resource->format; ++ struct wined3d_texture_sub_resource *sub_resource; ++ unsigned int fmt_flags = resource->format_flags; ++ struct wined3d_texture *texture; ++ unsigned int texture_level; ++ ++ texture = texture_from_resource(resource); ++ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) ++ return E_INVALIDARG; ++ ++ texture_level = sub_resource_idx % texture->level_count; ++ ++ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) ++ { ++ info->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count; ++ info->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * info->row_pitch; ++ } ++ else ++ { ++ wined3d_texture_get_pitch(texture, texture_level, &info->row_pitch, &info->slice_pitch); ++ } ++ ++ info->size = info->slice_pitch * wined3d_texture_get_level_depth(texture, texture_level); ++ ++ return WINED3D_OK; ++} ++ + static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) + { + struct wined3d_texture_sub_resource *sub_resource; +@@ -3104,6 +3134,7 @@ static const struct wined3d_resource_ops texture_resource_ops = + texture_resource_preload, + wined3d_texture_gl_unload, + texture_resource_sub_resource_map, ++ texture_resource_sub_resource_map_info, + texture_resource_sub_resource_unmap, + }; + +diff --git a/dll/directx/wine/wined3d/wined3d.spec b/dll/directx/wine/wined3d/wined3d.spec +index c7b10a2..119899e 100644 +--- a/dll/directx/wine/wined3d/wined3d.spec ++++ b/dll/directx/wine/wined3d/wined3d.spec +@@ -216,6 +216,7 @@ + @ cdecl wined3d_resource_get_parent(ptr) + @ cdecl wined3d_resource_get_priority(ptr) + @ cdecl wined3d_resource_map(ptr long ptr ptr long) ++@ cdecl wined3d_resource_map_info(ptr long ptr long) + @ cdecl wined3d_resource_preload(ptr) + @ cdecl wined3d_resource_set_parent(ptr ptr) + @ cdecl wined3d_resource_set_priority(ptr long) +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 307f7a4..b67ac6a 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -3415,6 +3415,8 @@ struct wined3d_resource_ops + void (*resource_unload)(struct wined3d_resource *resource); + HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); ++ HRESULT (*resource_map_info)(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ struct wined3d_map_info *info, DWORD flags); + HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx); + }; + +diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h +index 98f83dc..94ff746 100644 +--- a/sdk/include/reactos/wine/wined3d.h ++++ b/sdk/include/reactos/wine/wined3d.h +@@ -1836,6 +1836,13 @@ struct wined3d_map_desc + void *data; + }; + ++struct wined3d_map_info ++{ ++ UINT row_pitch; ++ UINT slice_pitch; ++ UINT size; ++}; ++ + struct wined3d_sub_resource_data + { + const void *data; +@@ -2603,6 +2610,8 @@ void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resour + DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource); + HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); ++HRESULT __cdecl wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ struct wined3d_map_info *info, DWORD flags); + void __cdecl wined3d_resource_preload(struct wined3d_resource *resource); + void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); + DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority); diff --git a/sdk/tools/winesync/wined3d_staging/0003-d3d11__Implement_d3d11_deferred_context_UpdateSubresource.diff b/sdk/tools/winesync/wined3d_staging/0003-d3d11__Implement_d3d11_deferred_context_UpdateSubresource.diff new file mode 100644 index 00000000000..90fd1bf9113 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0003-d3d11__Implement_d3d11_deferred_context_UpdateSubresource.diff @@ -0,0 +1,129 @@ +diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c +index ff31c00..5b2e624 100644 +--- a/dll/directx/wine/wined3d/resource.c ++++ b/dll/directx/wine/wined3d/resource.c +@@ -398,6 +398,99 @@ HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned + return wined3d_cs_unmap(resource->device->cs, resource, sub_resource_idx); + } + ++UINT CDECL wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch) ++{ ++ unsigned int width, height, depth; ++ struct wined3d_box b; ++ UINT data_size; ++ ++ TRACE("resource %p, sub_resource_idx %u, box %s, row_pitch %u, depth_pitch %u.\n", ++ resource, sub_resource_idx, debug_box(box), row_pitch, depth_pitch); ++ ++ if (resource->type == WINED3D_RTYPE_BUFFER) ++ { ++ if (sub_resource_idx > 0) ++ { ++ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); ++ return 0; ++ } ++ ++ width = resource->size; ++ height = 1; ++ depth = 1; ++ } ++ else if (resource->type == WINED3D_RTYPE_TEXTURE_1D || ++ resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D) ++ { ++ struct wined3d_texture *texture = texture_from_resource(resource); ++ unsigned int level; ++ ++ if (sub_resource_idx >= texture->level_count * texture->layer_count) ++ { ++ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); ++ return 0; ++ } ++ ++ level = sub_resource_idx % texture->level_count; ++ width = wined3d_texture_get_level_width(texture, level); ++ height = wined3d_texture_get_level_height(texture, level); ++ depth = wined3d_texture_get_level_depth(texture, level); ++ } ++ else ++ { ++ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); ++ return 0; ++ } ++ ++ if (!box) ++ { ++ wined3d_box_set(&b, 0, 0, width, height, 0, depth); ++ box = &b; ++ } ++ else if (box->left >= box->right || box->right > width ++ || box->top >= box->bottom || box->bottom > height ++ || box->front >= box->back || box->back > depth) ++ { ++ WARN("Invalid box %s specified.\n", debug_box(box)); ++ return 0; ++ } ++ ++ if (resource->format_flags & WINED3DFMT_FLAG_BLOCKS) ++ { ++ if (resource->type != WINED3D_RTYPE_TEXTURE_2D) ++ { ++ FIXME("Calculation of block formats not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); ++ return 0; ++ } ++ ++ height = (box->bottom - box->top + resource->format->block_height - 1) / resource->format->block_height; ++ width = (box->right - box->left + resource->format->block_width - 1) / resource->format->block_width; ++ return (height - 1) * row_pitch + width * resource->format->block_byte_count; ++ } ++ ++ data_size = 0; ++ switch (resource->type) ++ { ++ case WINED3D_RTYPE_TEXTURE_3D: ++ data_size += (box->back - box->front - 1) * depth_pitch; ++ /* fall-through */ ++ case WINED3D_RTYPE_TEXTURE_2D: ++ data_size += (box->bottom - box->top - 1) * row_pitch; ++ /* fall-through */ ++ case WINED3D_RTYPE_TEXTURE_1D: ++ data_size += (box->right - box->left) * resource->format->byte_count; ++ break; ++ case WINED3D_RTYPE_BUFFER: ++ data_size = box->right - box->left; ++ break; ++ case WINED3D_RTYPE_NONE: ++ break; ++ } ++ ++ return data_size; ++} ++ + void CDECL wined3d_resource_preload(struct wined3d_resource *resource) + { + wined3d_cs_emit_preload_resource(resource->device->cs, resource); +diff --git a/dll/directx/wine/wined3d/wined3d.spec b/dll/directx/wine/wined3d/wined3d.spec +index 119899e..fe3f49a 100644 +--- a/dll/directx/wine/wined3d/wined3d.spec ++++ b/dll/directx/wine/wined3d/wined3d.spec +@@ -221,6 +221,7 @@ + @ cdecl wined3d_resource_set_parent(ptr ptr) + @ cdecl wined3d_resource_set_priority(ptr long) + @ cdecl wined3d_resource_unmap(ptr long) ++@ cdecl wined3d_resource_update_info(ptr long ptr long long) + + @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr) + @ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr) +diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h +index 94ff746..baa7089 100644 +--- a/sdk/include/reactos/wine/wined3d.h ++++ b/sdk/include/reactos/wine/wined3d.h +@@ -2616,6 +2616,8 @@ void __cdecl wined3d_resource_preload(struct wined3d_resource *resource); + void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); + DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority); + HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); ++UINT __cdecl wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch); + + HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, diff --git a/sdk/tools/winesync/wined3d_staging/0004-wined3d__Use_real_values_for_memory_accounting_on_NVIDIA_cards.diff b/sdk/tools/winesync/wined3d_staging/0004-wined3d__Use_real_values_for_memory_accounting_on_NVIDIA_cards.diff new file mode 100644 index 00000000000..f55eb2b6ecf --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0004-wined3d__Use_real_values_for_memory_accounting_on_NVIDIA_cards.diff @@ -0,0 +1,76 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index ed10220..afd6a40 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -228,6 +228,7 @@ static const struct wined3d_extension_map gl_extension_map[] = + {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 }, + {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION }, + {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 }, ++ {"GL_NVX_gpu_memory_info", NVX_GPU_MEMORY_INFO }, + }; + + static const struct wined3d_extension_map wgl_extension_map[] = +@@ -1059,6 +1060,17 @@ static const struct wined3d_gpu_description *query_gpu_description(const struct + + gpu_description = wined3d_get_gpu_description(vendor, device); + } ++ else if (gl_info->supported[NVX_GPU_MEMORY_INFO]) ++ { ++ GLint vram_kb; ++ gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb); ++ ++ *vram_bytes = (UINT64)vram_kb * 1024; ++ TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n", ++ wine_dbgstr_longlong(*vram_bytes)); ++ ++ gpu_description = wined3d_get_gpu_description(vendor, device); ++ } + + if ((gpu_description_override = wined3d_get_user_override_gpu_description(vendor, device))) + gpu_description = gpu_description_override; +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 0a668c4..8bba545 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -1200,6 +1200,29 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device + + driver_info = &device->adapter->driver_info; + ++ /* We can not acquire the context unless there is a swapchain. */ ++ /* ++ if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO] && ++ !wined3d_settings.emulated_textureram) ++ { ++ GLint vram_free_kb; ++ UINT64 vram_free; ++ ++ struct wined3d_context *context = context_acquire(device, NULL, 0); ++ gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &vram_free_kb); ++ vram_free = (UINT64)vram_free_kb * 1024; ++ context_release(context); ++ ++ TRACE("Total 0x%s bytes. emulation 0x%s left, driver 0x%s left.\n", ++ wine_dbgstr_longlong(device->adapter->vram_bytes), ++ wine_dbgstr_longlong(device->adapter->vram_bytes - device->adapter->vram_bytes_used), ++ wine_dbgstr_longlong(vram_free)); ++ ++ vram_free = min(vram_free, device->adapter->vram_bytes - device->adapter->vram_bytes_used); ++ return min(UINT_MAX, vram_free); ++ } ++ */ ++ + TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n", + wine_dbgstr_longlong(driver_info->vram_bytes), + wine_dbgstr_longlong(device->adapter->vram_bytes_used), +diff --git a/dll/directx/wine/wined3d/wined3d_gl.h b/dll/directx/wine/wined3d/wined3d_gl.h +index 678ad1a..52eeeb0 100644 +--- a/dll/directx/wine/wined3d/wined3d_gl.h ++++ b/dll/directx/wine/wined3d/wined3d_gl.h +@@ -204,6 +204,7 @@ enum wined3d_gl_extension + NV_VERTEX_PROGRAM2, + NV_VERTEX_PROGRAM2_OPTION, + NV_VERTEX_PROGRAM3, ++ NVX_GPU_MEMORY_INFO, + /* WGL extensions */ + WGL_ARB_PIXEL_FORMAT, + WGL_EXT_SWAP_CONTROL, diff --git a/sdk/tools/winesync/wined3d_staging/0005-wined3d__Improve_wined3d_cs_emit_update_sub_resource.diff b/sdk/tools/winesync/wined3d_staging/0005-wined3d__Improve_wined3d_cs_emit_update_sub_resource.diff new file mode 100644 index 00000000000..0c1c91fe783 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0005-wined3d__Improve_wined3d_cs_emit_update_sub_resource.diff @@ -0,0 +1,160 @@ +diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c +index ec17b59..fc5d722 100644 +--- a/dll/directx/wine/wined3d/cs.c ++++ b/dll/directx/wine/wined3d/cs.c +@@ -409,6 +409,7 @@ struct wined3d_cs_update_sub_resource + unsigned int sub_resource_idx; + struct wined3d_box box; + struct wined3d_sub_resource_data data; ++ BYTE copy_data[1]; + }; + + struct wined3d_cs_add_dirty_texture_region +@@ -2363,6 +2364,51 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r + unsigned int slice_pitch) + { + struct wined3d_cs_update_sub_resource *op; ++ size_t data_size, size; ++ ++ if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags & WINED3DFMT_FLAG_BLOCKS) ++ goto no_async; ++ ++ data_size = 0; ++ switch (resource->type) ++ { ++ case WINED3D_RTYPE_TEXTURE_3D: ++ data_size += (box->back - box->front - 1) * slice_pitch; ++ /* fall-through */ ++ case WINED3D_RTYPE_TEXTURE_2D: ++ data_size += (box->bottom - box->top - 1) * row_pitch; ++ /* fall-through */ ++ case WINED3D_RTYPE_TEXTURE_1D: ++ data_size += (box->right - box->left) * resource->format->byte_count; ++ break; ++ case WINED3D_RTYPE_BUFFER: ++ data_size = box->right - box->left; ++ break; ++ case WINED3D_RTYPE_NONE: ++ return; ++ } ++ ++ size = FIELD_OFFSET(struct wined3d_cs_update_sub_resource, copy_data[data_size]); ++ if (!cs->ops->check_space(cs, size, WINED3D_CS_QUEUE_DEFAULT)) ++ goto no_async; ++ ++ op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT); ++ op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; ++ op->resource = resource; ++ op->sub_resource_idx = sub_resource_idx; ++ op->box = *box; ++ op->data.row_pitch = row_pitch; ++ op->data.slice_pitch = slice_pitch; ++ op->data.data = op->copy_data; ++ memcpy(op->copy_data, data, data_size); ++ ++ wined3d_resource_acquire(resource); ++ ++ cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); ++ return; ++ ++no_async: ++ wined3d_resource_wait_idle(resource); + + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; +@@ -2376,6 +2422,7 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r + wined3d_resource_acquire(resource); + + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_MAP); ++ + /* The data pointer may go away, so we need to wait until it is read. + * Copying the data may be faster if it's small. */ + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_MAP); +@@ -2558,6 +2605,11 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps, + }; + ++static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) ++{ ++ return TRUE; ++} ++ + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) + { + if (size > (cs->data_size - cs->end)) +@@ -2611,6 +2663,7 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id + + static const struct wined3d_cs_ops wined3d_cs_st_ops = + { ++ wined3d_cs_st_check_space, + wined3d_cs_st_require_space, + wined3d_cs_st_submit, + wined3d_cs_st_finish, +@@ -2644,6 +2697,19 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id + wined3d_cs_queue_submit(&cs->queue[queue_id], cs); + } + ++static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t size) ++{ ++ size_t queue_size = ARRAY_SIZE(queue->data); ++ size_t header_size, packet_size, remaining; ++ ++ header_size = FIELD_OFFSET(struct wined3d_cs_packet, data[0]); ++ size = (size + header_size - 1) & ~(header_size - 1); ++ packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[size]); ++ ++ remaining = queue_size - queue->head; ++ return (remaining >= packet_size); ++} ++ + static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs) + { + size_t queue_size = ARRAY_SIZE(queue->data); +@@ -2705,6 +2771,14 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size + return packet->data; + } + ++static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) ++{ ++ if (cs->thread_id == GetCurrentThreadId()) ++ return wined3d_cs_st_check_space(cs, size, queue_id); ++ ++ return wined3d_cs_queue_check_space(&cs->queue[queue_id], size); ++} ++ + static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) + { + if (cs->thread_id == GetCurrentThreadId()) +@@ -2724,6 +2798,7 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id + + static const struct wined3d_cs_ops wined3d_cs_mt_ops = + { ++ wined3d_cs_mt_check_space, + wined3d_cs_mt_require_space, + wined3d_cs_mt_submit, + wined3d_cs_mt_finish, +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 8bba545..90d04e6 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4870,8 +4870,6 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str + return; + } + +- wined3d_resource_wait_idle(resource); +- + wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); + } + +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index b67ac6a..0efff6d 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -4012,6 +4012,7 @@ struct wined3d_cs_queue + + struct wined3d_cs_ops + { ++ BOOL (*check_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id); + void *(*require_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id); + void (*submit)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id); + void (*finish)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id); diff --git a/sdk/tools/winesync/wined3d_staging/0006-wined3d__Implement_dual_source_blending.diff b/sdk/tools/winesync/wined3d_staging/0006-wined3d__Implement_dual_source_blending.diff new file mode 100644 index 00000000000..39cbbc70994 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0006-wined3d__Implement_dual_source_blending.diff @@ -0,0 +1,236 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index afd6a40..1fb325b 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -2981,6 +2981,12 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) + gl_info->limits.buffers = min(MAX_RENDER_TARGET_VIEWS, gl_max); + TRACE("Max draw buffers: %u.\n", gl_max); + } ++ if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) ++ { ++ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &gl_max); ++ gl_info->limits.dual_buffers = gl_max; ++ TRACE("Max dual source draw buffers: %u.\n", gl_max); ++ } + if (gl_info->supported[ARB_MULTITEXTURE]) + { + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) +@@ -5150,6 +5156,7 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ + struct fragment_caps fragment_caps; + struct shader_caps shader_caps; + GLfloat f[2]; ++ int i; + + adapter_gl->a.shader_backend->shader_get_caps(&adapter_gl->a, &shader_caps); + adapter_gl->a.vertex_pipe->vp_get_caps(&adapter_gl->a, &vertex_caps); +@@ -5170,6 +5177,10 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ + d3d_info->limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; + d3d_info->limits.active_light_count = vertex_caps.max_active_lights; + ++ d3d_info->valid_dual_rt_mask = 0; ++ for (i = 0; i < gl_info->limits.dual_buffers; ++i) ++ d3d_info->valid_dual_rt_mask |= (1u << i); ++ + d3d_info->limits.max_rt_count = gl_info->limits.buffers; + d3d_info->limits.max_clip_distances = gl_info->limits.user_clip_distances; + d3d_info->limits.texture_size = gl_info->limits.texture_size; +diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c +index 9cd6a6e..9001d60 100644 +--- a/dll/directx/wine/wined3d/context.c ++++ b/dll/directx/wine/wined3d/context.c +@@ -3142,10 +3142,23 @@ static uint32_t find_draw_buffers_mask(const struct wined3d_context_gl *context_ + else if (!context_gl->c.render_offscreen) + return context_generate_rt_mask_from_resource(rts[0]->resource); + ++ /* If we attach more buffers than supported in dual blend mode, the NVIDIA ++ * driver generates the following error: ++ * GL_INVALID_OPERATION error generated. State(s) are invalid: blend. ++ * DX11 does not treat this configuration as invalid, so disable the unused ones. ++ */ + rt_mask = ps ? ps->reg_maps.rt_mask : 1; +- rt_mask &= (1u << gl_info->limits.buffers) - 1; ++ ++ if (wined3d_dualblend_enabled(state, gl_info) && ps) ++ { ++ const struct wined3d_d3d_info *d3d_info = &ps->device->adapter->d3d_info; ++ rt_mask &= d3d_info->valid_dual_rt_mask; ++ } ++ else ++ rt_mask &= (1u << gl_info->limits.buffers) - 1; + + mask = rt_mask; ++ i = 0; + while (mask) + { + i = wined3d_bit_scan(&mask); +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 0e0977e..d45c131 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -2820,6 +2820,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * + break; + + case WINED3DSPR_COLOROUT: ++ /* FIXME: should check dual_buffers when dual blending is enabled */ + if (reg->idx[0].offset >= gl_info->limits.buffers) + WARN("Write to render target %u, only %d supported.\n", + reg->idx[0].offset, gl_info->limits.buffers); +@@ -7735,7 +7736,10 @@ static GLuint shader_glsl_generate_fragment_shader(const struct wined3d_context_ + { + const struct wined3d_shader_signature *output_signature = &shader->output_signature; + +- shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.buffers); ++ if (args->dual_source_blend) ++ shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.dual_buffers * 2); ++ else ++ shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.buffers); + if (output_signature->element_count) + { + for (i = 0; i < output_signature->element_count; ++i) +@@ -7750,7 +7754,12 @@ static GLuint shader_glsl_generate_fragment_shader(const struct wined3d_context_ + continue; + } + if (shader_glsl_use_explicit_attrib_location(gl_info)) +- shader_addline(buffer, "layout(location = %u) ", output->semantic_idx); ++ { ++ if (args->dual_source_blend) ++ shader_addline(buffer, "layout(location = %u, index = %u) ", output->semantic_idx / 2, output->semantic_idx % 2); ++ else ++ shader_addline(buffer, "layout(location = %u) ", output->semantic_idx); ++ } + shader_addline(buffer, "out %s4 color_out%u;\n", + component_type_info[output->component_type].glsl_vector_type, output->semantic_idx); + } +@@ -7763,7 +7772,12 @@ static GLuint shader_glsl_generate_fragment_shader(const struct wined3d_context_ + { + i = wined3d_bit_scan(&mask); + if (shader_glsl_use_explicit_attrib_location(gl_info)) +- shader_addline(buffer, "layout(location = %u) ", i); ++ { ++ if (args->dual_source_blend) ++ shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2); ++ else ++ shader_addline(buffer, "layout(location = %u) ", i); ++ } + shader_addline(buffer, "out vec4 color_out%u;\n", i); + } + } +diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c +index 3b9a96a..5c96d3b 100644 +--- a/dll/directx/wine/wined3d/shader.c ++++ b/dll/directx/wine/wined3d/shader.c +@@ -4168,6 +4168,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 + if (rtv && rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup)) + args->rt_alpha_swizzle |= 1u << i; + } ++ ++ args->dual_source_blend = wined3d_dualblend_enabled(state, gl_info); + } + + static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, +diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c +index 4bc371b..2f90fd5 100644 +--- a/dll/directx/wine/wined3d/state.c ++++ b/dll/directx/wine/wined3d/state.c +@@ -533,12 +533,14 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st + const struct wined3d_format *rt_format; + GLenum src_blend, dst_blend; + unsigned int rt_fmt_flags; ++ BOOL enable_dual_blend; + BOOL enable_blend; + + enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE]; +- if (enable_blend) ++ enable_dual_blend = wined3d_dualblend_enabled(state, gl_info); ++ ++ if (enable_blend && !enable_dual_blend) + { +- rt_format = state->fb->render_targets[0]->format; + rt_fmt_flags = state->fb->render_targets[0]->format_flags; + + /* Disable blending in all cases even without pixelshaders. +@@ -548,6 +550,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st + enable_blend = FALSE; + } + ++ /* Dual state blending changes the assignment of the output variables */ ++ if (context->last_was_dual_blend != enable_dual_blend) ++ { ++ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; ++ context->last_was_dual_blend = enable_dual_blend; ++ } ++ + if (!enable_blend) + { + gl_info->gl_ops.gl.p_glDisable(GL_BLEND); +@@ -558,6 +567,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st + gl_info->gl_ops.gl.p_glEnable(GL_BLEND); + checkGLcall("glEnable(GL_BLEND)"); + ++ rt_format = state->fb->render_targets[0]->format; + gl_blend_from_d3d(&src_blend, &dst_blend, + state->render_states[WINED3D_RS_SRCBLEND], + state->render_states[WINED3D_RS_DESTBLEND], rt_format); +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 0efff6d..361a594 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -199,6 +199,7 @@ struct wined3d_d3d_info + { + struct wined3d_d3d_limits limits; + struct wined3d_ffp_attrib_ops ffp_attrib_ops; ++ DWORD valid_dual_rt_mask; + uint32_t wined3d_creation_flags; + uint32_t xyzrhw : 1; + uint32_t emulated_flatshading : 1; +@@ -1397,7 +1398,8 @@ struct ps_compile_args + DWORD alpha_test_func : 3; + DWORD render_offscreen : 1; + DWORD rt_alpha_swizzle : 8; /* MAX_RENDER_TARGET_VIEWS, 8 */ +- DWORD padding : 18; ++ DWORD dual_source_blend : 1; ++ DWORD padding : 17; + }; + + enum fog_src_type +@@ -1969,7 +1971,8 @@ struct wined3d_context + DWORD destroyed : 1; + DWORD destroy_delayed : 1; + DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */ +- DWORD padding : 15; ++ DWORD last_was_dual_blend : 1; ++ DWORD padding : 14; + + DWORD constant_update_mask; + DWORD numbered_array_mask; +@@ -2681,6 +2684,7 @@ struct wined3d_fbo_ops + struct wined3d_gl_limits + { + UINT buffers; ++ UINT dual_buffers; + UINT lights; + UINT textures; + UINT texture_coords; +@@ -3185,6 +3189,22 @@ struct wined3d_state + struct wined3d_rasterizer_state *rasterizer_state; + }; + ++static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, const struct wined3d_gl_info *gl_info) ++{ ++ if (!state->fb->render_targets[0]) return FALSE; ++ if (!state->render_states[WINED3D_RS_ALPHABLENDENABLE]) return FALSE; ++ if (!gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) return FALSE; ++ ++#define IS_DUAL_SOURCE_BLEND(x) ((x) >= WINED3D_BLEND_SRC1COLOR && (x) <= WINED3D_BLEND_INVSRC1ALPHA) ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLEND])) return TRUE; ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLEND])) return TRUE; ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLENDALPHA])) return TRUE; ++ if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLENDALPHA])) return TRUE; ++#undef IS_DUAL_SOURCE_BLEND ++ ++ return FALSE; ++} ++ + struct wined3d_dummy_textures + { + GLuint tex_1d; diff --git a/sdk/tools/winesync/wined3d_staging/0007-wined3d__Use_UBO_for_vertex_shader_float_constants_if_supported.diff b/sdk/tools/winesync/wined3d_staging/0007-wined3d__Use_UBO_for_vertex_shader_float_constants_if_supported.diff new file mode 100644 index 00000000000..3f69b67208c --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0007-wined3d__Use_UBO_for_vertex_shader_float_constants_if_supported.diff @@ -0,0 +1,359 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index 1fb325b..6da0e20 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -3135,6 +3135,9 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max vertex uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX], gl_max); ++ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gl_max); ++ gl_info->limits.glsl_max_uniform_block_size = gl_max; ++ TRACE("Max uniform block size %u.\n", gl_max); + } + } + if (gl_info->supported[ARB_TESSELLATION_SHADER]) +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index d45c131..039bec0 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -138,6 +138,10 @@ struct shader_glsl_priv + unsigned char *stack; + UINT next_constant_version; + ++ BOOL consts_ubo; ++ GLuint ubo_vs_c; ++ struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F]; ++ + const struct wined3d_vertex_pipe_ops *vertex_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; + struct wine_rb_tree ffp_vertex_shaders; +@@ -189,6 +193,7 @@ struct glsl_vs_program + GLint pointsize_l_att_location; + GLint pointsize_q_att_location; + GLint clip_planes_location; ++ GLint vs_c_block_index; + }; + + struct glsl_hs_program +@@ -284,6 +289,7 @@ struct glsl_context_data + struct glsl_shader_prog_link *glsl_program; + GLenum vertex_color_clamp; + BOOL rasterization_disabled; ++ BOOL ubo_bound; + }; + + struct glsl_ps_compiled_shader +@@ -1183,12 +1189,54 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i + checkGLcall("walk_constant_heap_clamped()"); + } + ++static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv) ++{ ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); ++ checkGLcall("glBindBuffer"); ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); ++} ++ + /* Context activation is done by the caller. */ + static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, + const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, +- unsigned char *stack, unsigned int version) ++ unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv) + { + const struct wined3d_shader_lconst *lconst; ++ BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX; ++ ++ if (is_vertex_shader && priv->consts_ubo) ++ { ++ const struct wined3d_vec4 *data; ++ unsigned max_const_used; ++ ++ if (priv->ubo_vs_c == -1) ++ { ++ ERR("UBO is not initialized.\n"); ++ return; ++ } ++ ++ bind_and_orphan_consts_ubo(gl_info, priv); ++ max_const_used = shader->reg_maps.usesrelconstF ++ ? WINED3D_MAX_VS_CONSTS_F : shader->reg_maps.constant_float_count; ++ if (shader->load_local_constsF) ++ { ++ data = priv->vs_c_buffer; ++ memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants)); ++ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) ++ { ++ priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; ++ } ++ } ++ else ++ { ++ data = constants; ++ } ++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) * max_const_used, data)); ++ checkGLcall("glBufferSubData"); ++ return; ++ } + + /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */ + if (shader->reg_maps.shader_version.major == 1 +@@ -1523,7 +1571,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + { + const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; + const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; +- const struct glsl_context_data *ctx_data = context->shader_backend_data; ++ struct glsl_context_data *ctx_data = context->shader_backend_data; + struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + struct glsl_shader_prog_link *prog = ctx_data->glsl_program; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; +@@ -1540,9 +1588,32 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + constant_version = prog->constant_version; + update_mask = context->constant_update_mask & prog->constant_update_mask; + ++ if (!ctx_data->ubo_bound) ++ { ++ unsigned int base, count; ++ ++ if (priv->consts_ubo) ++ { ++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++ &base, &count); ++ if (priv->ubo_vs_c == -1) ++ { ++ GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); ++ checkGLcall("glBindBuffer (UBO)"); ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); ++ } ++ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base, priv->ubo_vs_c)); ++ checkGLcall("glBindBufferBase"); ++ } ++ ctx_data->ubo_bound = TRUE; ++ } ++ + if (update_mask & WINED3D_SHADER_CONST_VS_F) + shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f, +- prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version); ++ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version, priv); + + if (update_mask & WINED3D_SHADER_CONST_VS_I) + shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i, +@@ -1695,7 +1766,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + + if (update_mask & WINED3D_SHADER_CONST_PS_F) + shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f, +- prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); ++ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, priv); + + if (update_mask & WINED3D_SHADER_CONST_PS_I) + shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i, +@@ -1834,6 +1905,12 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev + struct constant_heap *heap = &priv->vconst_heap; + UINT i; + ++ if (!(device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS)) ++ WARN("Called without legacy shader constant mode.\n"); ++ ++ if (priv->consts_ubo) ++ return; ++ + for (i = start; i < count + start; ++i) + { + update_heap_entry(heap, i, priv->next_constant_version); +@@ -1846,6 +1923,9 @@ static void shader_glsl_update_float_pixel_constants(struct wined3d_device *devi + struct constant_heap *heap = &priv->pconst_heap; + UINT i; + ++ if (!(device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS)) ++ WARN("Called without legacy shader constant mode.\n"); ++ + for (i = start; i < count + start; ++i) + { + update_heap_entry(heap, i, priv->next_constant_version); +@@ -2155,6 +2235,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c + const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) + { + const struct wined3d_shader_version *version = ®_maps->shader_version; ++ struct shader_glsl_priv *priv = context_gl->c.device->shader_priv; + const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; + const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; + const struct wined3d_gl_info *gl_info = context_gl->gl_info; +@@ -2178,7 +2259,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c + } + + /* Declare the constants (aka uniforms) */ +- if (shader->limits->constant_float > 0) ++ if (shader->limits->constant_float > 0 && priv->consts_ubo ++ && version->type == WINED3D_SHADER_TYPE_VERTEX) ++ { ++ shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n" ++ "{ \n" ++ " vec4 %s_c[%u];\n" ++ "};\n", prefix, min(shader->limits->constant_float, WINED3D_MAX_VS_CONSTS_F)); ++ } ++ else if (shader->limits->constant_float > 0) + { + unsigned max_constantsF; + +@@ -2243,11 +2332,12 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c + } + else + { +- max_constantsF = gl_info->limits.glsl_vs_float_constants; ++ max_constantsF = reg_maps->constant_float_count; + } + } + max_constantsF = min(shader->limits->constant_float, max_constantsF); +- shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF); ++ if (max_constantsF) ++ shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF); + } + + /* Always declare the full set of constants, the compiler can remove the +@@ -9862,17 +9952,36 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str + + + static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info, +- struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count) ++ struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, ++ unsigned int vs_c_count) + { + unsigned int i; + struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers); + +- for (i = 0; i < vs_c_count; ++i) ++ if (priv->consts_ubo && vs_c_count) + { +- string_buffer_sprintf(name, "vs_c[%u]", i); +- vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); ++ unsigned int base, count; ++ ++ vs->vs_c_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "vs_c_ubo")); ++ checkGLcall("glGetUniformBlockIndex"); ++ if (vs->vs_c_block_index == -1) ++ ERR("Could not get ubo_vs_c block index.\n"); ++ ++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++ &base, &count); ++ assert(count >= 1); ++ GL_EXTCALL(glUniformBlockBinding(program_id, vs->vs_c_block_index, base)); ++ checkGLcall("glUniformBlockBinding"); ++ } ++ else if (!priv->consts_ubo) ++ { ++ for (i = 0; i < vs_c_count; ++i) ++ { ++ string_buffer_sprintf(name, "vs_c[%u]", i); ++ vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); ++ } ++ memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); + } +- memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); + + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) + { +@@ -10947,6 +11056,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + const struct wined3d_fragment_pipe_ops *fragment_pipe) + { + SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct fragment_caps fragment_caps; + void *vertex_priv, *fragment_priv; + struct shader_glsl_priv *priv; +@@ -10954,6 +11064,8 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + if (!(priv = heap_alloc_zero(sizeof(*priv)))) + return E_OUTOFMEMORY; + ++ priv->consts_ubo = (device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS) ++ && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]; + string_buffer_list_init(&priv->string_buffers); + + if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv))) +@@ -11008,6 +11120,8 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + device->fragment_priv = fragment_priv; + device->shader_priv = priv; + ++ priv->ubo_vs_c = -1; ++ + return WINED3D_OK; + + fail: +@@ -11035,6 +11149,13 @@ static void shader_glsl_free(struct wined3d_device *device, struct wined3d_conte + priv->fragment_pipe->free_private(device, context); + priv->vertex_pipe->vp_free(device, context); + ++ if (priv->ubo_vs_c != -1) ++ { ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_vs_c)); ++ checkGLcall("glDeleteBuffers"); ++ priv->ubo_vs_c = -1; ++ } + heap_free(device->shader_priv); + device->shader_priv = NULL; + } +diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c +index 5c96d3b..e572751 100644 +--- a/dll/directx/wine/wined3d/shader.c ++++ b/dll/directx/wine/wined3d/shader.c +@@ -767,6 +767,8 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w + } + else + { ++ if (reg->idx[0].offset >= reg_maps->constant_float_count) ++ reg_maps->constant_float_count = reg->idx[0].offset + 1; + wined3d_insert_bits(reg_maps->constf, reg->idx[0].offset, 1, 0x1); + } + } +diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c +index 2f90fd5..817166e 100644 +--- a/dll/directx/wine/wined3d/state.c ++++ b/dll/directx/wine/wined3d/state.c +@@ -4396,6 +4396,11 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state + unsigned int i, base, count; + + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); ++ if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS) ++ { ++ WARN("Called in legacy shader constant mode.\n"); ++ return; ++ } + + if (STATE_IS_GRAPHICS_CONSTANT_BUFFER(state_id)) + shader_type = state_id - STATE_GRAPHICS_CONSTANT_BUFFER(0); +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 361a594..731b44a 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -1073,6 +1073,7 @@ struct wined3d_shader_reg_maps + struct wined3d_shader_tgsm *tgsm; + SIZE_T tgsm_capacity; + unsigned int tgsm_count; ++ UINT constant_float_count; + }; + + /* Keeps track of details for TEX_M#x# instructions which need to maintain +@@ -2709,6 +2710,7 @@ struct wined3d_gl_limits + UINT glsl_varyings; + UINT glsl_vs_float_constants; + UINT glsl_ps_float_constants; ++ UINT glsl_max_uniform_block_size; + + UINT arb_vs_float_constants; + UINT arb_vs_native_constants; +diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h +index baa7089..e0df4c7 100644 +--- a/sdk/include/reactos/wine/wined3d.h ++++ b/sdk/include/reactos/wine/wined3d.h +@@ -1334,6 +1334,7 @@ enum wined3d_shader_type + #define WINED3D_NO_PRIMITIVE_RESTART 0x00000800 + #define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 + #define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 ++#define WINED3D_LEGACY_SHADER_CONSTANTS 0x00004000 + + #define WINED3D_RESZ_CODE 0x7fa05000 + diff --git a/sdk/tools/winesync/wined3d_staging/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff b/sdk/tools/winesync/wined3d_staging/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff new file mode 100644 index 00000000000..418db1eb0eb --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0008-wined3d__Report_actual_vertex_shader_float_constants_limit_for_SWVP_device.diff @@ -0,0 +1,77 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index 6da0e20..fe507de 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -5171,7 +5171,8 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ + d3d_info->limits.gs_version = shader_caps.gs_version; + d3d_info->limits.ps_version = shader_caps.ps_version; + d3d_info->limits.cs_version = shader_caps.cs_version; +- d3d_info->limits.vs_uniform_count = shader_caps.vs_uniform_count; ++ d3d_info->limits.vs_uniform_count_swvp = shader_caps.vs_uniform_count; ++ d3d_info->limits.vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, shader_caps.vs_uniform_count); + d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count; + d3d_info->limits.varying_count = shader_caps.varying_count; + d3d_info->limits.ffp_textures = fragment_caps.MaxSimultaneousTextures; +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 90d04e6..ac720b9 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4076,10 +4076,21 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d + + HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps) + { ++ const struct wined3d_adapter *adapter = device->wined3d->adapters[device->adapter->ordinal]; ++ struct wined3d_vertex_caps vertex_caps; ++ HRESULT hr; ++ + TRACE("device %p, caps %p.\n", device, caps); + +- return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, ++ hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal, + device->create_parms.device_type, caps); ++ if (FAILED(hr)) ++ return hr; ++ ++ adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); ++ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; ++ return hr; + } + + HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 039bec0..c9612c8 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -11233,7 +11233,10 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s + caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0; + caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0; + +- caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants); ++ caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F_SWVP, ++ gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] ++ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) ++ : gl_info->limits.glsl_vs_float_constants); + caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants); + caps->varying_count = gl_info->limits.glsl_varyings; + +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 731b44a..6a7dc4f 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -167,6 +167,7 @@ struct wined3d_d3d_limits + { + unsigned int vs_version, hs_version, ds_version, gs_version, ps_version, cs_version; + DWORD vs_uniform_count; ++ DWORD vs_uniform_count_swvp; + DWORD ps_uniform_count; + unsigned int varying_count; + unsigned int ffp_textures; +@@ -703,6 +704,7 @@ enum wined3d_shader_conditional_op + #define WINED3D_MAX_CONSTS_B 16 + #define WINED3D_MAX_CONSTS_I 16 + #define WINED3D_MAX_VS_CONSTS_F 256 ++#define WINED3D_MAX_VS_CONSTS_F_SWVP 8192 + #define WINED3D_MAX_PS_CONSTS_F 224 + + /* FIXME: This needs to go up to 2048 for diff --git a/sdk/tools/winesync/wined3d_staging/0009-wined3d__Support_SWVP_vertex_shader_constants_limit_in_state_tracking.diff b/sdk/tools/winesync/wined3d_staging/0009-wined3d__Support_SWVP_vertex_shader_constants_limit_in_state_tracking.diff new file mode 100644 index 00000000000..612f6972d3b --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0009-wined3d__Support_SWVP_vertex_shader_constants_limit_in_state_tracking.diff @@ -0,0 +1,146 @@ +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index ac720b9..33e2951 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -2450,13 +2450,17 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device, + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) + { + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; ++ unsigned int constants_count; + unsigned int i; + + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); + +- if (!constants || start_idx >= d3d_info->limits.vs_uniform_count +- || count > d3d_info->limits.vs_uniform_count - start_idx) ++ constants_count = device->create_parms.flags ++ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count; ++ if (!constants || start_idx >= constants_count ++ || count > constants_count - start_idx) + return WINED3DERR_INVALIDCALL; + + memcpy(&device->update_stateblock_state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); +@@ -2483,12 +2487,16 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device + unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants) + { + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; ++ unsigned int constants_count; + + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); + +- if (!constants || start_idx >= d3d_info->limits.vs_uniform_count +- || count > d3d_info->limits.vs_uniform_count - start_idx) ++ constants_count = device->create_parms.flags ++ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count; ++ if (!constants || start_idx >= constants_count ++ || count > constants_count - start_idx) + return WINED3DERR_INVALIDCALL; + + memcpy(constants, &device->state.vs_consts_f[start_idx], count * sizeof(*constants)); +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index c9612c8..050d94c 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -1911,7 +1911,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev + if (priv->consts_ubo) + return; + +- for (i = start; i < count + start; ++i) ++ for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i) + { + update_heap_entry(heap, i, priv->next_constant_version); + } +diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c +index a960932..172b46b 100644 +--- a/dll/directx/wine/wined3d/stateblock.c ++++ b/dll/directx/wine/wined3d/stateblock.c +@@ -312,7 +312,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) + } + } + +- for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i) ++ for (i = 0; i < d3d_info->limits.vs_uniform_count_swvp; ++i) + { + if (stateblock->changed.vs_consts_f[i]) + { +@@ -1289,10 +1289,17 @@ void CDECL wined3d_stateblock_set_vertex_shader(struct wined3d_stateblock *state + HRESULT CDECL wined3d_stateblock_set_vs_consts_f(struct wined3d_stateblock *stateblock, + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) + { ++ const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info; ++ unsigned int constants_count; ++ + TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n", + stateblock, start_idx, count, constants); + +- if (!constants || start_idx >= WINED3D_MAX_VS_CONSTS_F || count > WINED3D_MAX_VS_CONSTS_F - start_idx) ++ constants_count = stateblock->device->create_parms.flags ++ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count; ++ ++ if (!constants || start_idx >= constants_count || count > constants_count - start_idx) + return WINED3DERR_INVALIDCALL; + + memcpy(&stateblock->stateblock_state.vs_consts_f[start_idx], constants, count * sizeof(*constants)); +@@ -1758,7 +1765,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, + stateblock_init_lights(stateblock->stateblock_state.light_state.light_map, + device->stateblock_state.light_state.light_map); + stateblock_savedstates_set_all(&stateblock->changed, +- d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count); ++ d3d_info->limits.vs_uniform_count_swvp, d3d_info->limits.ps_uniform_count); + break; + + case WINED3D_SBT_PIXEL_STATE: +@@ -1770,7 +1777,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, + stateblock_init_lights(stateblock->stateblock_state.light_state.light_map, + device->stateblock_state.light_state.light_map); + stateblock_savedstates_set_vertex(&stateblock->changed, +- d3d_info->limits.vs_uniform_count); ++ d3d_info->limits.vs_uniform_count_swvp); + break; + + default: +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 6a7dc4f..efe41f8 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -3167,7 +3167,7 @@ struct wined3d_state + + BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; + struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; +- struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; ++ struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; + + BOOL ps_consts_b[WINED3D_MAX_CONSTS_B]; + struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I]; +@@ -3239,7 +3239,7 @@ struct wined3d_stateblock_state + int base_vertex_index; + + struct wined3d_shader *vs; +- struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; ++ struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; + struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; + BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; + +@@ -3938,7 +3938,7 @@ struct wined3d_saved_states + BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; + WORD vertexShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ + WORD vertexShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ +- BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; ++ BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; + DWORD textures : 20; /* WINED3D_MAX_COMBINED_SAMPLERS, 20 */ + DWORD indices : 1; + DWORD material : 1; +@@ -3975,7 +3975,7 @@ struct wined3d_stateblock + unsigned int num_contained_vs_consts_i; + DWORD contained_vs_consts_b[WINED3D_MAX_CONSTS_B]; + unsigned int num_contained_vs_consts_b; +- DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; ++ DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP]; + unsigned int num_contained_vs_consts_f; + DWORD contained_ps_consts_i[WINED3D_MAX_CONSTS_I]; + unsigned int num_contained_ps_consts_i; diff --git a/sdk/tools/winesync/wined3d_staging/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff b/sdk/tools/winesync/wined3d_staging/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff new file mode 100644 index 00000000000..305aa1fbaa4 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0010-wined3d__Support_SWVP_mode_vertex_shaders.diff @@ -0,0 +1,404 @@ +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 33e2951..d56ae07 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4532,6 +4532,14 @@ void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device * + warned = TRUE; + } + ++ wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); ++ if (!device->softwareVertexProcessing != !software) ++ { ++ unsigned int i; ++ ++ for (i = 0; i < device->context_count; ++i) ++ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; ++ } + device->softwareVertexProcessing = software; + } + +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 050d94c..0c3955f 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -140,7 +140,9 @@ struct shader_glsl_priv + + BOOL consts_ubo; + GLuint ubo_vs_c; +- struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F]; ++ BOOL prev_device_swvp; ++ struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F_SWVP]; ++ unsigned int max_vs_consts_f; + + const struct wined3d_vertex_pipe_ops *vertex_pipe; + const struct wined3d_fragment_pipe_ops *fragment_pipe; +@@ -155,7 +157,7 @@ struct glsl_vs_program + struct list shader_entry; + GLuint id; + GLenum vertex_color_clamp; +- GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F]; ++ GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F_SWVP]; + GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; + GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; + GLint pos_fixup_location; +@@ -1193,7 +1195,7 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st + { + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); + checkGLcall("glBindBuffer"); +- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); + } +@@ -1201,14 +1203,16 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st + /* Context activation is done by the caller. */ + static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, + const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, +- unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv) ++ unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv, BOOL device_swvp) + { + const struct wined3d_shader_lconst *lconst; + BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX; + + if (is_vertex_shader && priv->consts_ubo) + { ++ BOOL zero_sw_constants = !device_swvp && priv->prev_device_swvp; + const struct wined3d_vec4 *data; ++ unsigned int const_count; + unsigned max_const_used; + + if (priv->ubo_vs_c == -1) +@@ -1218,22 +1222,32 @@ static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, co + } + + bind_and_orphan_consts_ubo(gl_info, priv); +- max_const_used = shader->reg_maps.usesrelconstF +- ? WINED3D_MAX_VS_CONSTS_F : shader->reg_maps.constant_float_count; +- if (shader->load_local_constsF) ++ const_count = device_swvp ? priv->max_vs_consts_f : WINED3D_MAX_VS_CONSTS_F; ++ max_const_used = shader->reg_maps.usesrelconstF ? const_count : shader->reg_maps.constant_float_count; ++ if (shader->load_local_constsF || (zero_sw_constants && shader->reg_maps.usesrelconstF)) + { + data = priv->vs_c_buffer; + memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants)); +- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) ++ if (zero_sw_constants) + { +- priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; ++ memset(&priv->vs_c_buffer[const_count], 0, (priv->max_vs_consts_f - WINED3D_MAX_VS_CONSTS_F) ++ * sizeof(*constants)); ++ priv->prev_device_swvp = FALSE; ++ } ++ if (shader->load_local_constsF) ++ { ++ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry) ++ { ++ priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value; ++ } + } + } + else + { + data = constants; + } +- GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) * max_const_used, data)); ++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) ++ * (zero_sw_constants ? priv->max_vs_consts_f : max_const_used), data)); + checkGLcall("glBufferSubData"); + return; + } +@@ -1601,7 +1615,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); + GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c)); + checkGLcall("glBindBuffer (UBO)"); +- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4), ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4), + NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); + } +@@ -1613,7 +1627,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + + if (update_mask & WINED3D_SHADER_CONST_VS_F) + shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f, +- prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version, priv); ++ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, ++ constant_version, priv, device_is_swvp(context->device)); + + if (update_mask & WINED3D_SHADER_CONST_VS_I) + shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i, +@@ -1766,7 +1781,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + + if (update_mask & WINED3D_SHADER_CONST_PS_F) + shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f, +- prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, priv); ++ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, ++ priv, FALSE); + + if (update_mask & WINED3D_SHADER_CONST_PS_I) + shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i, +@@ -1911,7 +1927,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev + if (priv->consts_ubo) + return; + +- for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i) ++ for (i = start; i < count + start; ++i) + { + update_heap_entry(heap, i, priv->next_constant_version); + } +@@ -2265,7 +2281,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c + shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n" + "{ \n" + " vec4 %s_c[%u];\n" +- "};\n", prefix, min(shader->limits->constant_float, WINED3D_MAX_VS_CONSTS_F)); ++ "};\n", prefix, min(shader->limits->constant_float, priv->max_vs_consts_f)); + } + else if (shader->limits->constant_float > 0) + { +@@ -9975,12 +9991,13 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * + } + else if (!priv->consts_ubo) + { +- for (i = 0; i < vs_c_count; ++i) ++ for (i = 0; i < min(vs_c_count, priv->max_vs_consts_f); ++i) + { + string_buffer_sprintf(name, "vs_c[%u]", i); + vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } +- memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); ++ if (vs_c_count < priv->max_vs_consts_f) ++ memset(&vs->uniform_f_locations[vs_c_count], 0xff, (priv->max_vs_consts_f - vs_c_count) * sizeof(GLuint)); + } + + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) +@@ -10298,6 +10315,10 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, + vs_list = &ffp_shader->linked_programs; + } + ++ if (vshader && vshader->reg_maps.constant_float_count > WINED3D_MAX_VS_CONSTS_F ++ && !device_is_swvp(context_gl->c.device)) ++ FIXME("Applying context with SW shader in HW mode.\n"); ++ + hshader = state->shader[WINED3D_SHADER_TYPE_HULL]; + if (!(context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program) + hs_id = ctx_data->glsl_program->hs.id; +@@ -11055,7 +11076,7 @@ static void constant_heap_free(struct constant_heap *heap) + static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, + const struct wined3d_fragment_pipe_ops *fragment_pipe) + { +- SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1; ++ SIZE_T stack_size; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct fragment_caps fragment_caps; + void *vertex_priv, *fragment_priv; +@@ -11066,6 +11087,18 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + + priv->consts_ubo = (device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS) + && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]; ++ priv->max_vs_consts_f = min(WINED3D_MAX_VS_CONSTS_F_SWVP, priv->consts_ubo ++ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4) ++ : gl_info->limits.glsl_vs_float_constants); ++ ++ if (!(device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING))) ++ priv->max_vs_consts_f = min(priv->max_vs_consts_f, WINED3D_MAX_VS_CONSTS_F); ++ ++ stack_size = priv->consts_ubo ++ ? wined3d_log2i(WINED3D_MAX_PS_CONSTS_F) + 1 ++ : wined3d_log2i(max(priv->max_vs_consts_f, WINED3D_MAX_PS_CONSTS_F)) + 1; ++ TRACE("consts_ubo %#x, max_vs_consts_f %u.\n", priv->consts_ubo, priv->max_vs_consts_f); ++ + string_buffer_list_init(&priv->string_buffers); + + if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv))) +@@ -11095,7 +11128,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + goto fail; + } + +- if (!constant_heap_init(&priv->vconst_heap, WINED3D_MAX_VS_CONSTS_F)) ++ if (!priv->consts_ubo && !constant_heap_init(&priv->vconst_heap, priv->max_vs_consts_f)) + { + ERR("Failed to initialize vertex shader constant heap\n"); + goto fail; +diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c +index e572751..de4776b 100644 +--- a/dll/directx/wine/wined3d/shader.c ++++ b/dll/directx/wine/wined3d/shader.c +@@ -592,7 +592,7 @@ static void shader_delete_constant_list(struct list *clist) + list_init(clist); + } + +-static void shader_set_limits(struct wined3d_shader *shader) ++static void shader_set_limits(struct wined3d_shader *shader, BOOL swvp) + { + static const struct limits_entry + { +@@ -615,6 +615,19 @@ static void shader_set_limits(struct wined3d_shader *shader) + {WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}}, + {0} + }, ++ vs_limits_swvp[] = ++ { ++ /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */ ++ {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0, 0, 8192, 0, 12, 0}}, ++ {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 255), { 0, 16, 8192, 16, 12, 0}}, ++ /* DX10 cards on Windows advertise a D3D9 constant limit of 256 ++ * even though they are capable of supporting much more (GL ++ * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the ++ * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 ++ * shaders to 256. */ ++ {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 255), { 4, 16, 8192, 16, 12, 0}}, ++ {0} ++ }, + hs_limits[] = + { + /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */ +@@ -659,7 +672,7 @@ static void shader_set_limits(struct wined3d_shader *shader) + FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type); + /* Fall-through. */ + case WINED3D_SHADER_TYPE_VERTEX: +- limits_array = vs_limits; ++ limits_array = swvp ? vs_limits_swvp : vs_limits; + break; + case WINED3D_SHADER_TYPE_HULL: + limits_array = hs_limits; +@@ -1027,7 +1040,7 @@ static HRESULT shader_scan_output_signature(struct wined3d_shader *shader) + } + + /* Note that this does not count the loop register as an address register. */ +-static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size) ++static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size, BOOL swvp) + { + struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)]; + struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT]; +@@ -1053,7 +1066,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co + prev_ins = current_ins = ptr; + reg_maps->shader_version = shader_version; + +- shader_set_limits(shader); ++ shader_set_limits(shader, swvp); + + if (!(reg_maps->constf = heap_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32), + sizeof(*reg_maps->constf)))) +@@ -3325,7 +3338,7 @@ static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_l + } + + static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device, +- enum wined3d_shader_type type, unsigned int float_const_count) ++ enum wined3d_shader_type type, unsigned int float_const_count, BOOL swvp) + { + const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; + struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; +@@ -3350,7 +3363,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d + shader_trace_init(fe, shader->frontend_data); + + /* Second pass: figure out which registers are used, what the semantics are, etc. */ +- if (FAILED(hr = shader_get_registers_used(shader, float_const_count))) ++ if (FAILED(hr = shader_get_registers_used(shader, float_const_count, swvp))) + return hr; + + if (version->type != type) +@@ -3689,14 +3702,19 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_ + const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) + { + struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; ++ unsigned int vs_uniform_count; + unsigned int i; + HRESULT hr; ++ BOOL swvp = device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING ++ | WINED3DCREATE_MIXED_VERTEXPROCESSING); + + if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops))) + return hr; + ++ vs_uniform_count = swvp ? device->adapter->d3d_info.limits.vs_uniform_count_swvp ++ : device->adapter->d3d_info.limits.vs_uniform_count; + if (FAILED(hr = shader_set_function(shader, device, +- WINED3D_SHADER_TYPE_VERTEX, device->adapter->d3d_info.limits.vs_uniform_count))) ++ WINED3D_SHADER_TYPE_VERTEX, vs_uniform_count, swvp))) + { + shader_cleanup(shader); + return hr; +@@ -3800,7 +3818,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader, + { + shader->reg_maps.shader_version = shader_version; + shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; +- shader_set_limits(shader); ++ shader_set_limits(shader, 0); + if (FAILED(hr = shader_scan_output_signature(shader))) + return hr; + } +@@ -3853,7 +3871,7 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3 + goto fail; + + if (shader->function +- && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0))) ++ && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0, 0))) + goto fail; + + return WINED3D_OK; +@@ -4185,7 +4203,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d + return hr; + + if (FAILED(hr = shader_set_function(shader, device, +- WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count))) ++ WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count, 0))) + { + shader_cleanup(shader); + return hr; +@@ -4277,7 +4295,7 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru + return hr; + } + +- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0))) ++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0, 0))) + { + shader_cleanup(object); + heap_free(object); +@@ -4311,7 +4329,7 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru + return hr; + } + +- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0))) ++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0, 0))) + { + shader_cleanup(object); + heap_free(object); +@@ -4373,7 +4391,7 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru + return hr; + } + +- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0))) ++ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0, 0))) + { + shader_cleanup(object); + heap_free(object); +diff --git a/dll/directx/wine/wined3d/shader_sm1.c b/dll/directx/wine/wined3d/shader_sm1.c +index 0c6bb93..1051307 100644 +--- a/dll/directx/wine/wined3d/shader_sm1.c ++++ b/dll/directx/wine/wined3d/shader_sm1.c +@@ -543,7 +543,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size, + + major = WINED3D_SM1_VERSION_MAJOR(*byte_code); + minor = WINED3D_SM1_VERSION_MINOR(*byte_code); +- if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0)) ++ if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 255)) + { + WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code); + return NULL; +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index efe41f8..daccc13 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -4884,6 +4884,13 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, + return FALSE; + } + ++static inline BOOL device_is_swvp(const struct wined3d_device *device) ++{ ++ return (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ && device->softwareVertexProcessing); ++} ++ + void get_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN; + void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, + unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN; diff --git a/sdk/tools/winesync/wined3d_staging/0011-wined3d__Allow_higher_world_matrix_states.diff b/sdk/tools/winesync/wined3d_staging/0011-wined3d__Allow_higher_world_matrix_states.diff new file mode 100644 index 00000000000..4baa7797afa --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0011-wined3d__Allow_higher_world_matrix_states.diff @@ -0,0 +1,363 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index fe507de..06fbc51 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -5180,6 +5180,7 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_ + TRACE("Max texture stages: %u.\n", d3d_info->limits.ffp_blend_stages); + d3d_info->limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; + d3d_info->limits.active_light_count = vertex_caps.max_active_lights; ++ d3d_info->limits.ffp_max_vertex_blend_matrix_index = vertex_caps.max_vertex_blend_matrix_index; + + d3d_info->valid_dual_rt_mask = 0; + for (i = 0; i < gl_info->limits.dual_buffers; ++i) +diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c +index fc5d722..9f90d3c 100644 +--- a/dll/directx/wine/wined3d/cs.c ++++ b/dll/directx/wine/wined3d/cs.c +@@ -1671,7 +1671,8 @@ static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *dat + const struct wined3d_cs_set_transform *op = data; + + cs->state.transforms[op->state] = op->matrix; +- if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) ++ if (op->state < WINED3D_TS_WORLD_MATRIX(max(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices, ++ cs->device->adapter->d3d_info.limits.ffp_max_vertex_blend_matrix_index + 1))) + device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); + } + +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index d56ae07..986ea7a 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4098,6 +4098,11 @@ HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device + adapter->vertex_pipe->vp_get_caps(adapter, &vertex_caps); + if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp; ++ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; ++ if (!((device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) ++ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING) ++ && device->softwareVertexProcessing))) ++ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); + return hr; + } + +diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c +index 726b1e3..f366b8c 100644 +--- a/dll/directx/wine/wined3d/directx.c ++++ b/dll/directx/wine/wined3d/directx.c +@@ -2032,6 +2032,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, unsigned in + caps->MaxActiveLights = vertex_caps.max_active_lights; + caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices; + caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index; ++ if (caps->DeviceType == WINED3D_DEVICE_TYPE_HAL) ++ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8); + caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps; + caps->FVFCaps = vertex_caps.fvf_caps; + caps->RasterCaps |= vertex_caps.raster_caps; +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 0c3955f..055749f 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -11998,6 +11998,258 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, ++ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT}, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, +diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c +index 817166e..ab14864 100644 +--- a/dll/directx/wine/wined3d/state.c ++++ b/dll/directx/wine/wined3d/state.c +@@ -5416,7 +5416,8 @@ static void prune_invalid_states(struct wined3d_state_entry *state_table, const + state_table[i].apply = state_undefined; + } + +- start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(d3d_info->limits.ffp_vertex_blend_matrices)); ++ start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(max(d3d_info->limits.ffp_vertex_blend_matrices, ++ d3d_info->limits.ffp_max_vertex_blend_matrix_index + 1))); + last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)); + for (i = start; i <= last; ++i) + { +diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c +index cc217c7..d58c503 100644 +--- a/dll/directx/wine/wined3d/utils.c ++++ b/dll/directx/wine/wined3d/utils.c +@@ -5127,11 +5127,9 @@ const char *debug_d3dtstype(enum wined3d_transform_state tstype) + TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(3)); + #undef TSTYPE_TO_STR + default: +- if (tstype > 256 && tstype < 512) +- { +- FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype); +- return ("WINED3D_TS_WORLD_MATRIX > 0"); +- } ++ if (tstype > WINED3D_TS_WORLD_MATRIX(3) && tstype < WINED3D_TS_WORLD_MATRIX(256)) ++ return ("WINED3D_TS_WORLD_MATRIX > 3"); ++ + FIXME("Unrecognized transform state %#x.\n", tstype); + return "unrecognized"; + } +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index daccc13..c4c6bab 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -174,6 +174,7 @@ struct wined3d_d3d_limits + unsigned int ffp_blend_stages; + unsigned int ffp_vertex_blend_matrices; + unsigned int active_light_count; ++ unsigned int ffp_max_vertex_blend_matrix_index; + + unsigned int max_rt_count; + unsigned int max_clip_distances; diff --git a/sdk/tools/winesync/wined3d_staging/0012-wined3d__Support_indexed_vertex_blending.diff b/sdk/tools/winesync/wined3d_staging/0012-wined3d__Support_indexed_vertex_blending.diff new file mode 100644 index 00000000000..c528926c79d --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0012-wined3d__Support_indexed_vertex_blending.diff @@ -0,0 +1,380 @@ +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 055749f..05de1d7 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -150,6 +150,9 @@ struct shader_glsl_priv + struct wine_rb_tree ffp_fragment_shaders; + BOOL ffp_proj_control; + BOOL legacy_lighting; ++ ++ GLuint ubo_modelview; ++ struct wined3d_matrix *modelview_buffer; + }; + + struct glsl_vs_program +@@ -164,6 +167,7 @@ struct glsl_vs_program + GLint base_vertex_id_location; + + GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; ++ GLint modelview_block_index; + GLint projection_matrix_location; + GLint normal_matrix_location; + GLint texture_matrix_location[WINED3D_MAX_TEXTURES]; +@@ -1606,10 +1610,10 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + { + unsigned int base, count; + ++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++ &base, &count); + if (priv->consts_ubo) + { +- wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, +- &base, &count); + if (priv->ubo_vs_c == -1) + { + GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c)); +@@ -1622,6 +1626,21 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base, priv->ubo_vs_c)); + checkGLcall("glBindBufferBase"); + } ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT] ++ && (context->device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_SHADER_CONSTANTS)) ++ { ++ if (priv->ubo_modelview == -1) ++ { ++ GL_EXTCALL(glGenBuffers(1, &priv->ubo_modelview)); ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); ++ checkGLcall("glBindBuffer (UBO)"); ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, ++ sizeof(struct wined3d_matrix) * MAX_VERTEX_BLEND_UBO, NULL, GL_DYNAMIC_DRAW)); ++ checkGLcall("glBufferData (UBO)"); ++ } ++ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + 1, priv->ubo_modelview)); ++ checkGLcall("glBindBufferBase"); ++ } + ctx_data->ubo_bound = TRUE; + } + +@@ -1668,28 +1687,41 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context + } + + if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW) +- { +- struct wined3d_matrix mat; +- +- get_modelview_matrix(context, state, 0, &mat); +- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); +- checkGLcall("glUniformMatrix4fv"); +- + shader_glsl_ffp_vertex_normalmatrix_uniform(context_gl, state, prog); +- } + + if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) + { + struct wined3d_matrix mat; + +- for (i = 1; i < MAX_VERTEX_BLENDS; ++i) ++ if (prog->vs.modelview_block_index != -1) + { +- if (prog->vs.modelview_matrix_location[i] == -1) +- break; ++ if (priv->ubo_modelview == -1) ++ FIXME("UBO buffer with vertex blend matrices is not initialized.\n"); ++ ++ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview)); ++ checkGLcall("glBindBuffer (UBO)"); ++ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); + +- get_modelview_matrix(context, state, i, &mat); +- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); +- checkGLcall("glUniformMatrix4fv"); ++ for (i = 0; i < MAX_VERTEX_BLEND_UBO; ++i) ++ get_modelview_matrix(context, state, i, &priv->modelview_buffer[i]); ++ ++ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, ++ sizeof(*priv->modelview_buffer) * MAX_VERTEX_BLEND_UBO, priv->modelview_buffer)); ++ checkGLcall("glBufferSubData"); ++ } ++ else ++ { ++ for (i = 0; i < MAX_VERTEX_BLENDS; ++i) ++ { ++ if (prog->vs.modelview_matrix_location[i] == -1) ++ break; ++ ++ get_modelview_matrix(context, state, i, &mat); ++ GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); ++ checkGLcall("glUniformMatrix4fv"); ++ } + } + } + +@@ -9008,8 +9040,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + { + {"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */ + {"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */ +- /* TODO: Indexed vertex blending */ +- {"float", ""}, /* WINED3D_FFP_BLENDINDICES */ ++ {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */ + {"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */ + {"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */ + {"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */ +@@ -9025,6 +9056,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + string_buffer_clear(buffer); + + shader_glsl_add_version_declaration(buffer, gl_info); ++ TRACE("settings->vb_indices %#x.\n", settings->vb_indices); ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ shader_addline(buffer,"#extension GL_ARB_uniform_buffer_object : enable\n"); + + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); +@@ -9039,7 +9073,18 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + } + shader_addline(buffer, "\n"); + +- shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS); ++ if (settings->vb_indices && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ { ++ shader_addline(buffer,"layout(std140) uniform ffp_modelview_ubo\n\ ++ { \n\ ++ mat4 ffp_modelview_matrix[%u];\n\ ++ };\n", MAX_VERTEX_BLEND_UBO); ++ } ++ else ++ { ++ shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", settings->vertexblends + 1); ++ } ++ + shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); + shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); + shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", WINED3D_MAX_TEXTURES); +@@ -9101,6 +9146,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + shader_addline(buffer, "\nvoid main()\n{\n"); + shader_addline(buffer, "float m;\n"); + shader_addline(buffer, "vec3 r;\n"); ++ if (settings->vb_indices) ++ shader_addline(buffer, "int ind;\n"); + + for (i = 0; i < ARRAY_SIZE(attrib_info); ++i) + { +@@ -9130,8 +9177,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); + + shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); +- for (i = 0; i < settings->vertexblends + 1; ++i) +- shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); ++ if (settings->vb_indices) ++ { ++ for (i = 0; i < settings->vertexblends + 1; ++i) ++ { ++ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); ++ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " ++ "(ffp_modelview_matrix[ind] * ffp_attrib_position);\n", i); ++ } ++ } ++ else ++ { ++ for (i = 0; i < settings->vertexblends + 1; ++i) ++ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * " ++ "(ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); ++ } + + shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n"); + if (settings->clipping) +@@ -9155,7 +9215,19 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr + else + { + for (i = 0; i < settings->vertexblends + 1; ++i) +- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); ++ { ++ if (settings->vb_indices) ++ { ++ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i); ++ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " ++ "(mat3(ffp_modelview_matrix[ind]) * ffp_attrib_normal);\n", i); ++ } ++ else ++ { ++ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * " ++ "(mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); ++ } ++ } + } + + if (settings->normalize) +@@ -10020,6 +10092,28 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * + string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i); + vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } ++ ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ { ++ vs->modelview_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "ffp_modelview_ubo")); ++ checkGLcall("glGetUniformBlockIndex"); ++ if (vs->modelview_block_index != -1) ++ { ++ unsigned int base, count; ++ ++ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, ++ &base, &count); ++ assert(count >= 2); ++ ++ GL_EXTCALL(glUniformBlockBinding(program_id, vs->modelview_block_index, base + 1)); ++ checkGLcall("glUniformBlockBinding"); ++ } ++ } ++ else ++ { ++ vs->modelview_block_index = -1; ++ } ++ + vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); + vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) +@@ -10599,7 +10693,7 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, + entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW + | WINED3D_SHADER_CONST_FFP_PROJ; + +- for (i = 1; i < MAX_VERTEX_BLENDS; ++i) ++ for (i = 0; i < MAX_VERTEX_BLENDS; ++i) + { + if (entry->vs.modelview_matrix_location[i] != -1) + { +@@ -10608,6 +10702,9 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl, + } + } + ++ if (entry->vs.modelview_block_index != -1) ++ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; ++ + for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) + { + if (entry->vs.texture_matrix_location[i] != -1) +@@ -11148,7 +11245,17 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win + fragment_pipe->get_caps(device->adapter, &fragment_caps); + priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL; + priv->legacy_lighting = device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING; +- ++ priv->ubo_modelview = -1; /* To be initialized on first usage. */ ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ { ++ priv->modelview_buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv->modelview_buffer) ++ * MAX_VERTEX_BLEND_UBO); ++ if (!priv->modelview_buffer) ++ { ++ ERR("Failed to alloacte modelview buffer.\n"); ++ goto fail; ++ } ++ } + device->vertex_priv = vertex_priv; + device->fragment_priv = fragment_priv; + device->shader_priv = priv; +@@ -11181,6 +11288,14 @@ static void shader_glsl_free(struct wined3d_device *device, struct wined3d_conte + string_buffer_free(&priv->shader_buffer); + priv->fragment_pipe->free_private(device, context); + priv->vertex_pipe->vp_free(device, context); ++ if (priv->ubo_modelview != -1) ++ { ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_modelview)); ++ checkGLcall("glDeleteBuffers"); ++ priv->ubo_modelview = -1; ++ } ++ HeapFree(GetProcessHeap(), 0, priv->modelview_buffer); + + if (priv->ubo_vs_c != -1) + { +@@ -11605,7 +11720,11 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter, + caps->ffp_generic_attributes = TRUE; + caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS; + caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; +- caps->max_vertex_blend_matrix_index = 0; ++ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) ++ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLEND_UBO - 1; ++ else ++ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLENDS - 1; ++ + caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN + | WINED3DVTXPCAPS_MATERIALSOURCE7 + | WINED3DVTXPCAPS_VERTEXFOG +@@ -11807,7 +11926,8 @@ static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, + static void glsl_vertex_pipe_world(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) + { +- context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW; ++ context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW ++ | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; + } + + static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, +diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c +index d58c503..0466863 100644 +--- a/dll/directx/wine/wined3d/utils.c ++++ b/dll/directx/wine/wined3d/utils.c +@@ -6547,6 +6547,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, + settings->flatshading = FALSE; + + settings->swizzle_map = si->swizzle_map; ++ settings->vb_indices = is_indexed_vertex_blending(context, state); + } + + int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) +diff --git a/dll/directx/wine/wined3d/vertexdeclaration.c b/dll/directx/wine/wined3d/vertexdeclaration.c +index 8103274..e91409f 100644 +--- a/dll/directx/wine/wined3d/vertexdeclaration.c ++++ b/dll/directx/wine/wined3d/vertexdeclaration.c +@@ -119,6 +119,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e + return FALSE; + } + ++ case WINED3D_DECL_USAGE_BLEND_INDICES: ++ switch(element->format) ++ { ++ case WINED3DFMT_R8G8B8A8_UINT: ++ return TRUE; ++ default: ++ return FALSE; ++ } ++ + case WINED3D_DECL_USAGE_NORMAL: + switch(element->format) + { +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index c4c6bab..5a6d300 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -275,6 +275,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup + } + + /* Device caps */ ++#define MAX_VERTEX_BLEND_UBO 256 + #define WINED3D_MAX_STREAMS 16 + #define WINED3D_MAX_TEXTURES 8 + #define WINED3D_MAX_FRAGMENT_SAMPLERS 16 +@@ -3062,7 +3063,8 @@ struct wined3d_ffp_vs_settings + DWORD ortho_fog : 1; + DWORD flatshading : 1; + DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */ +- DWORD padding : 2; ++ DWORD vb_indices : 1; ++ DWORD padding : 1; + + DWORD texgen[WINED3D_MAX_TEXTURES]; + }; +@@ -5212,6 +5214,13 @@ static inline void wined3d_not_from_cs(struct wined3d_cs *cs) + assert(cs->thread_id != GetCurrentThreadId()); + } + ++static inline BOOL is_indexed_vertex_blending(const struct wined3d_context *context, ++ const struct wined3d_state *state) ++{ ++ return state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] ++ && (context->stream_info.use_map & (1 << WINED3D_FFP_BLENDINDICES)); ++} ++ + static inline enum wined3d_material_color_source validate_material_colour_source(WORD use_map, + enum wined3d_material_color_source source) + { diff --git a/sdk/tools/winesync/wined3d_staging/0013-wined3d__Print_FIXME_only_once_in_surface_cpu_blt.diff b/sdk/tools/winesync/wined3d_staging/0013-wined3d__Print_FIXME_only_once_in_surface_cpu_blt.diff new file mode 100644 index 00000000000..04d46332a6c --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0013-wined3d__Print_FIXME_only_once_in_surface_cpu_blt.diff @@ -0,0 +1,14 @@ +diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c +index 5064fb9..1beb98e 100644 +--- a/dll/directx/wine/wined3d/surface.c ++++ b/dll/directx/wine/wined3d/surface.c +@@ -1762,7 +1762,8 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int + && (src_width != dst_width || src_height != dst_height)) + { + /* Can happen when d3d9 apps do a StretchRect() call which isn't handled in GL. */ +- FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter)); ++ static int once; ++ if (!once++) FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter)); + } + + xinc = (src_width << 16) / dst_width; diff --git a/sdk/tools/winesync/wined3d_staging/0014-wined3d__Silence_extremely_noisy_FIXME_in_wined3d_texture_add_dirty_region.diff b/sdk/tools/winesync/wined3d_staging/0014-wined3d__Silence_extremely_noisy_FIXME_in_wined3d_texture_add_dirty_region.diff new file mode 100644 index 00000000000..b08873af30d --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0014-wined3d__Silence_extremely_noisy_FIXME_in_wined3d_texture_add_dirty_region.diff @@ -0,0 +1,13 @@ +diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c +index a74f692..0f5a765 100644 +--- a/dll/directx/wine/wined3d/texture.c ++++ b/dll/directx/wine/wined3d/texture.c +@@ -1838,7 +1838,7 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, + } + + if (dirty_region) +- FIXME("Ignoring dirty_region %s.\n", debug_box(dirty_region)); ++ WARN("Ignoring dirty_region %s.\n", debug_box(dirty_region)); + + wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer); + diff --git a/sdk/tools/winesync/wined3d_staging/0015-wined3d__Remaining_UAV_counter_changes.diff b/sdk/tools/winesync/wined3d_staging/0015-wined3d__Remaining_UAV_counter_changes.diff new file mode 100644 index 00000000000..ac72304bf01 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0015-wined3d__Remaining_UAV_counter_changes.diff @@ -0,0 +1,37 @@ +diff --git a/dll/directx/wine/wined3d/cs.c b/dll/directx/wine/wined3d/cs.c +index 9f90d3c..54be547 100644 +--- a/dll/directx/wine/wined3d/cs.c ++++ b/dll/directx/wine/wined3d/cs.c +@@ -2504,6 +2504,7 @@ static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void * + context_release(context); + + wined3d_resource_release(&op->buffer->resource); ++ wined3d_resource_release(view->resource); + } + + void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, +@@ -2518,6 +2519,7 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff + op->view = uav; + + wined3d_resource_acquire(&dst_buffer->resource); ++ wined3d_resource_acquire(uav->resource); + + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); + } +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 986ea7a..655b6d9 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -4616,6 +4616,12 @@ void CDECL wined3d_device_copy_uav_counter(struct wined3d_device *device, + TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n", + device, dst_buffer, offset, uav); + ++ if (offset + sizeof(GLuint) > dst_buffer->resource.size) ++ { ++ WARN("Offset %u too large.\n", offset); ++ return; ++ } ++ + wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav); + } + diff --git a/sdk/tools/winesync/wined3d_staging/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff b/sdk/tools/winesync/wined3d_staging/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff new file mode 100644 index 00000000000..1246998041c --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0016-wined3d__Implement_WINED3DFMT_B8G8R8X8_UNORM_to_WINED3DFMT_L8_UNORM_conversion.diff @@ -0,0 +1,38 @@ +diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c +index 1beb98e..981d6bf 100644 +--- a/dll/directx/wine/wined3d/surface.c ++++ b/dll/directx/wine/wined3d/surface.c +@@ -563,6 +563,25 @@ static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst, + } + } + ++static void convert_x8r8g8b8_l8(const BYTE *src, BYTE *dst, ++ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) ++{ ++ unsigned int x, y; ++ ++ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out); ++ ++ for (y = 0; y < h; ++y) ++ { ++ const DWORD *src_line = (const DWORD *)(src + y * pitch_in); ++ BYTE *dst_line = (BYTE *)(dst + y * pitch_out); ++ ++ for (x = 0; x < w; ++x) ++ { ++ dst_line[x] = src_line[x] & 0x000000ff; ++ } ++ } ++} ++ + struct d3dfmt_converter_desc + { + enum wined3d_format_id from, to; +@@ -577,6 +596,7 @@ static const struct d3dfmt_converter_desc converters[] = + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8A8_UNORM, convert_a8r8g8b8_x8r8g8b8}, + {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8}, + {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5}, ++ {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_L8_UNORM, convert_x8r8g8b8_l8}, + }; + + static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from, diff --git a/sdk/tools/winesync/wined3d_staging/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff b/sdk/tools/winesync/wined3d_staging/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff new file mode 100644 index 00000000000..52aa98f83bf --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0017-wined3d__Implement_all_8_d3d11_color_write_masks.diff @@ -0,0 +1,278 @@ +diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c +index 9001d60..dc57667 100644 +--- a/dll/directx/wine/wined3d/context.c ++++ b/dll/directx/wine/wined3d/context.c +@@ -2754,7 +2754,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, + const struct wined3d_gl_info *gl_info; + uint32_t rt_mask, *cur_mask; + struct wined3d_texture *rt; +- unsigned int sampler; ++ unsigned int i, sampler; + SIZE rt_size; + + TRACE("Setting up context %p for blitting.\n", context); +@@ -2861,10 +2861,8 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + } + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); ++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) ++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); + + context->last_was_rhw = TRUE; + context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ +@@ -4862,7 +4860,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s + if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) + continue; + +- if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) ++ if (state->render_states[WINED3D_RS_COLORWRITE(i)]) + { + wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding); + wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); +diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c +index 655b6d9..d4bd20a 100644 +--- a/dll/directx/wine/wined3d/device.c ++++ b/dll/directx/wine/wined3d/device.c +@@ -438,10 +438,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c + } + + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); ++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) ++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); + gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a); + checkGLcall("glClearColor"); + clear_mask = clear_mask | GL_COLOR_BUFFER_BIT; +diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c +index ab14864..41df2e9 100644 +--- a/dll/directx/wine/wined3d/state.c ++++ b/dll/directx/wine/wined3d/state.c +@@ -1553,9 +1553,6 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined + { + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE]; +- DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1]; +- DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2]; +- DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3]; + + TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", + mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, +@@ -1568,13 +1565,7 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); + checkGLcall("glColorMask(...)"); + +- if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) +- || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) +- { +- FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", +- mask0, mask1, mask2, mask3); +- FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); +- } ++ /* FIXME: WINED3D_RS_COLORWRITEENABLE1 .. WINED3D_RS_COLORWRITEENABLE7 not implemented. */ + } + + static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) +@@ -1587,9 +1578,20 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW + checkGLcall("glColorMaski"); + } + +-static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) ++static void state_colorwrite_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- set_color_mask(wined3d_context_gl(context)->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]); ++ const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; ++ int index; ++ ++ if (state_id == WINED3D_RS_COLORWRITEENABLE) index = 0; ++ else if (state_id <= WINED3D_RS_COLORWRITEENABLE3) index = state_id - WINED3D_RS_COLORWRITEENABLE1 + 1; ++ else if (state_id <= WINED3D_RS_COLORWRITEENABLE7) index = state_id - WINED3D_RS_COLORWRITEENABLE4 + 4; ++ else return; ++ ++ if (index >= gl_info->limits.buffers) ++ WARN("Ignoring color write value for index %d, because gpu only supports %d render targets\n", index, gl_info->limits.buffers); ++ ++ set_color_mask(gl_info, index, state->render_states[state_id]); + } + + static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +@@ -4666,18 +4668,26 @@ const struct wined3d_state_entry_template misc_state_template[] = + { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), state_colorwrite_i }, EXT_DRAW_BUFFERS2 }, ++ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, WINED3D_GL_BLEND_EQUATION }, + { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, +- { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, + /* Samplers */ +diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c +index 172b46b..08ccff6 100644 +--- a/dll/directx/wine/wined3d/stateblock.c ++++ b/dll/directx/wine/wined3d/stateblock.c +@@ -44,6 +44,10 @@ static const DWORD pixel_states_render[] = + WINED3D_RS_COLORWRITEENABLE1, + WINED3D_RS_COLORWRITEENABLE2, + WINED3D_RS_COLORWRITEENABLE3, ++ WINED3D_RS_COLORWRITEENABLE4, ++ WINED3D_RS_COLORWRITEENABLE5, ++ WINED3D_RS_COLORWRITEENABLE6, ++ WINED3D_RS_COLORWRITEENABLE7, + WINED3D_RS_DEPTHBIAS, + WINED3D_RS_DESTBLEND, + WINED3D_RS_DESTBLENDALPHA, +@@ -1452,6 +1456,7 @@ void CDECL wined3d_stateblock_set_blend_factor(struct wined3d_stateblock *stateb + + static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], const struct wined3d_d3d_info *d3d_info) + { ++ unsigned int i; + union + { + struct wined3d_line_pattern lp; +@@ -1545,7 +1550,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c + tmpfloat.f = d3d_info->limits.pointsize_max; + rs[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d; + rs[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE; +- rs[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f; + tmpfloat.f = 0.0f; + rs[WINED3D_RS_TWEENFACTOR] = tmpfloat.d; + rs[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD; +@@ -1571,9 +1575,6 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c + rs[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; + rs[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS; +- rs[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f; +- rs[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f; +- rs[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f; + rs[WINED3D_RS_SRGBWRITEENABLE] = 0; + rs[WINED3D_RS_DEPTHBIAS] = 0; + rs[WINED3D_RS_WRAP8] = 0; +@@ -1588,6 +1589,8 @@ static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], c + rs[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE; + rs[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO; + rs[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD; ++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) ++ rs[WINED3D_RS_COLORWRITE(i)] = 0x0000000f; + } + + static void init_default_texture_state(unsigned int i, DWORD stage[WINED3D_HIGHEST_TEXTURE_STATE + 1]) +diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c +index 981d6bf..7ebb765 100644 +--- a/dll/directx/wine/wined3d/surface.c ++++ b/dll/directx/wine/wined3d/surface.c +@@ -153,6 +153,7 @@ void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *co + GLenum gl_filter; + GLenum buffer; + RECT s, d; ++ int i; + + TRACE("device %p, context %p, filter %s, src_texture %p, src_sub_resource_idx %u, src_location %s, " + "src_rect %s, dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s.\n", +@@ -261,10 +262,8 @@ void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *co + context_invalidate_state(context, STATE_FRAMEBUFFER); + + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); +- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); ++ for (i = 0; i < MAX_RENDER_TARGETS; ++i) ++ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i))); + + gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); + context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); +diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c +index 0466863..e549e1a 100644 +--- a/dll/directx/wine/wined3d/utils.c ++++ b/dll/directx/wine/wined3d/utils.c +@@ -4949,7 +4949,6 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) + D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN); + D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX); + D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE); +- D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); + D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR); + D3DSTATE_TO_STR(WINED3D_RS_BLENDOP); + D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE); +@@ -4969,9 +4968,14 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL); + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS); + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE); + D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1); + D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2); + D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE4); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE5); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE6); ++ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE7); + D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE); + D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS); + D3DSTATE_TO_STR(WINED3D_RS_WRAP8); +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 5a6d300..5ec24e3 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -291,6 +291,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup + #define MAX_UNORDERED_ACCESS_VIEWS 8 + #define MAX_TGSM_REGISTERS 8192 + #define MAX_VERTEX_BLENDS 4 ++#define MAX_RENDER_TARGETS 8 + + struct min_lookup + { +diff --git a/sdk/include/reactos/wine/wined3d.h b/sdk/include/reactos/wine/wined3d.h +index e0df4c7..bbc9acf 100644 +--- a/sdk/include/reactos/wine/wined3d.h ++++ b/sdk/include/reactos/wine/wined3d.h +@@ -400,8 +400,20 @@ enum wined3d_render_state + WINED3D_RS_SRCBLENDALPHA = 207, + WINED3D_RS_DESTBLENDALPHA = 208, + WINED3D_RS_BLENDOPALPHA = 209, ++ WINED3D_RS_COLORWRITEENABLE4 = 210, ++ WINED3D_RS_COLORWRITEENABLE5 = 211, ++ WINED3D_RS_COLORWRITEENABLE6 = 212, ++ WINED3D_RS_COLORWRITEENABLE7 = 213, + }; +-#define WINEHIGHEST_RENDER_STATE WINED3D_RS_BLENDOPALPHA ++#define WINEHIGHEST_RENDER_STATE WINED3D_RS_COLORWRITEENABLE7 ++ ++static inline enum wined3d_render_state WINED3D_RS_COLORWRITE(int index) ++{ ++ if (index == 0) return WINED3D_RS_COLORWRITEENABLE; ++ if (index <= 3) return WINED3D_RS_COLORWRITEENABLE1 + index - 1; ++ if (index <= 7) return WINED3D_RS_COLORWRITEENABLE4 + index - 4; ++ return WINED3D_RS_COLORWRITEENABLE; ++} + + enum wined3d_blend + { diff --git a/sdk/tools/winesync/wined3d_staging/0018-wined3d__Multiple_games_need_WINED3D_TEXF_ANISOTROPIC_filter_mode.diff b/sdk/tools/winesync/wined3d_staging/0018-wined3d__Multiple_games_need_WINED3D_TEXF_ANISOTROPIC_filter_mode.diff new file mode 100644 index 00000000000..e99ac8669d5 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0018-wined3d__Multiple_games_need_WINED3D_TEXF_ANISOTROPIC_filter_mode.diff @@ -0,0 +1,26 @@ +diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c +index 7ebb765..3593455 100644 +--- a/dll/directx/wine/wined3d/surface.c ++++ b/dll/directx/wine/wined3d/surface.c +@@ -163,16 +163,16 @@ void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *co + + switch (filter) + { +- case WINED3D_TEXF_LINEAR: +- gl_filter = GL_LINEAR; ++ case WINED3D_TEXF_NONE: ++ case WINED3D_TEXF_POINT: ++ gl_filter = GL_NEAREST; + break; + + default: + FIXME("Unsupported filter mode %s (%#x).\n", debug_d3dtexturefiltertype(filter), filter); + /* fall through */ +- case WINED3D_TEXF_NONE: +- case WINED3D_TEXF_POINT: +- gl_filter = GL_NEAREST; ++ case WINED3D_TEXF_LINEAR: ++ gl_filter = GL_LINEAR; + break; + } + diff --git a/sdk/tools/winesync/wined3d_staging/0019-wined3d__Use_glReadPixels_for_RT_texture_download.diff b/sdk/tools/winesync/wined3d_staging/0019-wined3d__Use_glReadPixels_for_RT_texture_download.diff new file mode 100644 index 00000000000..2f9d3e50d37 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0019-wined3d__Use_glReadPixels_for_RT_texture_download.diff @@ -0,0 +1,44 @@ +diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c +index 0f5a765..abdd762 100644 +--- a/dll/directx/wine/wined3d/texture.c ++++ b/dll/directx/wine/wined3d/texture.c +@@ -2366,6 +2366,7 @@ static void wined3d_texture_gl_download_data(struct wined3d_context *context, + const struct wined3d_format_gl *format_gl; + BOOL srgb = FALSE; + GLenum target; ++ struct wined3d_texture_sub_resource *sub_resource; + + TRACE("context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_box %s, dst_bo_addr %s, " + "dst_format %s, dst_x %u, dst_y %u, dst_z %u, dst_row_pitch %u, dst_slice_pitch %u.\n", +@@ -2420,6 +2421,7 @@ static void wined3d_texture_gl_download_data(struct wined3d_context *context, + + format_gl = wined3d_format_gl(src_texture->resource.format); + target = wined3d_texture_gl_get_sub_resource_target(src_texture_gl, src_sub_resource_idx); ++ sub_resource = &src_texture->sub_resources[src_sub_resource_idx]; + + if ((src_texture->resource.type == WINED3D_RTYPE_TEXTURE_2D + && (target == GL_TEXTURE_2D_ARRAY || format_gl->f.conv_byte_count +@@ -2452,6 +2454,23 @@ static void wined3d_texture_gl_download_data(struct wined3d_context *context, + GL_EXTCALL(glGetCompressedTexImage(target, src_level, dst_bo_addr->addr)); + checkGLcall("glGetCompressedTexImage"); + } ++ else if (dst_bo_addr->buffer_object && src_texture->resource.bind_flags & WINED3D_BIND_RENDER_TARGET) ++ { ++ /* PBO texture download is not accelerated on Mesa. Use glReadPixels if possible. */ ++ TRACE("Downloading (glReadPixels) texture %p, %u, level %u, format %#x, type %#x, data %p.\n", ++ src_texture, src_sub_resource_idx, src_level, format_gl->format, format_gl->type, dst_bo_addr->addr); ++ ++ wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, &src_texture->resource, src_sub_resource_idx, NULL, ++ 0, sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)); ++ wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER); ++ context_invalidate_state(context, STATE_FRAMEBUFFER); ++ gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); ++ checkGLcall("glReadBuffer()"); ++ ++ gl_info->gl_ops.gl.p_glReadPixels(0, 0, wined3d_texture_get_level_width(src_texture, src_level), ++ wined3d_texture_get_level_height(src_texture, src_level), format_gl->format, format_gl->type, dst_bo_addr->addr); ++ checkGLcall("glReadPixels"); ++ } + else + { + TRACE("Downloading texture %p, %u, level %u, format %#x, type %#x, data %p.\n", diff --git a/sdk/tools/winesync/wined3d_staging/0020-wined3d__Dont_set_DDSCAPS_FLIP_for_gdi_renderer.diff b/sdk/tools/winesync/wined3d_staging/0020-wined3d__Dont_set_DDSCAPS_FLIP_for_gdi_renderer.diff new file mode 100644 index 00000000000..70a36524bfe --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0020-wined3d__Dont_set_DDSCAPS_FLIP_for_gdi_renderer.diff @@ -0,0 +1,38 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index 06fbc51..54423fb 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -4327,6 +4327,7 @@ static void adapter_gl_get_wined3d_caps(const struct wined3d_adapter *adapter, s + const struct wined3d_gl_info *gl_info = &adapter->gl_info; + + caps->ddraw_caps.dds_caps |= WINEDDSCAPS_BACKBUFFER ++ | WINEDDSCAPS_FLIP + | WINEDDSCAPS_COMPLEX + | WINEDDSCAPS_FRONTBUFFER + | WINEDDSCAPS_3DDEVICE +diff --git a/dll/directx/wine/wined3d/adapter_vk.c b/dll/directx/wine/wined3d/adapter_vk.c +index 21163a2..4b88769 100644 +--- a/dll/directx/wine/wined3d/adapter_vk.c ++++ b/dll/directx/wine/wined3d/adapter_vk.c +@@ -298,6 +298,7 @@ static void adapter_vk_get_wined3d_caps(const struct wined3d_adapter *adapter, s + BOOL sampler_anisotropy = limits->maxSamplerAnisotropy > 1.0f; + + caps->ddraw_caps.dds_caps |= WINEDDSCAPS_BACKBUFFER ++ | WINEDDSCAPS_FLIP + | WINEDDSCAPS_COMPLEX + | WINEDDSCAPS_FRONTBUFFER + | WINEDDSCAPS_3DDEVICE +diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c +index f366b8c..ddab690 100644 +--- a/dll/directx/wine/wined3d/directx.c ++++ b/dll/directx/wine/wined3d/directx.c +@@ -2196,8 +2196,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, unsigned in + caps->ddraw_caps.ssb_color_key_caps = ckey_caps; + caps->ddraw_caps.ssb_fx_caps = fx_caps; + +- caps->ddraw_caps.dds_caps = WINEDDSCAPS_FLIP +- | WINEDDSCAPS_OFFSCREENPLAIN ++ caps->ddraw_caps.dds_caps = WINEDDSCAPS_OFFSCREENPLAIN + | WINEDDSCAPS_PALETTE + | WINEDDSCAPS_PRIMARYSURFACE + | WINEDDSCAPS_TEXTURE diff --git a/sdk/tools/winesync/wined3d_staging/0021-wined3d__Also_check_for__Brian_Paul__to_detect_Mesa_gl_vendor.diff b/sdk/tools/winesync/wined3d_staging/0021-wined3d__Also_check_for__Brian_Paul__to_detect_Mesa_gl_vendor.diff new file mode 100644 index 00000000000..de5440784f2 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0021-wined3d__Also_check_for__Brian_Paul__to_detect_Mesa_gl_vendor.diff @@ -0,0 +1,12 @@ +diff --git a/dll/directx/wine/wined3d/adapter_gl.c b/dll/directx/wine/wined3d/adapter_gl.c +index 54423fb..186b228 100644 +--- a/dll/directx/wine/wined3d/adapter_gl.c ++++ b/dll/directx/wine/wined3d/adapter_gl.c +@@ -1242,6 +1242,7 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_in + return GL_VENDOR_FGLRX; + + if (strstr(gl_vendor_string, "Mesa") ++ || strstr(gl_vendor_string, "Brian Paul") + || strstr(gl_vendor_string, "X.Org") + || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.") + || strstr(gl_vendor_string, "DRI R300 Project") diff --git a/sdk/tools/winesync/wined3d_staging/0022-wined3d__Add_a_setting_to_workaround_0___inf_problem_in_shader_models_1-3.diff b/sdk/tools/winesync/wined3d_staging/0022-wined3d__Add_a_setting_to_workaround_0___inf_problem_in_shader_models_1-3.diff new file mode 100644 index 00000000000..bd386cee1a1 --- /dev/null +++ b/sdk/tools/winesync/wined3d_staging/0022-wined3d__Add_a_setting_to_workaround_0___inf_problem_in_shader_models_1-3.diff @@ -0,0 +1,298 @@ +diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c +index 05de1d7..cd3afa1 100644 +--- a/dll/directx/wine/wined3d/glsl_shader.c ++++ b/dll/directx/wine/wined3d/glsl_shader.c +@@ -2298,6 +2298,19 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c + if (wined3d_settings.strict_shader_math) + shader_addline(buffer, "#pragma optionNV(fastmath off)\n"); + ++ if (wined3d_settings.multiply_special == 2 && version->major < 4) ++ { ++ shader_addline(buffer, "float dot1(float v1, float v2) {return abs(v1) == 0.0 || abs(v2) == 0.0 ? 0.0 : v1 * v2;}\n"); ++ shader_addline(buffer, "float dot2(vec2 v1, vec2 v2) {return dot1(v1.x, v2.x) + dot1(v1.y, v2.y);}\n"); ++ shader_addline(buffer, "float dot3(vec3 v1, vec3 v2) {return dot2(v1.xy, v2.xy) + dot1(v1.z, v2.z);}\n"); ++ shader_addline(buffer, "float dot4(vec4 v1, vec4 v2) {return dot2(v1.xy, v2.xy) + dot2(v1.zw, v2.zw);}\n"); ++ ++ shader_addline(buffer, "float mul1(float v1, float v2) {return abs(v1) == 0.0 || abs(v2) == 0.0 ? 0.0 : v1 * v2;}\n"); ++ shader_addline(buffer, "vec2 mul2(vec2 v1, vec2 v2) {return vec2(mul1(v1.x, v2.x), mul1(v1.y, v2.y));}\n"); ++ shader_addline(buffer, "vec3 mul3(vec3 v1, vec3 v2) {return vec3(mul2(v1.xy, v2.xy), mul1(v1.z, v2.z));}\n"); ++ shader_addline(buffer, "vec4 mul4(vec4 v1, vec4 v2) {return vec4(mul2(v1.xy, v2.xy), mul2(v1.zw, v2.zw));}\n"); ++ } ++ + prefix = shader_glsl_get_prefix(version->type); + + /* Prototype the subroutines */ +@@ -3829,7 +3842,12 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins) + write_mask = shader_glsl_append_dst(buffer, ins); + shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); + shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); +- shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str); ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4 ++ && ins->handler_idx == WINED3DSIH_MUL) ++ shader_addline(buffer, "mul%d(%s, %s));\n", shader_glsl_get_write_mask_size(write_mask), ++ src0_param.param_str, src1_param.param_str); ++ else ++ shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str); + } + + static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) +@@ -4041,26 +4059,45 @@ static void shader_glsl_dot(const struct wined3d_shader_instruction *ins) + struct glsl_src_param src0_param; + struct glsl_src_param src1_param; + DWORD dst_write_mask, src_write_mask; +- unsigned int dst_size; ++ unsigned int dst_size, src_size; + + dst_write_mask = shader_glsl_append_dst(buffer, ins); + dst_size = shader_glsl_get_write_mask_size(dst_write_mask); + + /* dp4 works on vec4, dp3 on vec3, etc. */ + if (ins->handler_idx == WINED3DSIH_DP4) ++ { + src_write_mask = WINED3DSP_WRITEMASK_ALL; ++ src_size = 4; ++ } + else if (ins->handler_idx == WINED3DSIH_DP3) ++ { + src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; ++ src_size = 3; ++ } + else ++ { + src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; +- ++ src_size = 2; ++ } + shader_glsl_add_src_param(ins, &ins->src[0], src_write_mask, &src0_param); + shader_glsl_add_src_param(ins, &ins->src[1], src_write_mask, &src1_param); + +- if (dst_size > 1) { +- shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str); +- } else { +- shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str); ++ if (dst_size > 1) ++ { ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) ++ shader_addline(buffer, "vec%d(dot%d(%s, %s)));\n", dst_size, src_size, ++ src0_param.param_str, src1_param.param_str); ++ else ++ shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, ++ src0_param.param_str, src1_param.param_str); ++ } ++ else ++ { ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) ++ shader_addline(buffer, "dot%d(%s, %s));\n", src_size, src0_param.param_str, src1_param.param_str); ++ else ++ shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str); + } + } + +@@ -4096,10 +4133,14 @@ static void shader_glsl_cut(const struct wined3d_shader_instruction *ins) + static void shader_glsl_pow(const struct wined3d_shader_instruction *ins) + { + struct wined3d_string_buffer *buffer = ins->ctx->buffer; ++ static const float max_float = FLT_MAX; + struct glsl_src_param src0_param; + struct glsl_src_param src1_param; + DWORD dst_write_mask; + unsigned int dst_size; ++ BOOL guard_inf; ++ ++ guard_inf = wined3d_settings.multiply_special == 1 && ins->ctx->reg_maps->shader_version.major < 4; + + dst_write_mask = shader_glsl_append_dst(buffer, ins); + dst_size = shader_glsl_get_write_mask_size(dst_write_mask); +@@ -4109,13 +4150,33 @@ static void shader_glsl_pow(const struct wined3d_shader_instruction *ins) + + if (dst_size > 1) + { +- shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n", +- dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str); ++ if (guard_inf) ++ { ++ shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : min(pow(abs(%s), %s), ", ++ dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str); ++ shader_glsl_append_imm_vec(buffer, &max_float, 1, ins->ctx->gl_info); ++ shader_addline(buffer, "));\n"); ++ } ++ else ++ { ++ shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n", ++ dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str); ++ } + } + else + { +- shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n", +- src1_param.param_str, src0_param.param_str, src1_param.param_str); ++ if (guard_inf) ++ { ++ shader_addline(buffer, "%s == 0.0 ? 1.0 : min(pow(abs(%s), %s), ", ++ src1_param.param_str, src0_param.param_str, src1_param.param_str); ++ shader_glsl_append_imm_vec(buffer, &max_float, 1, ins->ctx->gl_info); ++ shader_addline(buffer, "));\n"); ++ } ++ else ++ { ++ shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n", ++ src1_param.param_str, src0_param.param_str, src1_param.param_str); ++ } + } + } + +@@ -4290,11 +4351,15 @@ static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) + { + DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, + ins->ctx->reg_maps->shader_version.minor); ++ static const float max_float = FLT_MAX, min_float = -FLT_MAX; ++ struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; ++ struct wined3d_string_buffer *suffix; + struct glsl_src_param src0_param; +- const char *prefix, *suffix; + unsigned int dst_size; + DWORD dst_write_mask; ++ const char *prefix; ++ BOOL guard_inf; + + dst_write_mask = shader_glsl_append_dst(buffer, ins); + dst_size = shader_glsl_get_write_mask_size(dst_write_mask); +@@ -4304,41 +4369,78 @@ static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) + + shader_glsl_add_src_param(ins, &ins->src[0], dst_write_mask, &src0_param); + ++ guard_inf = wined3d_settings.multiply_special == 1 && shader_version < WINED3D_SHADER_VERSION(4, 0); ++ suffix = string_buffer_get(priv->string_buffers); ++ + switch (ins->handler_idx) + { + case WINED3DSIH_EXP: + case WINED3DSIH_EXPP: + prefix = "exp2("; +- suffix = ")"; ++ string_buffer_sprintf(suffix, ")"); + break; + + case WINED3DSIH_LOG: + case WINED3DSIH_LOGP: +- prefix = "log2(abs("; +- suffix = "))"; ++ if (guard_inf) ++ { ++ prefix = "max(log2(abs("; ++ string_buffer_sprintf(suffix, ")), "); ++ shader_glsl_append_imm_vec(suffix, &min_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ")"); ++ } ++ else ++ { ++ prefix = "log2(abs("; ++ string_buffer_sprintf(suffix, "))"); ++ } + break; + + case WINED3DSIH_RCP: +- prefix = "1.0 / "; +- suffix = ""; ++ if (guard_inf) ++ { ++ prefix = "clamp(1.0 / "; ++ string_buffer_sprintf(suffix, ", "); ++ shader_glsl_append_imm_vec(suffix, &min_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ", "); ++ shader_glsl_append_imm_vec(suffix, &max_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ")"); ++ } ++ else ++ { ++ prefix = "1.0 / "; ++ string_buffer_clear(suffix); ++ } + break; + + case WINED3DSIH_RSQ: +- prefix = "inversesqrt(abs("; +- suffix = "))"; ++ if (guard_inf) ++ { ++ prefix = "min(inversesqrt(abs("; ++ string_buffer_sprintf(suffix, ")), "); ++ shader_glsl_append_imm_vec(suffix, &max_float, 1, ins->ctx->gl_info); ++ shader_addline(suffix, ")"); ++ } ++ else ++ { ++ prefix = "inversesqrt(abs("; ++ string_buffer_sprintf(suffix, "))"); ++ } + break; + + default: + prefix = ""; +- suffix = ""; ++ string_buffer_clear(suffix); + FIXME("Unhandled instruction %#x.\n", ins->handler_idx); + break; + } + + if (dst_size > 1 && shader_version < WINED3D_SHADER_VERSION(4, 0)) +- shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix); ++ shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix->buffer); + else +- shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix); ++ shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix->buffer); ++ ++ string_buffer_release(priv->string_buffers, suffix); + } + + /** Process the WINED3DSIO_EXPP instruction in GLSL: +@@ -4655,8 +4757,13 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins) + shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); + shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); + shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param); +- shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n", +- src0_param.param_str, src1_param.param_str, src2_param.param_str); ++ if (wined3d_settings.multiply_special == 2 && ins->ctx->reg_maps->shader_version.major < 4) ++ shader_addline(ins->ctx->buffer, "mul%d(%s, %s) + %s);\n", ++ shader_glsl_get_write_mask_size(write_mask), src0_param.param_str, ++ src1_param.param_str, src2_param.param_str); ++ else ++ shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n", ++ src0_param.param_str, src1_param.param_str, src2_param.param_str); + } + + /* Handles transforming all WINED3DSIO_M?x? opcodes for +diff --git a/dll/directx/wine/wined3d/wined3d_main.c b/dll/directx/wine/wined3d/wined3d_main.c +index 5d60a44..e9efbbf 100644 +--- a/dll/directx/wine/wined3d/wined3d_main.c ++++ b/dll/directx/wine/wined3d/wined3d_main.c +@@ -111,6 +111,7 @@ struct wined3d_settings wined3d_settings = + ~0u, /* Don't force a specific sample count by default. */ + FALSE, /* Don't range check relative addressing indices in float constants. */ + FALSE, /* No strict shader math by default. */ ++ 0, /* IEEE 0 * inf result. */ + ~0U, /* No VS shader model limit by default. */ + ~0U, /* No HS shader model limit by default. */ + ~0U, /* No DS shader model limit by default. */ +@@ -362,6 +363,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) + } + if (!get_config_key_dword(hkey, appkey, "strict_shader_math", &wined3d_settings.strict_shader_math)) + ERR_(winediag)("Setting strict shader math to %#x.\n", wined3d_settings.strict_shader_math); ++ if (!get_config_key_dword(hkey, appkey, "multiply_special", &wined3d_settings.multiply_special)) ++ ERR_(winediag)("Setting multiply special to %#x.\n", wined3d_settings.multiply_special); + if (!get_config_key_dword(hkey, appkey, "MaxShaderModelVS", &wined3d_settings.max_sm_vs)) + TRACE("Limiting VS shader model to %u.\n", wined3d_settings.max_sm_vs); + if (!get_config_key_dword(hkey, appkey, "MaxShaderModelHS", &wined3d_settings.max_sm_hs)) +diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h +index 5ec24e3..ac6bb2d 100644 +--- a/dll/directx/wine/wined3d/wined3d_private.h ++++ b/dll/directx/wine/wined3d/wined3d_private.h +@@ -427,6 +427,7 @@ struct wined3d_settings + unsigned int sample_count; + BOOL check_float_constants; + unsigned int strict_shader_math; ++ unsigned int multiply_special; + unsigned int max_sm_vs; + unsigned int max_sm_hs; + unsigned int max_sm_ds; diff --git a/sdk/tools/winesync/winesync.py b/sdk/tools/winesync/winesync.py old mode 100644 new mode 100755 index d596a5dd710..4599171d91f --- a/sdk/tools/winesync/winesync.py +++ b/sdk/tools/winesync/winesync.py @@ -2,6 +2,7 @@ import sys import os +import posixpath import string import argparse import subprocess @@ -35,7 +36,7 @@ def __init__(self, module): self.reactos_src = input('Please enter the path to the reactos git tree: ') self.wine_src = input('Please enter the path to the wine git tree: ') self.wine_staging_src = input('Please enter the path to the wine-staging git tree: ') - config['repos'] = { 'reactos' : self.reactos_src, + config['repos'] = { 'reactos': self.reactos_src, 'wine': self.wine_src, 'wine-staging': self.wine_staging_src } with open('winesync.cfg', 'w') as file_output: @@ -45,6 +46,9 @@ def __init__(self, module): self.wine_staging_repo = pygit2.Repository(self.wine_staging_src) self.reactos_repo = pygit2.Repository(self.reactos_src) + # the standard author signature we will use + self.winesync_author_signature = pygit2.Signature('winesync', 'ros-dev@reactos.org') + # read the index from the reactos tree self.reactos_index = self.reactos_repo.index self.reactos_index.read() @@ -54,45 +58,58 @@ def __init__(self, module): with open(module + '.cfg', 'r') as file_input: self.module_cfg = yaml.safe_load(file_input) - self.staged_patch_dir = os.path.join('sdk', 'tools', 'winesync', self.module + '_staging') + self.staged_patch_dir = posixpath.join('sdk', 'tools', 'winesync', self.module + '_staging') def create_or_checkout_wine_branch(self, wine_tag, wine_staging_tag): - wine_branch_name = 'winesync-' + wine_tag + '-' + wine_staging_tag + # build the wine branch name + wine_branch_name = 'winesync-' + wine_tag + if wine_staging_tag: + wine_branch_name += '-' + wine_staging_tag + branch = self.wine_repo.lookup_branch(wine_branch_name) if branch is None: # get our target commits wine_target_commit = self.wine_repo.revparse_single(wine_tag) if isinstance(wine_target_commit, pygit2.Tag): wine_target_commit = wine_target_commit.target + if isinstance(wine_target_commit, pygit2.Commit): + wine_target_commit = wine_target_commit.id - wine_staging_target_commit = self.wine_staging_repo.revparse_single(wine_staging_tag) - if isinstance(wine_staging_target_commit, pygit2.Tag): - wine_staging_target_commit = wine_staging_target_commit.target + # do the same for the wine-staging tree + if wine_staging_tag: + wine_staging_target_commit = self.wine_staging_repo.revparse_single(wine_staging_tag) + if isinstance(wine_staging_target_commit, pygit2.Tag): + wine_staging_target_commit = wine_staging_target_commit.target + if isinstance(wine_staging_target_commit, pygit2.Commit): + wine_staging_target_commit = wine_staging_target_commit.id self.wine_repo.branches.local.create(wine_branch_name, self.wine_repo.revparse_single('HEAD')) self.wine_repo.checkout(self.wine_repo.lookup_branch(wine_branch_name)) self.wine_repo.reset(wine_target_commit, pygit2.GIT_RESET_HARD) # do the same for the wine-staging tree - self.wine_staging_repo.branches.local.create(wine_branch_name, self.wine_staging_repo.revparse_single('HEAD')) - self.wine_staging_repo.checkout(self.wine_staging_repo.lookup_branch(wine_branch_name)) - self.wine_staging_repo.reset(wine_staging_target_commit, pygit2.GIT_RESET_HARD) - - # run the wine-staging script - subprocess.call(['bash', '-c', self.wine_staging_src + '/patches/patchinstall.sh DESTDIR=' + self.wine_src + ' --all --backend=git-am']) - - # delete the branch we created - self.wine_staging_repo.checkout(self.wine_staging_repo.lookup_branch('master')) - self.wine_staging_repo.branches.delete(wine_branch_name) + if wine_staging_tag: + self.wine_staging_repo.branches.local.create(wine_branch_name, self.wine_staging_repo.revparse_single('HEAD')) + self.wine_staging_repo.checkout(self.wine_staging_repo.lookup_branch(wine_branch_name)) + self.wine_staging_repo.reset(wine_staging_target_commit, pygit2.GIT_RESET_HARD) + + # run the wine-staging script + if subprocess.call(['python', self.wine_staging_src + '/staging/patchinstall.py', 'DESTDIR=' + self.wine_src, '--all', '--backend=git-am', '--no-autoconf']): + # the new script failed (it doesn't exist?), try the old one + subprocess.call(['bash', '-c', self.wine_staging_src + '/patches/patchinstall.sh DESTDIR=' + self.wine_src + ' --all --backend=git-am --no-autoconf']) + + # delete the branch we created + self.wine_staging_repo.checkout(self.wine_staging_repo.lookup_branch('master')) + self.wine_staging_repo.branches.delete(wine_branch_name) else: self.wine_repo.checkout(self.wine_repo.lookup_branch(wine_branch_name)) return wine_branch_name - # helper function for resolving wine tree path to reactos one - # Note : it doesn't care about the fact that the file actually exists or not + # Helper function for resolving wine tree path to reactos one + # Note: it doesn't care about the fact that the file actually exists or not def wine_to_reactos_path(self, wine_path): - if wine_path in self.module_cfg['files']: + if self.module_cfg['files'] and (wine_path in self.module_cfg['files']): # we have a direct mapping return self.module_cfg['files'][wine_path] @@ -100,13 +117,10 @@ def wine_to_reactos_path(self, wine_path): # root files should have a direct mapping return None - if self.module_cfg['directories'] is None: - return None - wine_dir, wine_file = os.path.split(wine_path) - if wine_dir in self.module_cfg['directories']: + if self.module_cfg['directories'] and (wine_dir in self.module_cfg['directories']): # we have a mapping for the directory - return os.path.join(self.module_cfg['directories'][wine_dir], wine_file) + return posixpath.join(self.module_cfg['directories'][wine_dir], wine_file) # no match return None @@ -133,7 +147,7 @@ def sync_wine_commit(self, wine_commit, in_staging, staging_patch_index): # check if we should care new_reactos_path = self.wine_to_reactos_path(delta.new_file.path) if not new_reactos_path is None: - warning_message += 'file ' + delta.new_file.path + ' is added to the wine tree !\n' + warning_message += 'file ' + delta.new_file.path + ' is added to the wine tree!\n' old_reactos_path = '/dev/null' else: old_reactos_path = None @@ -141,12 +155,12 @@ def sync_wine_commit(self, wine_commit, in_staging, staging_patch_index): # check if we should care old_reactos_path = self.wine_to_reactos_path(delta.old_file.path) if not old_reactos_path is None: - warning_message += 'file ' + delta.old_file.path + ' is removed from the wine tree !\n' + warning_message += 'file ' + delta.old_file.path + ' is removed from the wine tree!\n' new_reactos_path = '/dev/null' else: new_reactos_path = None elif delta.new_file.path.endswith('Makefile.in'): - warning_message += 'file ' + delta.new_file.path + ' was modified !\n' + warning_message += 'file ' + delta.new_file.path + ' was modified!\n' # no need to warn that those are ignored, we just did. continue else: @@ -210,7 +224,7 @@ def sync_wine_commit(self, wine_commit, in_staging, staging_patch_index): print('Applied patches from wine commit ' + str(wine_commit.id)) if ignored_files: - warning_message += 'WARNING : some files were ignored: ' + ' '.join(ignored_files) + '\n' + warning_message += 'WARNING: some files were ignored: ' + ' '.join(ignored_files) + '\n' if not in_staging: self.module_cfg['tags']['wine'] = str(wine_commit.id) @@ -224,7 +238,7 @@ def sync_wine_commit(self, wine_commit, in_staging, staging_patch_index): os.mkdir(os.path.join(self.reactos_src, self.staged_patch_dir)) with open(patch_path, 'w') as file_output: file_output.write(complete_patch) - self.reactos_index.add(os.path.join(self.staged_patch_dir, patch_file_name)) + self.reactos_index.add(posixpath.join(self.staged_patch_dir, patch_file_name)) self.reactos_index.write() @@ -234,8 +248,9 @@ def sync_wine_commit(self, wine_commit, in_staging, staging_patch_index): else: commit_msg += f'wine commit id {str(wine_commit.id)} by {wine_commit.author.name} <{wine_commit.author.email}>' - self.reactos_repo.create_commit('HEAD', - pygit2.Signature('winesync', 'ros-dev@reactos.org'), + self.reactos_repo.create_commit( + 'HEAD', + self.winesync_author_signature, self.reactos_repo.default_signature, commit_msg, self.reactos_index.write_tree(), @@ -260,7 +275,7 @@ def sync_wine_commit(self, wine_commit, in_staging, staging_patch_index): def revert_staged_patchset(self): # revert all of this in one commit - staged_patch_dir_path = os.path.join(self.reactos_src, self.staged_patch_dir) + staged_patch_dir_path = posixpath.join(self.reactos_src, self.staged_patch_dir) if not os.path.isdir(staged_patch_dir_path): return True @@ -275,26 +290,31 @@ def revert_staged_patchset(self): with open(patch_path, 'rb') as patch_file: try: - subprocess.run(['git', '-C', self.reactos_src, 'apply', '-R', '--reject'], stdin=patch_file, check=True) + subprocess.run(['git', '-C', self.reactos_src, 'apply', '-R', '--ignore-whitespace', '--reject'], stdin=patch_file, check=True) except subprocess.CalledProcessError as err: print(f'Error while reverting patch {patch_file_name}') print('Please check, remove the offending patch with git rm, and relaunch this script') return False - self.reactos_index.remove(os.path.join(self.staged_patch_dir, patch_file_name)) + self.reactos_index.remove(posixpath.join(self.staged_patch_dir, patch_file_name)) self.reactos_index.write() os.remove(patch_path) if not has_patches: return True - self.reactos_index.add_all([f for f in self.module_cfg['files'].values()]) - self.reactos_index.add_all([f'{d}/*.*' for d in self.module_cfg['directories'].values()]) + # Note: these path lists may be empty or None, in which case + # we should not call index.add_all(), otherwise we would add + # any untracked file present in the repository. + if self.module_cfg['files']: + self.reactos_index.add_all([f for f in self.module_cfg['files'].values()]) + if self.module_cfg['directories']: + self.reactos_index.add_all([f'{d}/*.*' for d in self.module_cfg['directories'].values()]) self.reactos_index.write() self.reactos_repo.create_commit( 'HEAD', - self.reactos_repo.default_signature, + self.winesync_author_signature, self.reactos_repo.default_signature, f'[WINESYNC]: revert wine-staging patchset for {self.module}', self.reactos_index.write_tree(), @@ -306,16 +326,18 @@ def sync_to_wine(self, wine_tag, wine_staging_tag): wine_target_commit = self.wine_repo.revparse_single(wine_tag) if isinstance(wine_target_commit, pygit2.Tag): wine_target_commit = wine_target_commit.target + if isinstance(wine_target_commit, pygit2.Commit): + wine_target_commit = wine_target_commit.id # print(f'wine target commit is {wine_target_commit}') # get the wine commit id where we left in_staging = False wine_last_sync = self.wine_repo.revparse_single(self.module_cfg['tags']['wine']) - if (isinstance(wine_last_sync, pygit2.Tag)): + if isinstance(wine_last_sync, pygit2.Tag): if not self.revert_staged_patchset(): return wine_last_sync = wine_last_sync.target - if (isinstance(wine_last_sync, pygit2.Commit)): + if isinstance(wine_last_sync, pygit2.Commit): wine_last_sync = wine_last_sync.id # create a branch to keep things clean @@ -358,7 +380,7 @@ def sync_to_wine(self, wine_tag, wine_staging_tag): self.reactos_index.write() self.reactos_repo.create_commit( 'HEAD', - self.reactos_repo.default_signature, + self.winesync_author_signature, self.reactos_repo.default_signature, f'[WINESYNC]: {self.module} is now in sync with wine-staging {wine_tag}', self.reactos_index.write_tree(), @@ -368,9 +390,9 @@ def sync_to_wine(self, wine_tag, wine_staging_tag): def main(): parser = argparse.ArgumentParser() - parser.add_argument('module', help='The module you want to sync. .cfg must exist in the current directory') - parser.add_argument('wine_tag', help='The wine tag or commit id to sync to') - parser.add_argument('wine_staging_tag', help='The wine staging tag or commit id to pick wine staged patches from') + parser.add_argument('module', help='The module you want to sync. .cfg must exist in the current directory.') + parser.add_argument('wine_tag', help='The wine tag or commit id to sync to.') + parser.add_argument('wine_staging_tag', nargs='?', default=None, help='The optional wine staging tag or commit id to pick wine staged patches from.') args = parser.parse_args()